test_vendor_lib: Use base::Thread

This upload starts the replacement of the event loop in HciTransport
with libbase's MessageLoopForIO. A global instance of the new
VendorManager class now manages the trio of previously global objects
(i.e. HciTransport, HciHandler, and BREDRController). Note that the new
libbase event loop structure doesn't actually handle anything right now
and the functionality will come in a future change.

Bug: 21586676
Change-Id: Id74392e2a566e06445eb65269f0142265087d47d
diff --git a/vendor_libs/test_vendor_lib/Android.mk b/vendor_libs/test_vendor_lib/Android.mk
index b6be619..2a18c86 100644
--- a/vendor_libs/test_vendor_lib/Android.mk
+++ b/vendor_libs/test_vendor_lib/Android.mk
@@ -5,14 +5,15 @@
 BT_DIR := $(TOP_DIR)system/bt
 
 LOCAL_SRC_FILES := \
-    src/bredr_controller.cc \
     src/bt_vendor.cc \
     src/command_packet.cc \
+    src/dual_mode_controller.cc \
     src/event_packet.cc \
     src/hci_handler.cc \
     src/hci_transport.cc \
     src/packet.cc \
     src/packet_stream.cc \
+    src/vendor_manager.cc \
 
 LOCAL_C_INCLUDES := \
     $(LOCAL_PATH)/include \
diff --git a/vendor_libs/test_vendor_lib/BUILD.gn b/vendor_libs/test_vendor_lib/BUILD.gn
index b62b92f..3d4b8ed 100644
--- a/vendor_libs/test_vendor_lib/BUILD.gn
+++ b/vendor_libs/test_vendor_lib/BUILD.gn
@@ -1,8 +1,8 @@
 shared_library("test_vendor_lib") {
   sources = [
-    "src/bredr_controller.cc",
     "src/bt_vendor.cc",
     "src/command_packet.cc",
+    "src/dual_mode__controller.cc",
     "src/event_packet.cc",
     "src/hci_handler.cc",
     "src/hci_transport.cc",
diff --git a/vendor_libs/test_vendor_lib/include/command_packet.h b/vendor_libs/test_vendor_lib/include/command_packet.h
index 16bb24c..f6308c0 100644
--- a/vendor_libs/test_vendor_lib/include/command_packet.h
+++ b/vendor_libs/test_vendor_lib/include/command_packet.h
@@ -44,7 +44,7 @@
  public:
   CommandPacket();
 
-  ~CommandPacket() override = default;
+  virtual ~CommandPacket() override = default;
 
   // Returns the command opcode as defined in stack/include/hcidefs.h.
   // See the Bluetooth Core Specification Version 4.2, Volume 2, Part E,
diff --git a/vendor_libs/test_vendor_lib/include/bredr_controller.h b/vendor_libs/test_vendor_lib/include/dual_mode_controller.h
similarity index 83%
rename from vendor_libs/test_vendor_lib/include/bredr_controller.h
rename to vendor_libs/test_vendor_lib/include/dual_mode_controller.h
index ebd52c8..492c487 100644
--- a/vendor_libs/test_vendor_lib/include/bredr_controller.h
+++ b/vendor_libs/test_vendor_lib/include/dual_mode_controller.h
@@ -20,37 +20,37 @@
 #include <vector>
 #include <unordered_map>
 
-#include "base/macros.h"
+#include "vendor_libs/test_vendor_lib/include/hci_handler.h"
 
 namespace test_vendor_lib {
 
-// Emulates a BR/EDR controller by maintaining the link layer state machine
-// detailed in the Bluetooth Core Specification Version 4.2, Volume 2, Part B,
-// Section 8 (page 159). Provides actions corresponding to commands sent by the
-// HCI. These actions will be registered from a single global controller
-// instance as callbacks and called from the HciHandler.
-// TODO(dennischeng): Should the controller implement an interface provided by
-// the HciHandler and be used as a delegate (i.e. the HciHandler would hold a
-// controller object) instead of registering its methods as callbacks?
-class BREDRController {
+// Emulates a dual mode BR/EDR + LE controller by maintaining the link layer
+// state machine detailed in the Bluetooth Core Specification Version 4.2,
+// Volume 6, Part B, Section 1.1 (page 30). Provides methods corresponding to
+// commands sent by the HCI. These methods will be registered as callbacks from
+// a controller instance with the HciHandler. To implement a new Bluetooth
+// command, simply add the method declaration below, with return type void and a
+// single const std::vector<std::uint8_t>& argument. After implementing the
+// method, simply register it with the HciHandler using the SET_HANDLER macro in
+// the controller's default constructor. Be sure to name your method after the
+// corresponding Bluetooth command in the Core Specification with the prefix
+// "Hci" to distinguish it as a controller command.
+class DualModeController {
  public:
+  // Sets all of the methods to be used as callbacks in the HciHandler.
+  DualModeController();
+
+  ~DualModeController() = default;
+
   // Registers command callbacks with the HciHandler instance so that they are
   // fired when the corresponding opcode is received from the HCI. For now, each
   // command must be individually registered. This allows for some flexibility
   // in which commands are made available by which controller.
-  void RegisterHandlerCallbacks();
+  void RegisterCommandsWithHandler(HciHandler& handler);
 
-  // Functions that operate on the global controller instance. Initialize()
-  // is called by the vendor library's Init() function to create the global
-  // controller and must be called before Get() and CleanUp().
-  // CleanUp() should be called when a call to TestVendorCleanUp() is made
-  // since the global controller should live throughout the entire time the test
-  // vendor library is in use.
-  static BREDRController* Get();
-
-  static void Initialize();
-
-  static void CleanUp();
+  // Sets the callback to be used for sending events back to the HCI.
+  void RegisterEventChannel(
+      std::function<void(std::unique_ptr<EventPacket>)> send_event);
 
   // Controller commands. For error codes, see the Bluetooth Core Specification,
   // Version 4.2, Volume 2, Part D (page 370).
@@ -318,12 +318,28 @@
   void HciInquiry(const std::vector<std::uint8_t>& args);
 
  private:
-  // There will only be a single global instance of this class.
-  BREDRController();
+  // Creates a command complete event and sends it back to the HCI.
+  void SendCommandComplete(uint16_t command_opcode,
+                           const std::vector<uint8_t>& return_parameters) const;
 
-  // The destructor can only be indirectly accessed through the static
-  // CleanUp() method that destructs the global controller.
-  ~BREDRController() = default;
+  // Sends a command complete event with no return parameters. This event is
+  // typically sent for commands that can be completed immediately.
+  void SendCommandCompleteSuccess(uint16_t command_opcode) const;
+
+  // Creates a command status event and sends it back to the HCI.
+  void SendCommandStatus(uint16_t command_opcode) const;
+
+  // Sends a command status event with default event parameters.
+  void SendCommandStatusSuccess(uint16_t command_opcode) const;
+
+  // Sends an inquiry response for a fake device.
+  void SendInquiryResult() const;
+
+  // Sends an extended inquiry response for a fake device.
+  void SendExtendedInquiryResult() const;
+
+  // Callback provided to send events from the controller back to the HCI.
+  std::function<void(std::unique_ptr<EventPacket>)> send_event_;
 
   // Maintains the commands to be registered and used in the HciHandler object.
   // Keys are command opcodes and values are the callbacks to handle each
@@ -332,9 +348,6 @@
                      std::function<void(const std::vector<std::uint8_t>&)>>
       active_commands_;
 
-  // Disallow any copies of the singleton to be made.
-  DISALLOW_COPY_AND_ASSIGN(BREDRController);
-
   // Specifies the format of Inquiry Result events to be returned during the
   // Inquiry command.
   // 0x00: Standard Inquiry Result event format (default).
diff --git a/vendor_libs/test_vendor_lib/include/event_packet.h b/vendor_libs/test_vendor_lib/include/event_packet.h
index e7025d9..4dc13b7 100644
--- a/vendor_libs/test_vendor_lib/include/event_packet.h
+++ b/vendor_libs/test_vendor_lib/include/event_packet.h
@@ -20,6 +20,7 @@
 #include <memory>
 #include <vector>
 
+#include "base/logging.h"
 #include "vendor_libs/test_vendor_lib/include/packet.h"
 
 namespace test_vendor_lib {
diff --git a/vendor_libs/test_vendor_lib/include/hci_handler.h b/vendor_libs/test_vendor_lib/include/hci_handler.h
index b90ab59..09dc7d4 100644
--- a/vendor_libs/test_vendor_lib/include/hci_handler.h
+++ b/vendor_libs/test_vendor_lib/include/hci_handler.h
@@ -21,8 +21,8 @@
 #include <unordered_map>
 #include <vector>
 
-#include "base/macros.h"
 #include "vendor_libs/test_vendor_lib/include/command_packet.h"
+#include "vendor_libs/test_vendor_lib/include/hci_transport.h"
 #include "vendor_libs/test_vendor_lib/include/packet.h"
 
 namespace test_vendor_lib {
@@ -30,56 +30,38 @@
 // Dispatches packets to the appropriate controller handler. These handlers
 // must be registered by controller objects in order for commands to be
 // processed. Unregistered commands will perform no operations. Exposes two
-// callbacks, HandleCommand() and HandleData(), to be registered with a listener
-// object and called when commands and data are sent by the host.
+// callbacks, HandleCommand() and HandleData(), to be registered with a
+// HciTransport object and called when commands and data are sent by the host.
 class HciHandler {
  public:
-  // Sets the command and data callbacks for when packets are received from the
-  // HCI.
-  void RegisterTransportCallbacks();
+  HciHandler() = default;
 
-  // Functions that operate on the global handler instance. Initialize()
-  // is called by the vendor library's Init() function to create the global
-  // handler and must be called before Get() and CleanUp().
-  // CleanUp() should be called when a call to TestVendorCleanUp() is made
-  // since the global handler should live throughout the entire time the test
-  // vendor library is in use.
-  static HciHandler* Get();
-
-  static void Initialize();
-
-  static void CleanUp();
+  ~HciHandler() = default;
 
   // Callback to be fired when a command packet is received from the HCI. Takes
   // ownership of the packet and dispatches work to the controller through the
   // callback registered with the command's opcode. After the controller
   // finishes processing the command and the callback returns, the command
   // packet is destroyed.
-  void HandleCommand(std::unique_ptr<CommandPacket> command);
+  void HandleCommand(std::unique_ptr<CommandPacket> command_packet);
 
   // Creates the mapping from the opcode to the method |callback|.
   // |callback|, which is provided by the controller, will be fired when its
   // command opcode is received from the HCI.
-  void RegisterControllerCallback(
+  void RegisterControllerCommand(
       std::uint16_t opcode,
       std::function<void(const std::vector<std::uint8_t> args)> callback);
 
+  // Sets the command and data callbacks for when packets are received from the
+  // HCI.
+  void RegisterHandlersWithTransport(HciTransport& transport);
+
  private:
-  // There will only be a single global instance of this class.
-  HciHandler() = default;
-
-  // The destructor can only be indirectly accessed through the static
-  // CleanUp() method that destructs the global handler.
-  ~HciHandler() = default;
-
-  // Disallow any copies of the singleton to be made.
-  DISALLOW_COPY_AND_ASSIGN(HciHandler);
-
   // Controller callbacks to be executed in handlers and registered in
   // RegisterControllerCallback().
   std::unordered_map<std::uint16_t,
                      std::function<void(const std::vector<std::uint8_t> args)> >
-      callbacks_;
+      commands_;
 };
 
 }  // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/include/hci_transport.h b/vendor_libs/test_vendor_lib/include/hci_transport.h
index 9a1bd31..e994255 100644
--- a/vendor_libs/test_vendor_lib/include/hci_transport.h
+++ b/vendor_libs/test_vendor_lib/include/hci_transport.h
@@ -24,7 +24,7 @@
 #include <sys/epoll.h>
 }  // extern "C"
 
-#include "base/macros.h"
+#include "base/message_loop/message_loop.h"
 #include "vendor_libs/test_vendor_lib/include/command_packet.h"
 #include "vendor_libs/test_vendor_lib/include/event_packet.h"
 #include "vendor_libs/test_vendor_lib/include/packet.h"
@@ -32,99 +32,59 @@
 
 namespace test_vendor_lib {
 
-// Manages communication channel between HCI and the controller. Listens for
-// available events from the host and receives packeted data when it is ready.
-// Also exposes a single send method for the controller to pass events back to
-// the HCI.
-// TODO(dennischeng): Create a nested delegate interface and have the HciHandler
-// subclass that interface instead of using callbacks.
-class HciTransport {
+// Manages communication channel between HCI and the controller by providing the
+// socketing mechanisms for reading/writing between the HCI and the controller.
+class HciTransport : public base::MessageLoopForIO::Watcher {
  public:
-  // Returns the HCI's file descriptor for sending commands and data to the
-  // controller and for receiving events back.
+  HciTransport() = default;
+
+  virtual ~HciTransport() = default;
+
   int GetHciFd() const;
 
-  // Functions that operate on the global transport instance. Initialize()
-  // is called by the vendor library's Init() function to create the global
-  // transport and must be called before Get() and CleanUp().
-  // CleanUp() should be called when a call to TestVendorCleanUp() is made
-  // since the global transport should live throughout the entire time the test
-  // vendor library is in use.
-  static HciTransport* Get();
+  int GetVendorFd() const;
 
-  static void Initialize();
+  // Creates the underlying socketpair to be used as a communication channel
+  // between the HCI and the vendor library/controller.
+  bool SetUp();
 
-  static void CleanUp();
-
-  // Creates the underlying socketpair and packet stream object. Returns true if
-  // the connection was successfully made.
-  bool Connect();
-
-  // Waits for events on the listener end of the socketpair. Fires the
-  // associated callback for each type of packet when data is received via
-  // |packet_stream_|. Returns false if an error occurs.
-  bool Listen();
-
-  // Sets the callback that is run when command packets are sent by the HCI.
-  void RegisterCommandCallback(
+  // Sets the callback that is run when command packets are received.
+  void RegisterCommandHandler(
       std::function<void(std::unique_ptr<CommandPacket>)> callback);
 
-  // Posts the event onto |outgoing_events_| to be written whenever the HCI file
-  // descriptor is ready for writing.
+  // Posts the event onto |outgoing_events_| to be written sometime in the
+  // future when the vendor file descriptor is ready for writing.
   void SendEvent(std::unique_ptr<EventPacket> event);
 
  private:
-  // Loops through the epoll event buffer and receives packets if they are
-  // ready. Fires the corresponding handler callback for each received packet.
-  bool CheckReadyEpollEvents(const epoll_event& event_buffer, int num_ready);
+  // base::MessageLoopForIO::Watcher overrides:
+  void OnFileCanReadWithoutBlocking(int fd) override;
 
-  // Receives a packet from the HCI whenever the event loop signals that there
-  // is data to be received.
-  bool ReceiveReadyPacket() const;
+  void OnFileCanWriteWithoutBlocking(int fd) override;
 
-  // Reads in a command packet and calls the handler's command ready callback,
-  // passing owernship of the command packet to the handler.
+  // Reads in a command packet and calls the HciHandler's command ready
+  // callback, passing owernship of the command packet to the HciHandler.
   void ReceiveReadyCommand() const;
 
-  // Sends the event at the front of |outgoing_events_| to the HCI.
-  bool SendReadyEvent();
-
-  // There will only be one global instance of the HCI transport used by
-  // bt_vendor.cc and accessed via the static GetInstance() function.
-  HciTransport();
-
-  // The destructor can only be indirectly accessed through the static
-  // CleanUp() method that destructs the global transport.
-  ~HciTransport();
-
-  // Sets up the epoll instance and registers the listener fd. Returns true on
-  // success.
-  // TODO(dennischeng): import base/ and use a MessageLoopForIO for event loop.
-  bool ConfigEpoll();
-
   // Write queue for sending events to the HCI. Event packets are removed from
-  // the queue and written when write-readiness is signalled.
-  std::queue<std::unique_ptr<EventPacket>> outgoing_events_;
+  // the queue and written when write-readiness is signalled by the message
+  // loop.
+  // TODO(dennischeng): Use std::unique_ptr here.
+  std::queue<EventPacket*> outgoing_events_;
 
-  // Callback executed in Listen() for command packets.
-  std::function<void(std::unique_ptr<CommandPacket>)> command_callback_;
+  // Callback executed in ReceiveReadyCommand() to pass the incoming command
+  // over to the HciHandler for further processing.
+  std::function<void(std::unique_ptr<CommandPacket>)> command_handler_;
 
-  // File descriptor for epoll instance. Closed in the HciTransport destructor.
-  int epoll_fd_;
-
-  // Used to guard against multiple calls to Connect().
-  bool connected_;
-
-  // For performing packet IO.
+  // For performing packet-based IO.
   PacketStream packet_stream_;
 
   // The two ends of the socket pair used to communicate with the HCI.
-  // |socketpair_fds_[0]| is the listener end and is closed in the PacketStream
-  // object. |socketpair_fds_[1]| is the HCI end and is closed in bt_vendor.cc.
+  // |socketpair_fds_[0]| is the end that is handed back to the HCI in
+  // bt_vendor.cc. It is also closed in bt_vendor.cc by the HCI.
+  // |socketpair_fds_[1]| is the vendor end, used to receive and send data in
+  // the vendor library and controller. It is closed by |packet_stream_|.
   int socketpair_fds_[2];
-
-  // Disallow any copies of the singleton to be made.
-  DISALLOW_COPY_AND_ASSIGN(HciTransport);
 };
 
 }  // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/include/vendor_manager.h b/vendor_libs/test_vendor_lib/include/vendor_manager.h
new file mode 100644
index 0000000..bea6f1c
--- /dev/null
+++ b/vendor_libs/test_vendor_lib/include/vendor_manager.h
@@ -0,0 +1,93 @@
+//
+// Copyright 2015 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 "base/macros.h"
+#include "base/threading/thread.h"
+#include "hci/include/bt_vendor_lib.h"
+#include "vendor_libs/test_vendor_lib/include/dual_mode_controller.h"
+#include "vendor_libs/test_vendor_lib/include/hci_handler.h"
+#include "vendor_libs/test_vendor_lib/include/hci_transport.h"
+
+#include <memory>
+
+namespace test_vendor_lib {
+
+class VendorManager {
+ public:
+
+  // Functions that operate on the global manager instance. Initialize()
+  // is called by the vendor library's TestVendorInitialize() function to create
+  // the global manager and must be called before Get() and CleanUp().
+  // CleanUp() should be called when a call to TestVendorCleanUp() is made
+  // since the global manager should live throughout the entire time the test
+  // vendor library is in use.
+  static void CleanUp();
+
+  static VendorManager* Get();
+
+  static void Initialize();
+
+  // Stores a copy of the vendor specific configuration callbacks passed into
+  // the vendor library from the HCI in TestVendorInit().
+  void SetVendorCallbacks(const bt_vendor_callbacks_t& callbacks);
+
+  const bt_vendor_callbacks_t& GetVendorCallbacks() const;
+
+  // Returns the HCI's file descriptor as allocated by |transport_|.
+  int GetHciFd() const;
+
+  // Returns true if |thread_| is able to be started and the
+  // StartingWatchingOnThread() task has been posted to the task runner.
+  bool Run();
+
+ private:
+  VendorManager();
+
+  ~VendorManager() = default;
+
+  // Starts watching for incoming data from the HCI and the test hook.
+  void StartWatchingOnThread();
+
+  // Creates the HCI's communication channel and overrides IO callbacks to
+  // receive and send packets.
+  HciTransport transport_;
+
+  // Multiplexes incoming requests to the appropriate methods in |controller_|.
+  HciHandler handler_;
+
+  // The controller object that provides implementations of Bluetooth commands.
+  DualModeController controller_;
+
+  // Configuration callbacks provided by the HCI for use in TestVendorOp().
+  bt_vendor_callbacks_t vendor_callbacks_;
+
+  // True if the underlying message loop (in |thread_|) is running.
+  bool running_;
+
+  // Dedicated thread for managing the message loop to receive and send packets
+  // from the HCI and to receive additional parameters from the test hook file
+  // descriptor.
+  base::Thread thread_;
+
+  // Used to handle further watching of the vendor's file descriptor after
+  // WatchFileDescriptor() is called.
+  base::MessageLoopForIO::FileDescriptorWatcher manager_watcher_;
+
+  // Prevent any copies of the singleton to be made.
+  DISALLOW_COPY_AND_ASSIGN(VendorManager);
+};
+
+}  // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/src/bt_vendor.cc b/vendor_libs/test_vendor_lib/src/bt_vendor.cc
index 4dc5076..562bcac 100644
--- a/vendor_libs/test_vendor_lib/src/bt_vendor.cc
+++ b/vendor_libs/test_vendor_lib/src/bt_vendor.cc
@@ -16,13 +16,9 @@
 
 #define LOG_TAG "bt_vendor"
 
-#include <pthread.h>
+#include "vendor_manager.h"
 
 #include "base/logging.h"
-#include "hci/include/bt_vendor_lib.h"
-#include "vendor_libs/test_vendor_lib/include/bredr_controller.h"
-#include "vendor_libs/test_vendor_lib/include/hci_handler.h"
-#include "vendor_libs/test_vendor_lib/include/hci_transport.h"
 
 extern "C" {
 #include "osi/include/log.h"
@@ -30,54 +26,20 @@
 #include <unistd.h>
 }  // extern "C"
 
-namespace {
-bt_vendor_callbacks_t* vendor_callbacks;
-
-// Wrapper for kicking off HciTransport listening on its own thread.
-void* ListenEntryPoint(void* context) {
-  while ((static_cast<test_vendor_lib::HciTransport*>(context))->Listen());
-  LOG_INFO(LOG_TAG, "HciTransport stopped listening.");
-  return NULL;
-}
-}  // namespace
-
 namespace test_vendor_lib {
 
-// Initializes event handler for test device. |p_cb| are the callbacks to be
-// used by event handler. |local_bdaddr| points to the address of the Bluetooth
+// Initializes vendor manager for test controller. |p_cb| are the callbacks to
+// be in TestVendorOp(). |local_bdaddr| points to the address of the Bluetooth
 // device. Returns 0 on success, -1 on error.
 static int TestVendorInitialize(const bt_vendor_callbacks_t* p_cb,
-                          unsigned char* /* local_bdaddr */) {
+                                unsigned char* /* local_bdaddr */) {
   LOG_INFO(LOG_TAG, "Initializing test controller.");
-
   CHECK(p_cb);
-  vendor_callbacks = const_cast<bt_vendor_callbacks_t*>(p_cb);
 
-  // Initialize global objects. The order of initialization does not matter,
-  // however all global objects should be initialized before any other work is
-  // done by the vendor library.
-  test_vendor_lib::HciTransport::Initialize();
-  test_vendor_lib::HciHandler::Initialize();
-  test_vendor_lib::BREDRController::Initialize();
-
-  // Configure the global HciTransport object.
-  HciTransport* transporter = HciTransport::Get();
-  if (!transporter->Connect()) {
-    LOG_ERROR(LOG_TAG, "Error connecting HciTransport object to HCI.");
-    return -1;
-  }
-
-  HciHandler* handler = HciHandler::Get();
-  handler->RegisterTransportCallbacks();
-
-  BREDRController* controller = BREDRController::Get();
-  controller->RegisterHandlerCallbacks();
-
-  // Start HciTransport listening on its own thread.
-  pthread_t transporter_thread;
-  pthread_create(&transporter_thread, NULL, &ListenEntryPoint,
-                 HciTransport::Get());
-  return 0;
+  VendorManager::Initialize();
+  VendorManager* manager = VendorManager::Get();
+  manager->SetVendorCallbacks(*(const_cast<bt_vendor_callbacks_t*>(p_cb)));
+  return manager->Run() ? 0 : -1;
 }
 
 // Vendor specific operations. |opcode| is the opcode for Bluedroid's vendor op
@@ -86,11 +48,8 @@
 static int TestVendorOp(bt_vendor_opcode_t opcode, void* param) {
   LOG_INFO(LOG_TAG, "Opcode received in vendor library: %d", opcode);
 
-  HciTransport* transporter = HciTransport::Get();
-  if (!transporter) {
-    LOG_ERROR(LOG_TAG, "HciTransport was not initialized");
-    return -1;
-  }
+  VendorManager* manager = VendorManager::Get();
+  CHECK(manager);
 
   switch (opcode) {
     case BT_VND_OP_POWER_CTRL: {
@@ -107,22 +66,22 @@
     // Give the HCI its fd to communicate with the HciTransport.
     case BT_VND_OP_USERIAL_OPEN: {
       LOG_INFO(LOG_TAG, "Doing op: BT_VND_OP_USERIAL_OPEN");
-      int* transporter_fd = static_cast<int*>(param);
-      transporter_fd[0] = transporter->GetHciFd();
-      LOG_INFO(LOG_TAG, "Setting HCI's fd to: %d", transporter_fd[0]);
+      int* fd_list = static_cast<int*>(param);
+      fd_list[0] = manager->GetHciFd();
+      LOG_INFO(LOG_TAG, "Setting HCI's fd to: %d", fd_list[0]);
       return 1;
     }
 
     // Close the HCI's file descriptor.
     case BT_VND_OP_USERIAL_CLOSE:
       LOG_INFO(LOG_TAG, "Doing op: BT_VND_OP_USERIAL_CLOSE");
-      LOG_INFO(LOG_TAG, "Closing HCI's fd (fd: %d)", transporter->GetHciFd());
-      close(transporter->GetHciFd());
+      LOG_INFO(LOG_TAG, "Closing HCI's fd (fd: %d)", manager->GetHciFd());
+      close(manager->GetHciFd());
       return 1;
 
     case BT_VND_OP_FW_CFG:
       LOG_INFO(LOG_TAG, "Unsupported op: BT_VND_OP_FW_CFG");
-      vendor_callbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL);
+      manager->GetVendorCallbacks().fwcfg_cb(BT_VND_OP_RESULT_FAIL);
       return -1;
 
     default:
@@ -132,12 +91,10 @@
   return 0;
 }
 
-// Closes the vendor interface and destroys global objects.
+// Closes the vendor interface and cleans up the global vendor manager object.
 static void TestVendorCleanUp(void) {
   LOG_INFO(LOG_TAG, "Cleaning up vendor library.");
-  test_vendor_lib::BREDRController::CleanUp();
-  test_vendor_lib::HciHandler::CleanUp();
-  test_vendor_lib::HciTransport::CleanUp();
+  VendorManager::CleanUp();
 }
 
 }  // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/src/bredr_controller.cc b/vendor_libs/test_vendor_lib/src/dual_mode_controller.cc
similarity index 66%
rename from vendor_libs/test_vendor_lib/src/bredr_controller.cc
rename to vendor_libs/test_vendor_lib/src/dual_mode_controller.cc
index fd7bfed..190162e 100644
--- a/vendor_libs/test_vendor_lib/src/bredr_controller.cc
+++ b/vendor_libs/test_vendor_lib/src/dual_mode_controller.cc
@@ -14,9 +14,9 @@
 // limitations under the License.
 //
 
-#define LOG_TAG "bredr_controller"
+#define LOG_TAG "dual_mode_controller"
 
-#include "vendor_libs/test_vendor_lib/include/bredr_controller.h"
+#include "vendor_libs/test_vendor_lib/include/dual_mode_controller.h"
 
 #include "base/logging.h"
 #include "vendor_libs/test_vendor_lib/include/event_packet.h"
@@ -113,63 +113,6 @@
 const std::vector<uint8_t> kClassOfDevice = {1, 2, 3};
 const std::vector<uint8_t> kClockOffset = {1, 2};
 
-// Creates a command complete event and sends it back to the HCI.
-void SendCommandComplete(uint16_t command_opcode,
-                         const std::vector<uint8_t>& return_parameters) {
-  std::unique_ptr<test_vendor_lib::EventPacket> command_complete =
-      test_vendor_lib::EventPacket::CreateCommandCompleteEvent(
-          kNumHciCommandPackets, command_opcode, return_parameters);
-  // TODO(dennischeng): Should this dependency on HciTransport be removed?
-  test_vendor_lib::HciTransport::Get()->SendEvent(std::move(command_complete));
-}
-
-// Sends a command complete event with no return parameters. This event is
-// typically sent for commands that can be completed immediately.
-void SendEmptySuccessCommandComplete(uint16_t command_opcode) {
-  SendCommandComplete(command_opcode, {kReturnStatusSuccess});
-}
-
-// Creates a command status event and sends it back to the HCI.
-void SendCommandStatus(uint16_t command_opcode) {
-  std::unique_ptr<test_vendor_lib::EventPacket> command_status =
-      test_vendor_lib::EventPacket::CreateCommandStatusEvent(
-          kNumHciCommandPackets, command_opcode);
-  // TODO(dennischeng): Should this dependency on HciTransport be removed?
-  test_vendor_lib::HciTransport::Get()->SendEvent(std::move(command_status));
-}
-
-void SendEmptySuccessCommandStatus(uint16_t command_opcode) {
-  SendCommandComplete(command_opcode, {kReturnStatusSuccess});
-}
-
-// Sends an inquiry response for a fake device.
-void SendInquiryResult() {
-  std::unique_ptr<test_vendor_lib::EventPacket> inquiry_result =
-      test_vendor_lib::EventPacket::CreateInquiryResultEvent(
-          1, kOtherDeviceBdAddress, kPageScanRepetitionMode,
-          kPageScanPeriodMode, kPageScanMode, kClassOfDevice, kClockOffset);
-  // TODO(dennischeng): Should this dependency on HciTransport be removed?
-  test_vendor_lib::HciTransport::Get()->SendEvent(std::move(inquiry_result));
-}
-
-// Sends an extended inquiry response for a fake device.
-void SendExtendedInquiryResult() {
-  std::vector<uint8_t> rssi = {0};
-  std::vector<uint8_t> extended_inquiry_data = {7, 0x09,
-                                                'F', 'o', 'o', 'B', 'a', 'r'};
-  // TODO(dennischeng): Use constants for parameter sizes, here and elsewhere.
-  while (extended_inquiry_data.size() < 240) {
-    extended_inquiry_data.push_back(0);
-  }
-  std::unique_ptr<test_vendor_lib::EventPacket> extended_inquiry_result =
-      test_vendor_lib::EventPacket::CreateExtendedInquiryResultEvent(
-          kOtherDeviceBdAddress, kPageScanRepetitionMode, kPageScanPeriodMode,
-          kClassOfDevice, kClockOffset, rssi, extended_inquiry_data);
-  // TODO(dennischeng): Should this dependency on HciTransport be removed?
-  test_vendor_lib::HciTransport::Get()->SendEvent(
-      std::move(extended_inquiry_result));
-}
-
 void LogCommand(const char* command) {
   LOG_INFO(LOG_TAG, "Controller performing command: %s", command);
 }
@@ -178,34 +121,59 @@
 
 namespace test_vendor_lib {
 
-// Global controller instance used in the vendor library.
-// TODO(dennischeng): Should this be moved to an unnamed namespace?
-BREDRController* g_controller = nullptr;
-
-// static
-BREDRController* BREDRController::Get() {
-  // Initialize should have been called already.
-  CHECK(g_controller);
-  return g_controller;
+void DualModeController::SendCommandComplete(
+    uint16_t command_opcode,
+    const std::vector<uint8_t>& return_parameters) const {
+  std::unique_ptr<EventPacket> command_complete =
+      EventPacket::CreateCommandCompleteEvent(
+          kNumHciCommandPackets, command_opcode, return_parameters);
+  send_event_(std::move(command_complete));
 }
 
-// static
-void BREDRController::Initialize() {
-  // Multiple calls to Initialize should not be made.
-  CHECK(!g_controller);
-  g_controller = new BREDRController();
+void DualModeController::SendCommandCompleteSuccess(
+    uint16_t command_opcode) const {
+  SendCommandComplete(command_opcode, {kReturnStatusSuccess});
 }
 
-// static
-void BREDRController::CleanUp() {
-  delete g_controller;
-  g_controller = nullptr;
+void DualModeController::SendCommandStatus(uint16_t command_opcode) const {
+  std::unique_ptr<EventPacket> command_status =
+      EventPacket::CreateCommandStatusEvent(kNumHciCommandPackets,
+                                            command_opcode);
+  send_event_(std::move(command_status));
 }
 
-BREDRController::BREDRController() {
+void DualModeController::SendCommandStatusSuccess(
+    uint16_t command_opcode) const {
+  SendCommandComplete(command_opcode, {kReturnStatusSuccess});
+}
+
+void DualModeController::SendInquiryResult() const {
+  std::unique_ptr<EventPacket> inquiry_result =
+      EventPacket::CreateInquiryResultEvent(
+          1, kOtherDeviceBdAddress, kPageScanRepetitionMode,
+          kPageScanPeriodMode, kPageScanMode, kClassOfDevice, kClockOffset);
+  send_event_(std::move(inquiry_result));
+}
+
+void DualModeController::SendExtendedInquiryResult() const {
+  std::vector<uint8_t> rssi = {0};
+  std::vector<uint8_t> extended_inquiry_data = {7, 0x09,
+                                                'F', 'o', 'o', 'B', 'a', 'r'};
+  // TODO(dennischeng): Use constants for parameter sizes, here and elsewhere.
+  while (extended_inquiry_data.size() < 240) {
+    extended_inquiry_data.push_back(0);
+  }
+  std::unique_ptr<EventPacket> extended_inquiry_result =
+      EventPacket::CreateExtendedInquiryResultEvent(
+          kOtherDeviceBdAddress, kPageScanRepetitionMode, kPageScanPeriodMode,
+          kClassOfDevice, kClockOffset, rssi, extended_inquiry_data);
+  send_event_(std::move(extended_inquiry_result));
+}
+
+DualModeController::DualModeController() {
 #define SET_HANDLER(opcode, command) \
   active_commands_[opcode] =         \
-      std::bind(&BREDRController::command, this, std::placeholders::_1);
+      std::bind(&DualModeController::command, this, std::placeholders::_1);
   SET_HANDLER(HCI_RESET, HciReset);
   SET_HANDLER(HCI_READ_BUFFER_SIZE, HciReadBufferSize);
   SET_HANDLER(HCI_HOST_BUFFER_SIZE, HciHostBufferSize);
@@ -234,45 +202,49 @@
 #undef SET_HANDLER
 }
 
-void BREDRController::RegisterHandlerCallbacks() {
-  HciHandler* handler = HciHandler::Get();
+void DualModeController::RegisterCommandsWithHandler(HciHandler& handler) {
   for (auto it = active_commands_.begin(); it != active_commands_.end(); ++it) {
-    handler->RegisterControllerCallback(it->first, it->second);
+    handler.RegisterControllerCommand(it->first, it->second);
   }
 }
 
+void DualModeController::RegisterEventChannel(
+    std::function<void(std::unique_ptr<EventPacket>)> callback) {
+  send_event_ = callback;
+}
+
 // TODO(dennischeng): Store relevant arguments from commands as attributes of
 // the controller.
 
-void BREDRController::HciReset(const std::vector<uint8_t>& /* args */) {
+void DualModeController::HciReset(const std::vector<uint8_t>& /* args */) {
   LogCommand("Reset");
-  SendEmptySuccessCommandComplete(HCI_RESET);
+  SendCommandCompleteSuccess(HCI_RESET);
 }
 
-void BREDRController::HciReadBufferSize(
+void DualModeController::HciReadBufferSize(
     const std::vector<uint8_t>& /* args */) {
   LogCommand("Read Buffer Size");
   SendCommandComplete(HCI_READ_BUFFER_SIZE, kBufferSize);
 }
 
-void BREDRController::HciHostBufferSize(
+void DualModeController::HciHostBufferSize(
     const std::vector<uint8_t>& /* args */) {
   LogCommand("Host Buffer Size");
-  SendEmptySuccessCommandComplete(HCI_HOST_BUFFER_SIZE);
+  SendCommandCompleteSuccess(HCI_HOST_BUFFER_SIZE);
 }
 
-void BREDRController::HciReadLocalVersionInformation(
+void DualModeController::HciReadLocalVersionInformation(
                  const std::vector<uint8_t>& /* args */) {
   LogCommand("Read Local Version Information");
   SendCommandComplete(HCI_READ_LOCAL_VERSION_INFO, kLocalVersionInformation);
 }
 
-void BREDRController::HciReadBdAddr(const std::vector<uint8_t>& /* args */) {
+void DualModeController::HciReadBdAddr(const std::vector<uint8_t>& /* args */) {
   LogCommand("Read Bd Addr");
   SendCommandComplete(HCI_READ_BD_ADDR, kBdAddress);
 }
 
-void BREDRController::HciReadLocalSupportedCommands(
+void DualModeController::HciReadLocalSupportedCommands(
     const std::vector<uint8_t>& /* args */) {
   LogCommand("Read Local Supported Commands");
   std::vector<uint8_t> return_parameters;
@@ -284,67 +256,69 @@
   SendCommandComplete(HCI_READ_LOCAL_SUPPORTED_CMDS, return_parameters);
 }
 
-void BREDRController::HciReadLocalExtendedFeatures(
+void DualModeController::HciReadLocalExtendedFeatures(
     const std::vector<uint8_t>& /* args */) {
   LogCommand("Read Local Extended Features");
   SendCommandComplete(HCI_READ_LOCAL_EXT_FEATURES, kLocalExtendedFeatures);
 }
 
-void BREDRController::HciWriteSimplePairingMode(
+void DualModeController::HciWriteSimplePairingMode(
     const std::vector<uint8_t>& /* args */) {
   LogCommand("Write Simple Pairing Mode");
-  SendEmptySuccessCommandComplete(HCI_WRITE_SIMPLE_PAIRING_MODE);
+  SendCommandCompleteSuccess(HCI_WRITE_SIMPLE_PAIRING_MODE);
 }
 
-void BREDRController::HciWriteLeHostSupport(
+void DualModeController::HciWriteLeHostSupport(
     const std::vector<uint8_t>& /* args */) {
   LogCommand("Write Le Host Support");
-  SendEmptySuccessCommandComplete(HCI_WRITE_LE_HOST_SUPPORT);
+  SendCommandCompleteSuccess(HCI_WRITE_LE_HOST_SUPPORT);
 }
 
-void BREDRController::HciSetEventMask(const std::vector<uint8_t>& /* args */) {
+void DualModeController::HciSetEventMask(
+    const std::vector<uint8_t>& /* args */) {
   LogCommand("Set Event Mask");
-  SendEmptySuccessCommandComplete(HCI_SET_EVENT_MASK);
+  SendCommandCompleteSuccess(HCI_SET_EVENT_MASK);
 }
 
-void BREDRController::HciWriteInquiryMode(const std::vector<uint8_t>& args) {
+void DualModeController::HciWriteInquiryMode(const std::vector<uint8_t>& args) {
   LogCommand("Write Inquiry Mode");
   CHECK(args.size() == 1);
   inquiry_mode_ = args[0];
-  SendEmptySuccessCommandComplete(HCI_WRITE_INQUIRY_MODE);
+  SendCommandCompleteSuccess(HCI_WRITE_INQUIRY_MODE);
 }
 
-void BREDRController::HciWritePageScanType(
+void DualModeController::HciWritePageScanType(
     const std::vector<uint8_t>& /* args */) {
   LogCommand("Write Page Scan Type");
-  SendEmptySuccessCommandComplete(HCI_WRITE_PAGESCAN_TYPE);
+  SendCommandCompleteSuccess(HCI_WRITE_PAGESCAN_TYPE);
 }
 
-void BREDRController::HciWriteInquiryScanType(
+void DualModeController::HciWriteInquiryScanType(
     const std::vector<uint8_t>& /* args */) {
   LogCommand("Write Inquiry Scan Type");
-  SendEmptySuccessCommandComplete(HCI_WRITE_INQSCAN_TYPE);
+  SendCommandCompleteSuccess(HCI_WRITE_INQSCAN_TYPE);
 }
 
-void BREDRController::HciWriteClassOfDevice(
+void DualModeController::HciWriteClassOfDevice(
     const std::vector<uint8_t>& /* args */) {
   LogCommand("Write Class Of Device");
-  SendEmptySuccessCommandComplete(HCI_WRITE_CLASS_OF_DEVICE);
+  SendCommandCompleteSuccess(HCI_WRITE_CLASS_OF_DEVICE);
 }
 
-void BREDRController::HciWritePageTimeout(
+void DualModeController::HciWritePageTimeout(
     const std::vector<uint8_t>& /* args */) {
   LogCommand("Write Page Timeout");
-  SendEmptySuccessCommandComplete(HCI_WRITE_PAGE_TOUT);
+  SendCommandCompleteSuccess(HCI_WRITE_PAGE_TOUT);
 }
 
-void BREDRController::HciWriteDefaultLinkPolicySettings(
+void DualModeController::HciWriteDefaultLinkPolicySettings(
     const std::vector<uint8_t>& /* args */) {
   LogCommand("Write Default Link Policy Settings");
-  SendEmptySuccessCommandComplete(HCI_WRITE_DEF_POLICY_SETTINGS);
+  SendCommandCompleteSuccess(HCI_WRITE_DEF_POLICY_SETTINGS);
 }
 
-void BREDRController::HciReadLocalName(const std::vector<uint8_t>& /* args */) {
+void DualModeController::HciReadLocalName(
+    const std::vector<uint8_t>& /* args */) {
   LogCommand("Get Local Name");
   std::vector<uint8_t> return_parameters;
   return_parameters.reserve(249);
@@ -355,51 +329,51 @@
   SendCommandComplete(HCI_READ_LOCAL_NAME, return_parameters);
 }
 
-void BREDRController::HciWriteLocalName(
+void DualModeController::HciWriteLocalName(
     const std::vector<uint8_t>& /* args */) {
   LogCommand("Write Local Name");
-  SendEmptySuccessCommandComplete(HCI_CHANGE_LOCAL_NAME);
+  SendCommandCompleteSuccess(HCI_CHANGE_LOCAL_NAME);
 }
 
-void BREDRController::HciWriteExtendedInquiryResponse(
+void DualModeController::HciWriteExtendedInquiryResponse(
     const std::vector<uint8_t>& /* args */) {
   LogCommand("Write Extended Inquiry Response");
-  SendEmptySuccessCommandComplete(HCI_WRITE_EXT_INQ_RESPONSE);
+  SendCommandCompleteSuccess(HCI_WRITE_EXT_INQ_RESPONSE);
 }
 
-void BREDRController::HciWriteVoiceSetting(
+void DualModeController::HciWriteVoiceSetting(
     const std::vector<uint8_t>& /* args */) {
   LogCommand("Write Voice Setting");
-  SendEmptySuccessCommandComplete(HCI_WRITE_VOICE_SETTINGS);
+  SendCommandCompleteSuccess(HCI_WRITE_VOICE_SETTINGS);
 }
 
-void BREDRController::HciWriteCurrentIacLap(
+void DualModeController::HciWriteCurrentIacLap(
     const std::vector<uint8_t>& /* args */) {
   LogCommand("Write Current IAC LAP");
-  SendEmptySuccessCommandComplete(HCI_WRITE_CURRENT_IAC_LAP);
+  SendCommandCompleteSuccess(HCI_WRITE_CURRENT_IAC_LAP);
 }
 
-void BREDRController::HciWriteInquiryScanActivity(
+void DualModeController::HciWriteInquiryScanActivity(
     const std::vector<uint8_t>& /* args */) {
   LogCommand("Write Inquiry Scan Activity");
-  SendEmptySuccessCommandComplete(HCI_WRITE_INQUIRYSCAN_CFG);
+  SendCommandCompleteSuccess(HCI_WRITE_INQUIRYSCAN_CFG);
 }
 
-void BREDRController::HciWriteScanEnable(
+void DualModeController::HciWriteScanEnable(
     const std::vector<uint8_t>& /* args */) {
   LogCommand("Write Scan Enable");
-  SendEmptySuccessCommandComplete(HCI_WRITE_SCAN_ENABLE);
+  SendCommandCompleteSuccess(HCI_WRITE_SCAN_ENABLE);
 }
 
-void BREDRController::HciSetEventFilter(
+void DualModeController::HciSetEventFilter(
     const std::vector<uint8_t>& /* args */) {
   LogCommand("Set Event Filter");
-  SendEmptySuccessCommandComplete(HCI_SET_EVENT_FILTER);
+  SendCommandCompleteSuccess(HCI_SET_EVENT_FILTER);
 }
 
-void BREDRController::HciInquiry(const std::vector<uint8_t>& /* args */) {
+void DualModeController::HciInquiry(const std::vector<uint8_t>& /* args */) {
   LogCommand("Inquiry");
-  SendEmptySuccessCommandStatus(HCI_INQUIRY);
+  SendCommandStatusSuccess(HCI_INQUIRY);
   switch (inquiry_mode_) {
     case (kStandardInquiry):
       SendInquiryResult();
diff --git a/vendor_libs/test_vendor_lib/src/hci_handler.cc b/vendor_libs/test_vendor_lib/src/hci_handler.cc
index 9b08d96..1444db4 100644
--- a/vendor_libs/test_vendor_lib/src/hci_handler.cc
+++ b/vendor_libs/test_vendor_lib/src/hci_handler.cc
@@ -19,7 +19,6 @@
 #include "vendor_libs/test_vendor_lib/include/hci_handler.h"
 
 #include "base/logging.h"
-#include "vendor_libs/test_vendor_lib/include/hci_transport.h"
 
 extern "C" {
 #include "osi/include/log.h"
@@ -27,59 +26,31 @@
 
 namespace test_vendor_lib {
 
-// Global HciHandler instance used in the vendor library.
-// TODO(dennischeng): Should this be moved to an unnamed namespace?
-HciHandler* g_handler = nullptr;
-
-void HciHandler::RegisterTransportCallbacks() {
-  HciTransport* transporter = HciTransport::Get();
+void HciHandler::RegisterHandlersWithTransport(HciTransport& transport) {
   // Register the command packet callback with the HciTransport.
-  transporter->RegisterCommandCallback(
+  transport.RegisterCommandHandler(
       std::bind(&HciHandler::HandleCommand, this, std::placeholders::_1));
 }
 
-// static
-HciHandler* HciHandler::Get() {
-  // Initialize should have been called already.
-  CHECK(g_handler);
-  return g_handler;
-}
-
-// static
-void HciHandler::Initialize() {
-  // Multiple calls to Initialize should not be made.
-  CHECK(!g_handler);
-  g_handler = new HciHandler();
-}
-
-// static
-void HciHandler::CleanUp() {
-  delete g_handler;
-  g_handler = nullptr;
-}
-
-void HciHandler::HandleCommand(std::unique_ptr<CommandPacket> command) {
-  LOG_INFO(LOG_TAG, "Handling command packet in HciHandler.");
-
-  uint16_t opcode = command->GetOpcode();
-  LOG_INFO(LOG_TAG, "Command packet opcode: 0x%04X", opcode);
-  LOG_INFO(LOG_TAG, "Command packet OGF: 0x%04X", command->GetOGF());
-  LOG_INFO(LOG_TAG, "Command packet OCF: 0x%04X", command->GetOCF());
+void HciHandler::HandleCommand(std::unique_ptr<CommandPacket> command_packet) {
+  uint16_t opcode = command_packet->GetOpcode();
+  LOG_INFO(LOG_TAG, "Command opcode: 0x%04X, OGF: 0x%04X, OCF: 0x%04X", opcode,
+           command_packet->GetOGF(), command_packet->GetOCF());
 
   // The command hasn't been registered with the handler yet. There is nothing
   // to do.
-  if (callbacks_.count(opcode) == 0) {
+  if (commands_.count(opcode) == 0) {
     return;
   }
-  std::function<void(const std::vector<uint8_t> args)> callback =
-      callbacks_[opcode];
-  callback(command->GetPayload());
+  std::function<void(const std::vector<uint8_t> args)> command =
+      commands_[opcode];
+  command(command_packet->GetPayload());
 }
 
-void HciHandler::RegisterControllerCallback(
+void HciHandler::RegisterControllerCommand(
     uint16_t opcode,
     std::function<void(const std::vector<uint8_t> args)> callback) {
-  callbacks_[opcode] = callback;
+  commands_[opcode] = callback;
 }
 
 }  // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/src/hci_transport.cc b/vendor_libs/test_vendor_lib/src/hci_transport.cc
index 82c7020..3324fcb 100644
--- a/vendor_libs/test_vendor_lib/src/hci_transport.cc
+++ b/vendor_libs/test_vendor_lib/src/hci_transport.cc
@@ -31,144 +31,46 @@
 #include "osi/include/log.h"
 }  // extern "C"
 
-namespace {
-// The maximum number of events in the epoll event buffer.
-const int kMaxEpollEvents = 10;
-}  // namespace
-
 namespace test_vendor_lib {
 
-// Global HciTransport instance used in the vendor library.
-// TODO(dennischeng): Should this be moved to an unnamed namespace?
-HciTransport* g_transporter = nullptr;
-
-HciTransport::HciTransport() : epoll_fd_(-1), connected_(false) {}
-
-HciTransport::~HciTransport() {
-  close(epoll_fd_);
-}
-
-bool HciTransport::ConfigEpoll() {
-  epoll_fd_ = epoll_create1(EPOLL_CLOEXEC);
-  epoll_event event;
-  event.events = EPOLLIN | EPOLLOUT;
-  event.data.fd = socketpair_fds_[0];
-  return epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, socketpair_fds_[0], &event) >= 0;
-}
-
 int HciTransport::GetHciFd() const {
+  return socketpair_fds_[0];
+}
+
+int HciTransport::GetVendorFd() const {
   return socketpair_fds_[1];
 }
 
-// static
-HciTransport* HciTransport::Get() {
-  // Initialize should have been called already.
-  CHECK(g_transporter);
-  return g_transporter;
-}
-
-// static
-void HciTransport::Initialize() {
-  // Multiple calls to Initialize should not be made.
-  CHECK(!g_transporter);
-  g_transporter = new HciTransport();
-}
-
-// static
-void HciTransport::CleanUp() {
-  delete g_transporter;
-  g_transporter = nullptr;
-}
-
-bool HciTransport::Connect() {
-  if (connected_) {
-    LOG_ERROR(LOG_TAG, "Error: transporter is already connected.");
-    return false;
-  }
-
+bool HciTransport::SetUp() {
   // TODO(dennischeng): Use SOCK_SEQPACKET here.
-  if (socketpair(AF_LOCAL, SOCK_STREAM, 0, socketpair_fds_) < 0) {
-    LOG_ERROR(LOG_TAG, "Error: creating socketpair in HciTransport.");
-    return false;
-  }
-
-  // Set the descriptor for the packet stream object. |packet_stream_| will take
-  // ownership of the descriptor.
-  packet_stream_.SetFd(socketpair_fds_[0]);
-
-  // Initialize epoll instance and set the file descriptor to listen on.
-  if (ConfigEpoll() < 0) {
-    LOG_ERROR(LOG_TAG, "Error: registering hci listener with epoll instance.");
-    return false;
-  }
-
-  connected_ = true;
-  return true;
+  return socketpair(AF_LOCAL, SOCK_STREAM, 0, socketpair_fds_) >= 0;
 }
 
-bool HciTransport::Listen() {
-  epoll_event event_buffer[kMaxEpollEvents];
-  int num_ready;
+void HciTransport::OnFileCanReadWithoutBlocking(int fd) {
+  CHECK(fd == GetVendorFd());
 
-  // Check for ready events.
-  if ((num_ready = epoll_wait(epoll_fd_, event_buffer, kMaxEpollEvents, -1)) <
-      0) {
-     LOG_ERROR(LOG_TAG, "Error: epoll wait.");
-     return false;
-  }
-
-  return CheckReadyEpollEvents(*event_buffer, num_ready);
-}
-
-bool HciTransport::CheckReadyEpollEvents(const epoll_event& event_buffer,
-                                         int num_ready) {
-  for (int i = 0; i < num_ready; ++i) {
-    epoll_event event = (&event_buffer)[i];
-    // Event has data ready to be read.
-    if (event.events & EPOLLIN) {
-      return ReceiveReadyPacket();
-    }
-    if (event.events & EPOLLOUT) {
-      if (!outgoing_events_.empty()) {
-        return SendReadyEvent();
-      }
-      return true;
-    }
-  }
-  return false;
-}
-
-bool HciTransport::SendReadyEvent() {
-  bool send_successful = packet_stream_.SendEvent(*outgoing_events_.front());
-  outgoing_events_.pop();
-  return send_successful;
-}
-
-bool HciTransport::ReceiveReadyPacket() const {
   LOG_INFO(LOG_TAG, "Event ready in HciTransport.");
   serial_data_type_t packet_type = packet_stream_.ReceivePacketType();
 
   switch (packet_type) {
     case (DATA_TYPE_COMMAND): {
       ReceiveReadyCommand();
-      return true;
+      break;
     }
 
     case (DATA_TYPE_ACL): {
       LOG_INFO(LOG_TAG, "ACL data packets not currently supported.");
-      return true;
+      break;
     }
 
     case (DATA_TYPE_SCO): {
       LOG_INFO(LOG_TAG, "SCO data packets not currently supported.");
-      return true;
+      break;
     }
 
     // TODO(dennischeng): Add debug level assert here.
     default: {
-      LOG_INFO(LOG_TAG,
-               "Error received an invalid packet type from the HCI.");
-      return false;
+      LOG_INFO(LOG_TAG, "Error received an invalid packet type from the HCI.");
     }
   }
 }
@@ -177,16 +79,25 @@
   std::unique_ptr<CommandPacket> command =
       packet_stream_.ReceiveCommand();
   LOG_INFO(LOG_TAG, "Received command packet.");
-  command_callback_(std::move(command));
+  command_handler_(std::move(command));
 }
 
-void HciTransport::RegisterCommandCallback(
+void HciTransport::RegisterCommandHandler(
     std::function<void(std::unique_ptr<CommandPacket>)> callback) {
-  command_callback_ = callback;
+  command_handler_ = callback;
 }
 
+// TODO(dennischeng): Use std::move() semantics here.
 void HciTransport::SendEvent(std::unique_ptr<EventPacket> event) {
-  outgoing_events_.push(std::move(event));
+  outgoing_events_.push(event.get());
+}
+
+void HciTransport::OnFileCanWriteWithoutBlocking(int fd) {
+  CHECK(fd == GetVendorFd());
+  if (!outgoing_events_.empty()) {
+    packet_stream_.SendEvent(*outgoing_events_.front());
+    outgoing_events_.pop();
+  }
 }
 
 }  // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/src/vendor_manager.cc b/vendor_libs/test_vendor_lib/src/vendor_manager.cc
new file mode 100644
index 0000000..72df3b1
--- /dev/null
+++ b/vendor_libs/test_vendor_lib/src/vendor_manager.cc
@@ -0,0 +1,99 @@
+//
+// Copyright 2015 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.
+//
+
+#define LOG_TAG "vendor_manager"
+
+#include "vendor_manager.h"
+
+#include "base/logging.h"
+
+extern "C" {
+#include "osi/include/log.h"
+}  // extern "C"
+
+namespace test_vendor_lib {
+
+VendorManager* g_manager = nullptr;
+
+// static
+void VendorManager::CleanUp() {
+  delete g_manager;
+  g_manager = nullptr;
+}
+
+// static
+VendorManager* VendorManager::Get() {
+  // Initialize should have been called already.
+  CHECK(g_manager);
+  return g_manager;
+}
+
+// static
+void VendorManager::Initialize() {
+  CHECK(!g_manager);
+  g_manager = new VendorManager();
+}
+
+VendorManager::VendorManager()
+    : running_(false), thread_("TestVendorLibrary") {}
+
+bool VendorManager::Run() {
+  CHECK(!running_);
+
+  if (!transport_.SetUp()) {
+    LOG_ERROR(LOG_TAG, "Error setting up transport object.");
+    return false;
+  }
+
+  handler_.RegisterHandlersWithTransport(transport_);
+  controller_.RegisterCommandsWithHandler(handler_);
+  controller_.RegisterEventChannel(
+      std::bind(&HciTransport::SendEvent, transport_, std::placeholders::_1));
+
+  running_ = true;
+  if (!thread_.StartWithOptions(
+          base::Thread::Options(base::MessageLoop::TYPE_IO, 0))) {
+    LOG_ERROR(LOG_TAG, "Error starting TestVendorLibrary thread.");
+    running_ = false;
+    return false;
+  }
+
+  // TODO(dennischeng): Use PostTask() + base::Bind() to call
+  // StartWatchingOnThread().
+  return true;
+}
+
+void VendorManager::StartWatchingOnThread() {
+  CHECK(running_);
+  CHECK(base::MessageLoopForIO::IsCurrent());
+  base::MessageLoopForIO::current()->WatchFileDescriptor(
+      transport_.GetVendorFd(), true, base::MessageLoopForIO::WATCH_READ_WRITE,
+      &manager_watcher_, &transport_);
+}
+
+void VendorManager::SetVendorCallbacks(const bt_vendor_callbacks_t& callbacks) {
+  vendor_callbacks_ = callbacks;
+}
+
+const bt_vendor_callbacks_t& VendorManager::GetVendorCallbacks() const {
+  return vendor_callbacks_;
+}
+
+int VendorManager::GetHciFd() const {
+  return transport_.GetHciFd();
+}
+
+}  // namespace test_vendor_lib