Migrate GD code to module

Test: atest --host bluetooth_test_gd
Change-Id: Ibcb219666ff5552efc602bf063e69a6e6b7e4bd8
diff --git a/gd/Android.bp b/gd/Android.bp
index 572eebc..da660ab 100644
--- a/gd/Android.bp
+++ b/gd/Android.bp
@@ -24,6 +24,9 @@
         "-fvisibility=hidden",
         "-DLOG_NDEBUG=1",
         "-DGOOGLE_PROTOBUF_NO_RTTI",
+        "-Wno-unused-parameter",
+        "-Wno-implicit-fallthrough",
+        "-Wno-unused-result",
     ],
     conlyflags: [
         "-std=c99",
@@ -116,9 +119,8 @@
     ],
     host_supported: true,
     srcs: [
-        "stack_manager.cc",
         "facade/stack_with_grpc_main.cc",
-        "facade/facade_manager.cc",
+        "grpc/grpc_module.cc",
         ":BluetoothCertFacade_hci_hal",
     ],
     generated_headers: [
@@ -146,11 +148,6 @@
             ],
         },
     },
-    cflags: [
-        "-Wno-unused-parameter",
-        "-Wno-implicit-fallthrough",
-        "-Wno-unused-result",
-    ],
     sanitize: {
         address: true,
     },
@@ -182,11 +179,6 @@
     sanitize: {
         address: true,
     },
-    cflags: [
-        "-Wno-unused-parameter",
-        "-Wno-implicit-fallthrough",
-        "-Wno-unused-result",
-    ],
 }
 
 cc_test {
@@ -228,11 +220,6 @@
         ":BluetoothL2capTestSources",
         ":BluetoothPacketTestSources",
     ],
-    cflags: [
-        "-Wno-unused-parameter",
-        "-Wno-implicit-fallthrough",
-        "-Wno-unused-result",
-    ],
     generated_headers : [
         "BluetoothGeneratedPackets_h",
     ],
diff --git a/gd/facade/facade_manager.cc b/gd/facade/facade_manager.cc
deleted file mode 100644
index 95decb0..0000000
--- a/gd/facade/facade_manager.cc
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "facade/facade_manager.h"
-
-#include "grpc/async_grpc.h"
-#include "hal/facade/facade.h"
-#include "os/log.h"
-#include "stack_manager.h"
-
-using ::bluetooth::hal::HciPacket;
-
-using ::grpc::Server;
-using ::grpc::ServerBuilder;
-
-namespace {
-
-::bluetooth::facade::CertFacade* module_enum_to_module(const ::bluetooth::facade::FacadeManager::Module& module) {
-  switch (module) {
-    case ::bluetooth::facade::FacadeManager::Module::HciHal:
-      return ::bluetooth::hal::facade::GetFacadeModule();
-  }
-  return nullptr;
-}
-}  // namespace
-
-namespace bluetooth {
-namespace facade {
-
-void FacadeManager::EnableModule(Module module) {
-  enabled_modules_.push_back(module);
-}
-
-void FacadeManager::StartUp() {
-  StackManager::Get()->StartUp();
-  LOG_INFO("%d", FacadeConfig::Get()->GetGrpcPort());
-  start_server("0.0.0.0", FacadeConfig::Get()->GetGrpcPort());
-
-  for (const auto& enabled_module : enabled_modules_) {
-    auto* module = module_enum_to_module(enabled_module);
-    module->StartUp(get_grpc_completion_queue());
-  }
-}
-
-void FacadeManager::start_server(const std::string& address, int port) {
-  std::string listening_port = address + ":" + std::to_string(port);
-  ServerBuilder builder;
-  builder.AddListeningPort(listening_port, ::grpc::InsecureServerCredentials());
-
-  grpc_completion_queue_ = builder.AddCompletionQueue();
-  for (const auto& enabled_module : enabled_modules_) {
-    auto* module = module_enum_to_module(enabled_module);
-    builder.RegisterService(module->GetModuleGrpcService());
-  }
-
-  server_ = builder.BuildAndStart();
-}
-
-void FacadeManager::ShutDown() {
-  stop_server();
-
-  for (const auto& enabled_module : enabled_modules_) {
-    auto* module = module_enum_to_module(enabled_module);
-    module->ShutDown();
-  }
-
-  StackManager::Get()->ShutDown();
-}
-
-void FacadeManager::stop_server() {
-  server_->Shutdown();
-  grpc_completion_queue_->Shutdown();
-}
-
-::grpc::ServerCompletionQueue* FacadeManager::get_grpc_completion_queue() {
-  auto* queue = grpc_completion_queue_.get();
-  ASSERT(queue != nullptr);
-  return queue;
-}
-
-void FacadeManager::GrpcMainLoop() {
-  void* tag;
-  bool ok;
-  while (true) {
-    if (!grpc_completion_queue_->Next(&tag, &ok)) {
-      LOG_INFO("gRPC is shutdown");
-      break;
-    }
-    auto* data = static_cast<grpc::GrpcAsyncEventCallback*>(tag);
-    (*data)(ok);
-  }
-}
-
-}  // namespace facade
-}  // namespace bluetooth
diff --git a/gd/facade/facade_manager.h b/gd/facade/facade_manager.h
deleted file mode 100644
index 969ba6a..0000000
--- a/gd/facade/facade_manager.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <functional>
-#include <list>
-
-#include <grpc++/grpc++.h>
-
-#include "hal/hci_hal.h"
-
-namespace bluetooth {
-namespace facade {
-
-class FacadeConfig {
- public:
-  static FacadeConfig* Get() {
-    static FacadeConfig instance;
-    return &instance;
-  }
-
-  void SetGrpcPort(int port) {
-    grpc_port_ = port;
-  }
-
-  int GetGrpcPort() {
-    return grpc_port_;
-  }
-
- private:
-  FacadeConfig() = default;
-  int grpc_port_ = 8899;
-};
-
-class FacadeManager {
- public:
-  enum class Module {
-    HciHal,
-  };
-
-  static FacadeManager* Get() {
-    static FacadeManager instance;
-    return &instance;
-  }
-
-  void EnableModule(Module module);
-
-  void StartUp();
-
-  void ShutDown();
-
-  // Blocks for incoming gRPC requests
-  void GrpcMainLoop();
-
- private:
-  std::unique_ptr<::grpc::Server> server_ = nullptr;
-  std::unique_ptr<::grpc::ServerCompletionQueue> grpc_completion_queue_ = nullptr;
-  std::list<Module> enabled_modules_;
-  void start_server(const std::string& address, int port);
-  void stop_server();
-  ::grpc::ServerCompletionQueue* get_grpc_completion_queue();
-};
-
-// Cert facade for each layer
-class CertFacade {
- public:
-  virtual ~CertFacade() = default;
-
-  // Initialize gRPC service, asynchronous request handlers, and other resources here.
-  // This should be invoked after CompletionQueue is started.
-  virtual void StartUp(::grpc::ServerCompletionQueue* cq) {}
-
-  // Do the clean up here
-  // This should be invoked before CompletionQueue is shutdown.
-  virtual void ShutDown() {}
-
-  // Each facade has a gRPC service that implements stubs from its api proto. The service instance should exist all
-  // the time, so static storage is recommended.
-  virtual ::grpc::Service* GetModuleGrpcService() const = 0;
-};
-
-}  // namespace facade
-}  // namespace bluetooth
diff --git a/gd/facade/stack_with_grpc_main.cc b/gd/facade/stack_with_grpc_main.cc
index 054b44b..67b618d 100644
--- a/gd/facade/stack_with_grpc_main.cc
+++ b/gd/facade/stack_with_grpc_main.cc
@@ -14,26 +14,33 @@
  * limitations under the License.
  */
 
-#include "facade/facade_manager.h"
+#include "grpc/grpc_module.h"
 #include "hal/hci_hal_host_rootcanal.h"
+#include "hal/facade/facade.h"
 
 #include <csignal>
 #include <string>
 #include <thread>
 
-using ::bluetooth::facade::FacadeConfig;
-using ::bluetooth::facade::FacadeManager;
+#include "stack_manager.h"
+
 using ::bluetooth::hal::HciHalHostRootcanalConfig;
+using ::bluetooth::StackManager;
+using ::bluetooth::grpc::GrpcModule;
+using ::bluetooth::ModuleList;
 
 namespace {
+static StackManager* stack;
+
 void interrupt_handler(int) {
-  FacadeManager::Get()->ShutDown();
+  stack->GetInstance<GrpcModule>()->StopServer();
 }
 }  // namespace
 
 // The entry point for the binary with libbluetooth + facades
 int main(int argc, const char** argv) {
-  signal(SIGINT, interrupt_handler);
+
+  int port = 8899;
 
   const std::string arg_grpc_port = "--port=";
   const std::string arg_rootcanal_port = "--rootcanal-port=";
@@ -41,7 +48,7 @@
     std::string arg = argv[i];
     if (arg.find(arg_grpc_port) == 0) {
       auto port_number = arg.substr(arg_grpc_port.size());
-      FacadeConfig::Get()->SetGrpcPort(std::stoi(port_number));
+      port = std::stoi(port_number);
     }
     if (arg.find(arg_rootcanal_port) == 0) {
       auto port_number = arg.substr(arg_rootcanal_port.size());
@@ -49,13 +56,22 @@
     }
   }
 
-  // TODO: This should be run-time configurable
-  FacadeManager::Get()->EnableModule(FacadeManager::Module::HciHal);
+  ModuleList modules;
+  modules.add<::bluetooth::hal::facade::HalFacadeModule>();
 
-  FacadeManager::Get()->StartUp();
-  auto wait_thread = std::thread([] { FacadeManager::Get()->GrpcMainLoop(); });
+  stack = new StackManager();
+  stack->StartUp(&modules);
+
+  GrpcModule* grpc_module = stack->GetInstance<GrpcModule>();
+  grpc_module->StartServer("0.0.0.0", port);
+
+  signal(SIGINT, interrupt_handler);
+  auto wait_thread = std::thread([grpc_module] { grpc_module->RunGrpcLoop(); });
   wait_thread.join();
-  FacadeManager::Get()->ShutDown();
+
+  grpc_module->StopServer();
+  stack->ShutDown();
+  delete stack;
 
   return 0;
 }
diff --git a/gd/grpc/grpc_module.cc b/gd/grpc/grpc_module.cc
new file mode 100644
index 0000000..60099a8
--- /dev/null
+++ b/gd/grpc/grpc_module.cc
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "grpc/grpc_module.h"
+
+#include "os/log.h"
+#include "grpc/async_grpc.h"
+
+using ::grpc::Server;
+using ::grpc::ServerBuilder;
+
+namespace bluetooth {
+namespace grpc {
+
+void GrpcModule::ListDependencies(ModuleList* list) {
+}
+
+void GrpcModule::Start(const ModuleRegistry* registry) {
+  ASSERT(!started_);
+}
+
+void GrpcModule::Stop(const ModuleRegistry* registry) {
+  ASSERT(!started_);
+}
+
+void GrpcModule::StartServer(const std::string& address, int port) {
+  ASSERT(!started_);
+  started_ = true;
+
+  std::string listening_port = address + ":" + std::to_string(port);
+  ServerBuilder builder;
+
+  for (const auto& facade : facades_) {
+    builder.RegisterService(facade->GetService());
+  }
+
+  builder.AddListeningPort(listening_port, ::grpc::InsecureServerCredentials());
+  completion_queue_ = builder.AddCompletionQueue();
+  server_ = builder.BuildAndStart();
+
+  for (const auto& facade : facades_) {
+    facade->OnServerStarted(completion_queue_.get());
+  }
+}
+
+void GrpcModule::StopServer() {
+  ASSERT(started_);
+
+  server_->Shutdown();
+  completion_queue_->Shutdown();
+
+  for (const auto& facade : facades_) {
+    facade->OnServerStopped();
+  }
+
+  started_ = false;
+}
+
+void GrpcModule::Register(GrpcFacadeModule* facade) {
+  ASSERT(!started_);
+
+  facades_.push_back(facade);
+}
+
+void GrpcModule::Unregister(GrpcFacadeModule* facade) {
+  ASSERT(!started_);
+
+  for (auto it = facades_.begin(); it != facades_.end(); it++) {
+    if (*it == facade) {
+      facades_.erase(it);
+      return;
+    }
+  }
+
+  ASSERT(false);
+}
+
+void GrpcModule::RunGrpcLoop() {
+  void* tag;
+  bool ok;
+  while (true) {
+    if (!completion_queue_->Next(&tag, &ok)) {
+      LOG_INFO("gRPC is shutdown");
+      break;
+    }
+    auto* data = static_cast<GrpcAsyncEventCallback*>(tag);
+    (*data)(ok);
+  }
+}
+
+const ::bluetooth::ModuleFactory GrpcModule::Factory = ::bluetooth::ModuleFactory([]() {
+  return new GrpcModule();
+});
+
+
+void GrpcFacadeModule::ListDependencies(ModuleList* list) {
+  list->add<GrpcModule>();
+}
+
+void GrpcFacadeModule::Start(const ModuleRegistry* registry) {
+  registry->GetInstance<GrpcModule>()->Register(this);
+}
+
+void GrpcFacadeModule::Stop(const ModuleRegistry* registry) {
+  registry->GetInstance<GrpcModule>()->Unregister(this);
+}
+
+}  // namespace grpc
+}  // namespace bluetooth
diff --git a/gd/grpc/grpc_module.h b/gd/grpc/grpc_module.h
new file mode 100644
index 0000000..f059a69
--- /dev/null
+++ b/gd/grpc/grpc_module.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <functional>
+#include <vector>
+
+#include <grpc++/grpc++.h>
+#include <module.h>
+
+namespace bluetooth {
+namespace grpc {
+
+class GrpcFacadeModule;
+
+class GrpcModule : public ::bluetooth::Module {
+ public:
+  static const ModuleFactory Factory;
+
+  void StartServer(const std::string& address, int port);
+
+  void StopServer();
+
+  void Register(GrpcFacadeModule* facade);
+
+  void Unregister(GrpcFacadeModule* facade);
+
+  // Blocks for incoming gRPC requests
+  void RunGrpcLoop();
+
+ protected:
+  void ListDependencies(ModuleList* list) override;
+
+  void Start(const ModuleRegistry* registry) override;
+
+  void Stop(const ModuleRegistry* registry) override;
+
+ private:
+  bool started_;
+  std::unique_ptr<::grpc::Server> server_ = nullptr;
+  std::unique_ptr<::grpc::ServerCompletionQueue> completion_queue_ = nullptr;
+  std::vector<GrpcFacadeModule*> facades_;
+};
+
+class GrpcFacadeModule : public ::bluetooth::Module {
+ friend GrpcModule;
+ protected:
+  void ListDependencies(ModuleList* list) override;
+
+  void Start(const ModuleRegistry* registry) override;
+
+  void Stop(const ModuleRegistry* registry) override;
+
+  virtual ::grpc::Service* GetService() const = 0;
+
+  virtual void OnServerStarted(::grpc::ServerCompletionQueue* cq) {}
+
+  virtual void OnServerStopped() {}
+};
+
+}  // namespace grpc
+}  // namespace bluetooth
diff --git a/gd/hal/cert/simple_hal_test.cc b/gd/hal/cert/simple_hal_test.cc
index b5879a2..8804a23 100644
--- a/gd/hal/cert/simple_hal_test.cc
+++ b/gd/hal/cert/simple_hal_test.cc
@@ -21,7 +21,6 @@
 #include <string>
 #include <thread>
 
-#include "facade/facade_manager.h"
 #include "hal/facade/api.grpc.pb.h"
 #include "hci/hci_packets.h"
 #include "os/log.h"
@@ -40,7 +39,7 @@
 class HalAdapterCertTest : public ::testing::Test {
  protected:
   void SetUp() override {
-    int port = ::bluetooth::facade::FacadeConfig::Get()->GetGrpcPort();
+    int port = 8899;
     std::string channel = "localhost:" + std::to_string(port);
     stub_ = HciTransportation::NewStub(grpc::CreateChannel(channel, grpc::InsecureChannelCredentials()));
   }
diff --git a/gd/hal/facade/facade.cc b/gd/hal/facade/facade.cc
index 9163fb3..7542931 100644
--- a/gd/hal/facade/facade.cc
+++ b/gd/hal/facade/facade.cc
@@ -35,16 +35,13 @@
 namespace hal {
 namespace facade {
 
-namespace {
-
-HalFacadeModule hci_cert_module_instance_;
-
-void stop_stream_hci_evt();
-void stop_stream_hci_acl();
-void stop_stream_hci_sco();
-
-class HciTransportationSyncService : public HciTransportation::Service {
+class HciTransportationService
+    : public HciTransportation::Service,
+      public ::bluetooth::hal::BluetoothHciHalCallbacks {
  public:
+  HciTransportationService(BluetoothHciHal* hal) : hal_(hal) {
+  }
+
   ::grpc::Status SetLoopbackMode(::grpc::ServerContext* context,
                                  const ::bluetooth::hal::facade::LoopbackModeSettings* request,
                                  ::google::protobuf::Empty* response) override {
@@ -54,277 +51,70 @@
     std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
     hci::BitInserter it(*packet_bytes);
     packet->Serialize(it);
-    GetBluetoothHciHal()->sendHciCommand(*packet_bytes);
+    hal_->sendHciCommand(*packet_bytes);
     return ::grpc::Status::OK;
   }
 
   ::grpc::Status SendHciCmd(::grpc::ServerContext* context, const ::bluetooth::hal::facade::HciCmdPacket* request,
                             ::google::protobuf::Empty* response) override {
     std::string req_string = request->payload();
-    ::bluetooth::hal::GetBluetoothHciHal()->sendHciCommand(std::vector<uint8_t>(req_string.begin(), req_string.end()));
+    hal_->sendHciCommand(std::vector<uint8_t>(req_string.begin(), req_string.end()));
     return ::grpc::Status::OK;
   }
 
   ::grpc::Status SendHciAcl(::grpc::ServerContext* context, const ::bluetooth::hal::facade::HciAclPacket* request,
                             ::google::protobuf::Empty* response) override {
     std::string req_string = request->payload();
-    ::bluetooth::hal::GetBluetoothHciHal()->sendAclData(std::vector<uint8_t>(req_string.begin(), req_string.end()));
+    hal_->sendAclData(std::vector<uint8_t>(req_string.begin(), req_string.end()));
     return ::grpc::Status::OK;
   }
 
   ::grpc::Status SendHciSco(::grpc::ServerContext* context, const ::bluetooth::hal::facade::HciScoPacket* request,
                             ::google::protobuf::Empty* response) override {
     std::string req_string = request->payload();
-    ::bluetooth::hal::GetBluetoothHciHal()->sendScoData(std::vector<uint8_t>(req_string.begin(), req_string.end()));
+    hal_->sendScoData(std::vector<uint8_t>(req_string.begin(), req_string.end()));
     return ::grpc::Status::OK;
   }
 
-  ::grpc::Status UnregisterHciEvt(::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
-                                  ::google::protobuf::Empty* response) override {
-    stop_stream_hci_evt();
-    return ::grpc::Status::OK;
-  }
-  ::grpc::Status UnregisterHciAcl(::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
-                                  ::google::protobuf::Empty* response) override {
-    stop_stream_hci_acl();
-    return ::grpc::Status::OK;
-  }
-
-  ::grpc::Status UnregisterHciSco(::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
-                                  ::google::protobuf::Empty* response) override {
-    stop_stream_hci_sco();
-    return ::grpc::Status::OK;
-  }
-};
-
-using HciTransportationAsyncService =
-    HciTransportation::WithAsyncMethod_RegisterHciEvt<HciTransportation::WithAsyncMethod_RegisterHciAcl<
-        HciTransportation::WithAsyncMethod_RegisterHciSco<HciTransportationSyncService>>>;
-
-HciTransportationAsyncService async_service_;
-
-class RegisterHciEvtImpl : public grpc::GrpcAsyncServerStreamingHandler<::google::protobuf::Empty, HciEvtPacket>,
-                           public HalFacadeModule::HciEvtListener {
- public:
-  explicit RegisterHciEvtImpl(HciTransportationAsyncService* service, ::grpc::ServerCompletionQueue* cq)
-      : service_(service), streaming_control_box_(this, cq) {
-    streaming_control_box_.RequestNewRpc();
-  }
-
-  void OnReadyForNextRequest(::grpc::ServerContext* context, google::protobuf::Empty* req,
-                             ServerAsyncWriter<HciEvtPacket>* res, ::grpc::CompletionQueue* new_call_cq,
-                             ServerCompletionQueue* notification_cq, void* tag) override {
-    service_->RequestRegisterHciEvt(context, req, res, new_call_cq, notification_cq, tag);
-  }
-
-  void OnRpcRequestReceived(google::protobuf::Empty) override {
-    hci_cert_module_instance_.RegisterHciEvtListener(this);
-  }
-
-  void OnRpcFinished() override {
-    streaming_control_box_.RequestNewRpc();
-  }
-
-  void operator()(const hal::HciPacket& hciPacket) override {
-    HciEvtPacket packet;
-    packet.set_payload(std::string(hciPacket.begin(), hciPacket.end()));
-    streaming_control_box_.Write(packet);
-  }
-
-  void StopStream() {
-    hci_cert_module_instance_.UnregisterHciEvtListener(this);
-    streaming_control_box_.StopStreaming();
-  }
-
- private:
-  HciTransportationAsyncService* service_;
-  grpc::GrpcAsyncServerStreamingControlBox<::google::protobuf::Empty, HciEvtPacket> streaming_control_box_;
-};
-
-class RegisterHciAclImpl : public grpc::GrpcAsyncServerStreamingHandler<::google::protobuf::Empty, HciAclPacket>,
-                           public HalFacadeModule::HciAclListener {
- public:
-  explicit RegisterHciAclImpl(HciTransportationAsyncService* service, ::grpc::ServerCompletionQueue* cq)
-      : service_(service), streaming_control_box_(this, cq) {
-    streaming_control_box_.RequestNewRpc();
-  }
-
-  void OnReadyForNextRequest(::grpc::ServerContext* context, google::protobuf::Empty* req,
-                             ServerAsyncWriter<HciAclPacket>* res, ::grpc::CompletionQueue* new_call_cq,
-                             ServerCompletionQueue* notification_cq, void* tag) override {
-    service_->RequestRegisterHciAcl(context, req, res, new_call_cq, notification_cq, tag);
-  }
-
-  void OnRpcRequestReceived(google::protobuf::Empty) override {
-    hci_cert_module_instance_.RegisterHciAclListener(this);
-  }
-
-  void OnRpcFinished() override {
-    streaming_control_box_.RequestNewRpc();
-  }
-
-  void operator()(const hal::HciPacket& hciPacket) override {
-    HciAclPacket packet;
-    packet.set_payload(std::string(hciPacket.begin(), hciPacket.end()));
-    streaming_control_box_.Write(packet);
-  }
-
-  void StopStream() {
-    hci_cert_module_instance_.UnregisterHciAclListener(this);
-    streaming_control_box_.StopStreaming();
-  }
-
- private:
-  HciTransportationAsyncService* service_;
-  grpc::GrpcAsyncServerStreamingControlBox<::google::protobuf::Empty, HciAclPacket> streaming_control_box_;
-};
-
-class RegisterHciScoImpl : public grpc::GrpcAsyncServerStreamingHandler<::google::protobuf::Empty, HciScoPacket>,
-                           public HalFacadeModule::HciScoListener {
- public:
-  explicit RegisterHciScoImpl(HciTransportationAsyncService* service, ::grpc::ServerCompletionQueue* cq)
-      : service_(service), streaming_control_box_(this, cq) {
-    streaming_control_box_.RequestNewRpc();
-  }
-
-  void OnReadyForNextRequest(::grpc::ServerContext* context, google::protobuf::Empty* req,
-                             ServerAsyncWriter<HciScoPacket>* res, ::grpc::CompletionQueue* new_call_cq,
-                             ServerCompletionQueue* notification_cq, void* tag) override {
-    service_->RequestRegisterHciSco(context, req, res, new_call_cq, notification_cq, tag);
-  }
-
-  void OnRpcRequestReceived(google::protobuf::Empty) override {
-    hci_cert_module_instance_.RegisterHciScoListener(this);
-  }
-
-  void OnRpcFinished() override {
-    streaming_control_box_.RequestNewRpc();
-  }
-
-  void operator()(const hal::HciPacket& hciPacket) override {
-    HciScoPacket packet;
-    packet.set_payload(std::string(hciPacket.begin(), hciPacket.end()));
-    streaming_control_box_.Write(packet);
-  }
-
-  void StopStream() {
-    hci_cert_module_instance_.UnregisterHciScoListener(this);
-    streaming_control_box_.StopStreaming();
-  }
-
- private:
-  HciTransportationAsyncService* service_;
-  grpc::GrpcAsyncServerStreamingControlBox<::google::protobuf::Empty, HciScoPacket> streaming_control_box_;
-};
-
-struct GrpcHelper {
-  explicit GrpcHelper(::grpc::ServerCompletionQueue* cq)
-      : hci_evt_impl_(&async_service_, cq), hci_acl_impl_(&async_service_, cq), hci_sco_impl_(&async_service_, cq) {}
-
-  RegisterHciEvtImpl hci_evt_impl_;
-  RegisterHciAclImpl hci_acl_impl_;
-  RegisterHciScoImpl hci_sco_impl_;
-};
-GrpcHelper* grpc_helper_instance_ = nullptr;
-
-void stop_stream_hci_evt() {
-  grpc_helper_instance_->hci_evt_impl_.StopStream();
-}
-
-void stop_stream_hci_acl() {
-  grpc_helper_instance_->hci_acl_impl_.StopStream();
-}
-
-void stop_stream_hci_sco() {
-  grpc_helper_instance_->hci_sco_impl_.StopStream();
-}
-
-}  // namespace
-
-class IncomingPacketCallback : public ::bluetooth::hal::BluetoothHciHalCallbacks {
- public:
-  explicit IncomingPacketCallback(HalFacadeModule* hal_cert_module) : hal_cert_module_(hal_cert_module) {}
-
   void hciEventReceived(bluetooth::hal::HciPacket event) override {
-    std::unique_lock<std::mutex> lock(hal_cert_module_->mutex_);
-    for (auto* listener : hal_cert_module_->registered_evt_listener_) {
-      (*listener)(event);
-    }
+    // TODO
   }
 
   void aclDataReceived(bluetooth::hal::HciPacket data) override {
-    std::unique_lock<std::mutex> lock(hal_cert_module_->mutex_);
-    for (auto* listener : hal_cert_module_->registered_acl_listener_) {
-      (*listener)(data);
-    }
+    // TODO
   }
 
   void scoDataReceived(bluetooth::hal::HciPacket data) override {
-    std::unique_lock<std::mutex> lock(hal_cert_module_->mutex_);
-    for (auto* listener : hal_cert_module_->registered_sco_listener_) {
-      (*listener)(data);
-    }
+    // TODO
   }
-
  private:
-  HalFacadeModule* hal_cert_module_;
+  BluetoothHciHal* hal_;
 };
 
-static IncomingPacketCallback* incoming_packet_callback_;
-
-void HalFacadeModule::StartUp(::grpc::ServerCompletionQueue* cq) {
-  std::unique_lock<std::mutex> lock(mutex_);
-  incoming_packet_callback_ = new IncomingPacketCallback(this);
-  hal::GetBluetoothHciHal()->registerIncomingPacketCallback(incoming_packet_callback_);
-
-  grpc_helper_instance_ = new GrpcHelper(cq);
+void HalFacadeModule::ListDependencies(ModuleList* list) {
+  ::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
+  list->add<BluetoothHciHal>();
 }
 
-void HalFacadeModule::ShutDown() {
-  std::unique_lock<std::mutex> lock(mutex_);
-  delete grpc_helper_instance_;
-  grpc_helper_instance_ = nullptr;
-  delete incoming_packet_callback_;
-  incoming_packet_callback_ = nullptr;
+void HalFacadeModule::Start(const ModuleRegistry* registry) {
+  ::bluetooth::grpc::GrpcFacadeModule::Start(registry);
+  auto hal = registry->GetInstance<BluetoothHciHal>();
+
+  service_ = new HciTransportationService(hal);
+  hal->registerIncomingPacketCallback(service_);
 }
 
-::grpc::Service* HalFacadeModule::GetModuleGrpcService() const {
-  return &async_service_;
+void HalFacadeModule::Stop(const ModuleRegistry* registry) {
+  delete service_;
 }
 
-void HalFacadeModule::RegisterHciEvtListener(HciEvtListener* listener) {
-  std::unique_lock<std::mutex> lock(mutex_);
-  registered_evt_listener_.push_back(listener);
+::grpc::Service* HalFacadeModule::GetService() const {
+  return service_;
 }
 
-void HalFacadeModule::UnregisterHciEvtListener(HciEvtListener* listener) {
-  std::unique_lock<std::mutex> lock(mutex_);
-  registered_evt_listener_.remove(listener);
-}
-
-void HalFacadeModule::RegisterHciAclListener(HciAclListener* listener) {
-  std::unique_lock<std::mutex> lock(mutex_);
-  registered_acl_listener_.push_back(listener);
-}
-
-void HalFacadeModule::UnregisterHciAclListener(HciAclListener* listener) {
-  std::unique_lock<std::mutex> lock(mutex_);
-  registered_acl_listener_.remove(listener);
-}
-
-void HalFacadeModule::RegisterHciScoListener(HciScoListener* listener) {
-  std::unique_lock<std::mutex> lock(mutex_);
-  registered_sco_listener_.push_back(listener);
-}
-
-void HalFacadeModule::UnregisterHciScoListener(HciScoListener* listener) {
-  std::unique_lock<std::mutex> lock(mutex_);
-  registered_sco_listener_.remove(listener);
-}
-
-::bluetooth::facade::CertFacade* GetFacadeModule() {
-  return &hci_cert_module_instance_;
-}
+const ModuleFactory HalFacadeModule::Factory = ::bluetooth::ModuleFactory([]() {
+  return new HalFacadeModule();
+});
 
 }  // namespace facade
 }  // namespace hal
diff --git a/gd/hal/facade/facade.h b/gd/hal/facade/facade.h
index 45ab919..3a0896c 100644
--- a/gd/hal/facade/facade.h
+++ b/gd/hal/facade/facade.h
@@ -21,52 +21,29 @@
 
 #include <grpc++/grpc++.h>
 
-#include "facade/facade_manager.h"
+#include "grpc/grpc_module.h"
+#include "hal/hci_hal.h"
 
 namespace bluetooth {
 namespace hal {
 namespace facade {
-// Get cert facade. This instance has static storage.
-::bluetooth::facade::CertFacade* GetFacadeModule();
 
-class HalFacadeModule : public ::bluetooth::facade::CertFacade {
+class HciTransportationService;
+
+class HalFacadeModule : public ::bluetooth::grpc::GrpcFacadeModule {
  public:
-  void StartUp(::grpc::ServerCompletionQueue* cq) override;
+  static const ModuleFactory Factory;
 
-  void ShutDown() override;
+  void ListDependencies(ModuleList* list) override;
 
-  ::grpc::Service* GetModuleGrpcService() const override;
+  void Start(const ModuleRegistry* registry) override;
+  void Stop(const ModuleRegistry* registry) override;
 
-  struct HciEvtListener {
-    virtual ~HciEvtListener() = default;
-    virtual void operator()(const hal::HciPacket&) {}
-  };
-
-  void RegisterHciEvtListener(HciEvtListener* listener);
-  void UnregisterHciEvtListener(HciEvtListener* listener);
-
-  struct HciAclListener {
-    virtual ~HciAclListener() = default;
-    virtual void operator()(const hal::HciPacket&) {}
-  };
-
-  void RegisterHciAclListener(HciAclListener* listener);
-  void UnregisterHciAclListener(HciAclListener* listener);
-
-  struct HciScoListener {
-    virtual ~HciScoListener() = default;
-    virtual void operator()(const hal::HciPacket&) {}
-  };
-
-  void RegisterHciScoListener(HciScoListener* listener);
-  void UnregisterHciScoListener(HciScoListener* listener);
+  ::grpc::Service* GetService() const override;
 
  private:
-  std::mutex mutex_;
+  HciTransportationService* service_;
   friend class IncomingPacketCallback;
-  std::list<HciEvtListener*> registered_evt_listener_;
-  std::list<HciAclListener*> registered_acl_listener_;
-  std::list<HciScoListener*> registered_sco_listener_;
 };
 
 }  // namespace facade
diff --git a/gd/hal/hci_hal.h b/gd/hal/hci_hal.h
index 375af4b..b8d6849 100644
--- a/gd/hal/hci_hal.h
+++ b/gd/hal/hci_hal.h
@@ -18,6 +18,8 @@
 
 #include <vector>
 
+#include "module.h"
+
 namespace bluetooth {
 namespace hal {
 
@@ -47,15 +49,6 @@
   virtual void scoDataReceived(HciPacket data) = 0;
 };
 
-// Callback for BluetoothHciHal::initialize()
-class BluetoothInitializationCompleteCallback {
- public:
-  virtual ~BluetoothInitializationCompleteCallback() = default;
-
-  // Invoked when the Bluetooth controller initialization has been completed
-  virtual void initializationComplete(Status status) = 0;
-};
-
 // Mirrors hardware/interfaces/bluetooth/1.0/IBluetoothHci.hal in Android
 // The Host Controller Interface (HCI) is the layer defined by the Bluetooth
 // specification between the software that runs on the host and the Bluetooth
@@ -63,24 +56,11 @@
 // Abstraction Layer (HAL). Dealing only in HCI packets and events simplifies
 // the stack and abstracts away power management, initialization, and other
 // implementation-specific details related to the hardware.
-class BluetoothHciHal {
+class BluetoothHciHal : public ::bluetooth::Module {
  public:
-  virtual ~BluetoothHciHal() = default;
+  static const ModuleFactory Factory;
 
-  // Initialize the underlying HCI interface.
-  //
-  // This method should be used to initialize any hardware interfaces
-  // required to communicate with the Bluetooth hardware in the
-  // device.
-  //
-  // The |InitializationCompleteCallback| callback must be invoked in response
-  // to this function to indicate success before any other function
-  // (sendHciCommand, sendAclData, * sendScoData) is invoked on this
-  // interface.
-  //
-  // @param callback implements BluetoothInitializationCompleteCallback which will
-  //    receive callbacks when incoming HCI initialization is complete
-  virtual void initialize(BluetoothInitializationCompleteCallback* callback) = 0;
+  virtual ~BluetoothHciHal() = default;
 
   // Register the callback for incoming packets. All incoming packets are dropped before
   // this callback is registered. Callback can only be registered once, but will be reset
@@ -107,12 +87,7 @@
   // V4.2, Vol 2, Part 5, Section 5.4.3) to the Bluetooth controller.
   // Packets must be processed in order.
   virtual void sendScoData(HciPacket data) = 0;
-
-  // Close the HCI interface
-  virtual void close() = 0;
 };
 
-BluetoothHciHal* GetBluetoothHciHal();
-
 }  // namespace hal
 }  // namespace bluetooth
diff --git a/gd/hal/hci_hal_android_hidl.cc b/gd/hal/hci_hal_android_hidl.cc
index 217da9f..0c2b56f 100644
--- a/gd/hal/hci_hal_android_hidl.cc
+++ b/gd/hal/hci_hal_android_hidl.cc
@@ -18,6 +18,7 @@
 
 #include <stdlib.h>
 #include <vector>
+#include <future>
 
 #include <android/hardware/bluetooth/1.0/IBluetoothHci.h>
 #include <android/hardware/bluetooth/1.0/IBluetoothHciCallbacks.h>
@@ -50,9 +51,10 @@
 
 class HciHalBluetoothHciCallbacks : public IBluetoothHciCallbacks {
  public:
-  HciHalBluetoothHciCallbacks(BluetoothInitializationCompleteCallback* initialization_callback,
-                              BluetoothSnoopLogger* btsnoop_logger)
-      : initialization_callback_(initialization_callback), btsnoop_logger_(btsnoop_logger) {}
+  HciHalBluetoothHciCallbacks(BluetoothSnoopLogger* btsnoop_logger)
+      : btsnoop_logger_(btsnoop_logger) {
+    init_promise_ = new std::promise<void>();
+  }
 
   void SetCallback(BluetoothHciHalCallbacks* callback) {
     ASSERT(callback_ == nullptr && callback != nullptr);
@@ -63,9 +65,13 @@
     callback_ = nullptr;
   }
 
+  std::promise<void>* GetInitPromise() {
+    return init_promise_;
+  }
+
   Return<void> initializationComplete(HidlStatus status) {
     ASSERT(status == HidlStatus::SUCCESS);
-    initialization_callback_->initializationComplete(Status::SUCCESS);
+    init_promise_->set_value();
     return Void();
   }
 
@@ -100,7 +106,7 @@
   }
 
  private:
-  BluetoothInitializationCompleteCallback* initialization_callback_ = nullptr;
+  std::promise<void>* init_promise_ = nullptr;
   BluetoothHciHalCallbacks* callback_ = nullptr;
   BluetoothSnoopLogger* btsnoop_logger_ = nullptr;
 };
@@ -109,19 +115,6 @@
 
 class BluetoothHciHalHidl : public BluetoothHciHal {
  public:
-  void initialize(BluetoothInitializationCompleteCallback* callback) override {
-    btsnoop_logger_ = new BluetoothSnoopLogger(kDefaultBtsnoopPath);
-    bt_hci_ = IBluetoothHci::getService();
-    ASSERT(bt_hci_ != nullptr);
-    auto death_link = bt_hci_->linkToDeath(bluetooth_hci_death_recipient_, 0);
-    ASSERT_LOG(death_link.isOk(), "Unable to set the death recipient for the Bluetooth HAL");
-    // Block allows allocation of a variable that might be bypassed by goto.
-    {
-      callbacks_ = new HciHalBluetoothHciCallbacks(callback, btsnoop_logger_);
-      bt_hci_->initialize(callbacks_);
-    }
-  }
-
   void registerIncomingPacketCallback(BluetoothHciHalCallbacks* callback) override {
     callbacks_->SetCallback(callback);
   }
@@ -141,7 +134,27 @@
     bt_hci_->sendScoData(packet);
   }
 
-  void close() override {
+ protected:
+  void ListDependencies(ModuleList* list) override {
+    // We have no dependencies
+  }
+
+  void Start(const ModuleRegistry* registry) override {
+    btsnoop_logger_ = new BluetoothSnoopLogger(kDefaultBtsnoopPath);
+    bt_hci_ = IBluetoothHci::getService();
+    ASSERT(bt_hci_ != nullptr);
+    auto death_link = bt_hci_->linkToDeath(bluetooth_hci_death_recipient_, 0);
+    ASSERT_LOG(death_link.isOk(), "Unable to set the death recipient for the Bluetooth HAL");
+    // Block allows allocation of a variable that might be bypassed by goto.
+    {
+      callbacks_ = new HciHalBluetoothHciCallbacks(btsnoop_logger_);
+      bt_hci_->initialize(callbacks_);
+      // Don't timeout here, time out at a higher layer
+      callbacks_->GetInitPromise()->get_future().wait();
+    }
+  }
+
+  void Stop(const ModuleRegistry* registry) override {
     ASSERT(bt_hci_ != nullptr);
     auto death_unlink = bt_hci_->unlinkToDeath(bluetooth_hci_death_recipient_);
     if (!death_unlink.isOk()) {
@@ -160,10 +173,9 @@
   BluetoothSnoopLogger* btsnoop_logger_;
 };
 
-BluetoothHciHal* GetBluetoothHciHal() {
-  static auto* instance = new BluetoothHciHalHidl;
-  return instance;
-}
+const ModuleFactory BluetoothHciHal::Factory = ModuleFactory([]() {
+  return new BluetoothHciHalHidl();
+});
 
 }  // namespace hal
 }  // namespace bluetooth
diff --git a/gd/hal/hci_hal_android_hidl_test.cc b/gd/hal/hci_hal_android_hidl_test.cc
index 0171fc5..01eaa2d 100644
--- a/gd/hal/hci_hal_android_hidl_test.cc
+++ b/gd/hal/hci_hal_android_hidl_test.cc
@@ -25,38 +25,20 @@
 namespace hal {
 namespace {
 
-std::promise<void>* g_promise;
-
-class TestBluetoothInitializationCompleteCallback : public BluetoothInitializationCompleteCallback {
- public:
-  void initializationComplete(Status status) override {
-    EXPECT_EQ(status, Status::SUCCESS);
-    g_promise->set_value();
-  }
-};
-
 class HciHalHidlTest : public ::testing::Test {
  protected:
   void SetUp() override {
-    g_promise = new std::promise<void>;
-    hal_ = GetBluetoothHciHal();
-    hal_->initialize(&init_callback_);
   }
 
   void TearDown() override {
-    hal_->close();
-    hal_ = nullptr;
-    delete g_promise;
   }
 
-  BluetoothHciHal* hal_ = nullptr;
-  TestBluetoothInitializationCompleteCallback init_callback_;
+  ModuleRegistry fake_registry_;
 };
 
 TEST_F(HciHalHidlTest, init_and_close) {
-  // Give a long timeout because this only checks HAL is initialized, not performance
-  auto wait_status = g_promise->get_future().wait_for(std::chrono::seconds(30));
-  EXPECT_EQ(wait_status, std::future_status::ready);
+  fake_registry_.Start<BluetoothHciHal>();
+  fake_registry_.StopAll();
 }
 }  // namespace
 }  // namespace hal
diff --git a/gd/hal/hci_hal_host_rootcanal.cc b/gd/hal/hci_hal_host_rootcanal.cc
index 4c8cf9e..94afad7 100644
--- a/gd/hal/hci_hal_host_rootcanal.cc
+++ b/gd/hal/hci_hal_host_rootcanal.cc
@@ -17,6 +17,7 @@
 #include "hal/hci_hal_host_rootcanal.h"
 #include "hal/hci_hal.h"
 
+#include <csignal>
 #include <fcntl.h>
 #include <netdb.h>
 #include <unistd.h>
@@ -85,18 +86,6 @@
 
 class BluetoothHciHalHostRootcanal : public BluetoothHciHal {
  public:
-  void initialize(BluetoothInitializationCompleteCallback* callback) override {
-    std::lock_guard<std::mutex> lock(mutex_);
-    ASSERT(sock_fd_ == INVALID_FD && callback != nullptr);
-    sock_fd_ = ConnectToRootCanal(config_->GetServerAddress(), config_->GetPort());
-    ASSERT(sock_fd_ != INVALID_FD);
-    reactable_ =
-        hci_incoming_thread_.GetReactor()->Register(sock_fd_, [this]() { this->incoming_packet_received(); }, nullptr);
-    callback->initializationComplete(Status::SUCCESS);
-    btsnoop_logger_ = new BluetoothSnoopLogger(kDefaultBtsnoopPath);
-    LOG_INFO("Rootcanal HAL opened successfully");
-  }
-
   void registerIncomingPacketCallback(BluetoothHciHalCallbacks* callback) override {
     std::lock_guard<std::mutex> lock(mutex_);
     ASSERT(incoming_packet_callback_ == nullptr && callback != nullptr);
@@ -130,7 +119,23 @@
     write_to_rootcanal_fd(packet);
   }
 
-  void close() override {
+ protected:
+  void ListDependencies(ModuleList* list) override {
+    // We have no dependencies
+  }
+
+  void Start(const ModuleRegistry* registry) override {
+    std::lock_guard<std::mutex> lock(mutex_);
+    ASSERT(sock_fd_ == INVALID_FD);
+    sock_fd_ = ConnectToRootCanal(config_->GetServerAddress(), config_->GetPort());
+    ASSERT(sock_fd_ != INVALID_FD);
+    reactable_ =
+        hci_incoming_thread_.GetReactor()->Register(sock_fd_, [this]() { this->incoming_packet_received(); }, nullptr);
+    btsnoop_logger_ = new BluetoothSnoopLogger(kDefaultBtsnoopPath);
+    LOG_INFO("Rootcanal HAL opened successfully");
+  }
+
+  void Stop(const ModuleRegistry* registry) override {
     std::lock_guard<std::mutex> lock(mutex_);
     delete btsnoop_logger_;
     btsnoop_logger_ = nullptr;
@@ -187,8 +192,8 @@
     RUN_NO_INTR(received_size = recv(sock_fd_, buf, kH4HeaderSize, 0));
     ASSERT_LOG(received_size != -1, "Can't receive from socket: %s", strerror(errno));
     if (received_size == 0) {
-      LOG_WARN("Can't read H4 header. Closing this Rootcanal HAL.");
-      close();
+      LOG_WARN("Can't read H4 header.");
+      raise(SIGINT);
       return;
     }
 
@@ -247,18 +252,9 @@
   }
 };
 
-namespace {
-BluetoothHciHalHostRootcanal* instance = new BluetoothHciHalHostRootcanal;
-}
-
-BluetoothHciHal* GetBluetoothHciHal() {
-  return instance;
-}
-
-void ResetRootcanalHal() {
-  delete instance;
-  instance = new BluetoothHciHalHostRootcanal;
-}
+const ModuleFactory BluetoothHciHal::Factory = ModuleFactory([]() {
+  return new BluetoothHciHalHostRootcanal();
+});
 
 }  // namespace hal
 }  // namespace bluetooth
diff --git a/gd/hal/hci_hal_host_rootcanal.h b/gd/hal/hci_hal_host_rootcanal.h
index a34d741..9b73b15 100644
--- a/gd/hal/hci_hal_host_rootcanal.h
+++ b/gd/hal/hci_hal_host_rootcanal.h
@@ -55,8 +55,5 @@
   std::string server_address_ = "127.0.0.1";  // Default server address
 };
 
-// Destroy and construct a new rootcanal HAL to clear all internal states
-void ResetRootcanalHal();
-
 }  // namespace hal
 }  // namespace bluetooth
diff --git a/gd/hal/hci_hal_host_rootcanal_test.cc b/gd/hal/hci_hal_host_rootcanal_test.cc
index e26ec95..33b6221 100644
--- a/gd/hal/hci_hal_host_rootcanal_test.cc
+++ b/gd/hal/hci_hal_host_rootcanal_test.cc
@@ -50,13 +50,6 @@
 
 std::queue<std::pair<uint8_t, HciPacket>> incoming_packets_queue_;
 
-class TestBluetoothInitializationCompleteCallback : public BluetoothInitializationCompleteCallback {
- public:
-  void initializationComplete(Status status) override {
-    EXPECT_EQ(status, Status::SUCCESS);
-  }
-};
-
 class TestBluetoothHciHalCallbacks : public BluetoothHciHalCallbacks {
  public:
   void hciEventReceived(HciPacket packet) override {
@@ -141,8 +134,8 @@
   void SetUp() override {
     HciHalHostRootcanalConfig::Get()->SetPort(kTestPort);
     fake_server_ = new FakeRootcanalDesktopHciServer;
-    hal_ = GetBluetoothHciHal();
-    hal_->initialize(&init_callback_);
+    fake_registry_.Start<BluetoothHciHal>();
+    hal_ = fake_registry_.GetInstance<BluetoothHciHal>();
     hal_->registerIncomingPacketCallback(&callbacks_);
     fake_server_socket_ = fake_server_->Accept();  // accept() after client is connected to avoid blocking
     std::queue<std::pair<uint8_t, HciPacket>> empty;
@@ -150,7 +143,7 @@
   }
 
   void TearDown() override {
-    hal_->close();
+    fake_registry_.StopAll();
     close(fake_server_socket_);
     delete fake_server_;
   }
@@ -163,7 +156,7 @@
 
   FakeRootcanalDesktopHciServer* fake_server_ = nullptr;
   BluetoothHciHal* hal_ = nullptr;
-  TestBluetoothInitializationCompleteCallback init_callback_;
+  ModuleRegistry fake_registry_;
   TestBluetoothHciHalCallbacks callbacks_;
   int fake_server_socket_ = -1;
 };
diff --git a/gd/module.cc b/gd/module.cc
index 95f4d10..cf8b7e9 100644
--- a/gd/module.cc
+++ b/gd/module.cc
@@ -27,21 +27,25 @@
 
 void ModuleRegistry::Start(ModuleList* modules) {
   for (auto it = modules->list_.begin(); it != modules->list_.end(); it++) {
-    if (IsStarted(*it)) {
-      continue;
-    }
-
-    Module* instance = (*it)->ctor_();
-    ModuleList dependencies;
-    instance->ListDependencies(&dependencies);
-    Start(&dependencies);
-
-    instance->Start(this);
-    start_order_.push_back(*it);
-    started_modules_[*it] = instance;
+    Start(*it);
   }
 }
 
+void ModuleRegistry::Start(const ModuleFactory* module) {
+  if (IsStarted(module)) {
+    return;
+  }
+
+  Module* instance = module->ctor_();
+  ModuleList dependencies;
+  instance->ListDependencies(&dependencies);
+  Start(&dependencies);
+
+  instance->Start(this);
+  start_order_.push_back(module);
+  started_modules_[module] = instance;
+}
+
 void ModuleRegistry::StopAll() {
   // Since modules were brought up in dependency order,
   // it is safe to tear down by going in reverse order.
diff --git a/gd/module.h b/gd/module.h
index 2e78bca..a073649 100644
--- a/gd/module.h
+++ b/gd/module.h
@@ -90,6 +90,13 @@
   // in dependency order
   void Start(ModuleList* modules);
 
+  template <class T>
+  void Start() {
+    Start(&T::Factory);
+  }
+
+  void Start(const ModuleFactory* id);
+
   // Stop all running modules in reverse order of start
   void StopAll();
 
diff --git a/gd/stack_manager.cc b/gd/stack_manager.cc
index 8e859e8..e3749ac 100644
--- a/gd/stack_manager.cc
+++ b/gd/stack_manager.cc
@@ -21,49 +21,47 @@
 #include <queue>
 
 #include "hal/hci_hal.h"
+#include "os/thread.h"
 #include "os/handler.h"
 #include "os/log.h"
+#include "module.h"
 
-using ::bluetooth::hal::BluetoothHciHalCallbacks;
-using ::bluetooth::hal::BluetoothInitializationCompleteCallback;
-using ::bluetooth::hal::HciPacket;
-using ::bluetooth::hal::Status;
 using ::bluetooth::os::Handler;
 using ::bluetooth::os::Thread;
 
 namespace bluetooth {
-namespace {
-std::promise<void>* startup_promise;
 
-class InitCallback : public BluetoothInitializationCompleteCallback {
- public:
-  void initializationComplete(Status status) override {
-    ASSERT(status == Status::SUCCESS);
-    startup_promise->set_value();
-  }
-} init_callback;
+void StackManager::StartUp(ModuleList* modules) {
+  management_thread_ = new Thread("management_thread", Thread::Priority::NORMAL);
+  handler_ = new Handler(management_thread_);
 
-Thread* main_thread_;
+  std::promise<void>* promise = new std::promise<void>();
+  handler_->Post([this, promise, modules]() {
+    registry_.Start(modules);
+    promise->set_value();
+  });
 
-}  // namespace
-
-void StackManager::StartUp() {
-  startup_promise = new std::promise<void>;
-  ::bluetooth::hal::GetBluetoothHciHal()->initialize(&init_callback);
-  auto init_status = startup_promise->get_future().wait_for(std::chrono::seconds(3));
-  ASSERT_LOG(init_status == std::future_status::ready, "Can't initialize HCI HAL");
-  delete startup_promise;
-
-  main_thread_ = new Thread("main_thread", Thread::Priority::NORMAL);
+  auto future = promise->get_future();
+  auto init_status = future.wait_for(std::chrono::seconds(3));
+  ASSERT_LOG(init_status == std::future_status::ready, "Can't start stack");
+  delete promise;
 
   LOG_INFO("init complete");
-  // Bring up HCI layer
 }
 
 void StackManager::ShutDown() {
-  // Delete HCI layer
-  delete main_thread_;
-  main_thread_ = nullptr;
-  ::bluetooth::hal::GetBluetoothHciHal()->close();
+  std::promise<void>* promise = new std::promise<void>();
+  handler_->Post([this, promise]() {
+    registry_.StopAll();
+    promise->set_value();
+  });
+
+  auto future = promise->get_future();
+  auto stop_status = future.wait_for(std::chrono::seconds(3));
+  ASSERT_LOG(stop_status == std::future_status::ready, "Can't stop stack");
+
+  delete promise;
+  delete handler_;
+  delete management_thread_;
 }
 }  // namespace bluetooth
diff --git a/gd/stack_manager.h b/gd/stack_manager.h
index 11d218b..b9fb985 100644
--- a/gd/stack_manager.h
+++ b/gd/stack_manager.h
@@ -16,23 +16,26 @@
 
 #pragma once
 
+#include "module.h"
+#include "os/thread.h"
+#include "os/handler.h"
+
 namespace bluetooth {
 
 class StackManager {
  public:
-  static StackManager* Get() {
-    static StackManager instance;
-    return &instance;
-  }
-
-  // Start up the stack, init HCI HAL
-  void StartUp();
-
-  // Shut down the stack, close HCI HAL
+  void StartUp(ModuleList *modules);
   void ShutDown();
 
+  template <class T>
+  T* GetInstance() const {
+    return registry_.GetInstance<T>();
+  }
+
  private:
-  StackManager() = default;
+  os::Thread* management_thread_;
+  os::Handler* handler_;
+  ModuleRegistry registry_;
 };
 
 }  // namespace bluetooth