OSDN Git Service

HCI: Add AdvertisingManager tests
authorMyles Watson <mylesgw@google.com>
Sat, 2 Nov 2019 00:20:22 +0000 (17:20 -0700)
committerMyles Watson <mylesgw@google.com>
Mon, 11 Nov 2019 17:05:59 +0000 (09:05 -0800)
Bug: 139080884
Test: bluetooth_test_gd
Change-Id: Ic982c2b5716cf4951b98d21ee3745bf4f6316df4

gd/hci/Android.bp
gd/hci/le_advertising_manager.cc
gd/hci/le_advertising_manager.h
gd/hci/le_advertising_manager_test.cc [new file with mode: 0644]

index ecb0f46..8784a49 100644 (file)
@@ -30,6 +30,7 @@ filegroup {
         "dual_device_test.cc",
         "hci_layer_test.cc",
         "hci_packets_test.cc",
+        "le_advertising_manager_test.cc",
         "le_scanning_manager_test.cc",
     ],
 }
index a776113..35e30a7 100644 (file)
@@ -30,6 +30,12 @@ namespace hci {
 
 const ModuleFactory LeAdvertisingManager::Factory = ModuleFactory([]() { return new LeAdvertisingManager(); });
 
+enum class AdvertisingApiType {
+  LE_4_0 = 1,
+  ANDROID_HCI = 2,
+  LE_5_0 = 3,
+};
+
 struct Advertiser {
   os::Handler* handler;
   common::Callback<void(Address, AddressType)> scan_callback;
@@ -37,14 +43,22 @@ struct Advertiser {
 };
 
 struct LeAdvertisingManager::impl {
-  impl(Module* module, os::Handler* handler, hci::HciLayer* hci_layer, hci::Controller* controller)
-      : registered_handler_(nullptr), module_(module), module_handler_(handler), hci_layer_(hci_layer),
-        controller_(controller), le_advertising_interface_(nullptr), num_instances_(0) {}
+  impl(Module* module) : module_(module), le_advertising_interface_(nullptr), num_instances_(0) {}
 
-  void start() {
+  void start(os::Handler* handler, hci::HciLayer* hci_layer, hci::Controller* controller) {
+    module_handler_ = handler;
+    hci_layer_ = hci_layer;
+    controller_ = controller;
     le_advertising_interface_ = hci_layer_->GetLeAdvertisingInterface(
         common::Bind(&LeAdvertisingManager::impl::handle_event, common::Unretained(this)), module_handler_);
     num_instances_ = controller_->GetControllerLeNumberOfSupportedAdverisingSets();
+    if (controller_->IsSupported(hci::OpCode::LE_SET_EXTENDED_ADVERTISING_PARAMETERS)) {
+      advertising_api_type_ = AdvertisingApiType::LE_5_0;
+    } else if (controller_->IsSupported(hci::OpCode::LE_MULTI_ADVT)) {
+      advertising_api_type_ = AdvertisingApiType::ANDROID_HCI;
+    } else {
+      advertising_api_type_ = AdvertisingApiType::LE_4_0;
+    }
   }
 
   size_t GetNumberOfAdvertisingInstances() const {
@@ -87,7 +101,7 @@ struct LeAdvertisingManager::impl {
     AdvertiserId id = 0;
     {
       std::unique_lock lock(id_mutex_);
-      while (id < num_instances_ && advertising_sets_.count(id) == 0) {
+      while (id < num_instances_ && advertising_sets_.count(id) != 0) {
         id++;
       }
     }
@@ -112,48 +126,72 @@ struct LeAdvertisingManager::impl {
     advertising_sets_[id].scan_callback = scan_callback;
     advertising_sets_[id].set_terminated_callback = set_terminated_callback;
     advertising_sets_[id].handler = handler;
-    if (!controller_->IsSupported(hci::OpCode::LE_MULTI_ADVT)) {
-      le_advertising_interface_->EnqueueCommand(
-          hci::LeSetAdvertisingParametersBuilder::Create(config.interval_min, config.interval_max, config.event_type,
-                                                         config.address_type, config.peer_address_type,
-                                                         config.peer_address, config.channel_map, config.filter_policy),
-          common::BindOnce(impl::check_enable_status), module_handler_);
-      le_advertising_interface_->EnqueueCommand(hci::LeSetAdvertisingDataBuilder::Create(config.advertisement),
-                                                common::BindOnce(impl::check_enable_status), module_handler_);
-      le_advertising_interface_->EnqueueCommand(hci::LeSetRandomAddressBuilder::Create(config.random_address),
-                                                common::BindOnce(impl::check_enable_status), module_handler_);
-      if (!config.scan_response.empty()) {
-        le_advertising_interface_->EnqueueCommand(hci::LeSetScanResponseDataBuilder::Create(config.scan_response),
-                                                  common::BindOnce(impl::check_enable_status), module_handler_);
-      }
-      le_advertising_interface_->EnqueueCommand(hci::LeSetAdvertisingDataBuilder::Create(config.advertisement),
-                                                common::BindOnce(impl::check_enable_status), module_handler_);
-      return;
+    switch (advertising_api_type_) {
+      case (AdvertisingApiType::LE_4_0):
+        le_advertising_interface_->EnqueueCommand(
+            hci::LeSetAdvertisingParametersBuilder::Create(
+                config.interval_min, config.interval_max, config.event_type, config.address_type,
+                config.peer_address_type, config.peer_address, config.channel_map, config.filter_policy),
+            common::BindOnce(impl::check_status<LeSetAdvertisingParametersCompleteView>), module_handler_);
+        le_advertising_interface_->EnqueueCommand(hci::LeSetRandomAddressBuilder::Create(config.random_address),
+                                                  common::BindOnce(impl::check_status<LeSetRandomAddressCompleteView>),
+                                                  module_handler_);
+        if (!config.scan_response.empty()) {
+          le_advertising_interface_->EnqueueCommand(
+              hci::LeSetScanResponseDataBuilder::Create(config.scan_response),
+              common::BindOnce(impl::check_status<LeSetScanResponseDataCompleteView>), module_handler_);
+        }
+        le_advertising_interface_->EnqueueCommand(
+            hci::LeSetAdvertisingDataBuilder::Create(config.advertisement),
+            common::BindOnce(impl::check_status<LeSetAdvertisingDataCompleteView>), module_handler_);
+        le_advertising_interface_->EnqueueCommand(
+            hci::LeSetAdvertisingEnableBuilder::Create(Enable::ENABLED),
+            common::BindOnce(impl::check_status<LeSetAdvertisingEnableCompleteView>), module_handler_);
+        break;
+      case (AdvertisingApiType::ANDROID_HCI):
+        le_advertising_interface_->EnqueueCommand(
+            hci::LeMultiAdvtParamBuilder::Create(config.interval_min, config.interval_max, config.event_type,
+                                                 config.address_type, config.peer_address_type, config.peer_address,
+                                                 config.channel_map, config.filter_policy, id, config.tx_power),
+            common::BindOnce(impl::check_status<LeMultiAdvtCompleteView>), module_handler_);
+        le_advertising_interface_->EnqueueCommand(hci::LeMultiAdvtSetDataBuilder::Create(config.advertisement, id),
+                                                  common::BindOnce(impl::check_status<LeMultiAdvtCompleteView>),
+                                                  module_handler_);
+        if (!config.scan_response.empty()) {
+          le_advertising_interface_->EnqueueCommand(
+              hci::LeMultiAdvtSetScanRespBuilder::Create(config.scan_response, id),
+              common::BindOnce(impl::check_status<LeMultiAdvtCompleteView>), module_handler_);
+        }
+        le_advertising_interface_->EnqueueCommand(
+            hci::LeMultiAdvtSetRandomAddrBuilder::Create(config.random_address, id),
+            common::BindOnce(impl::check_status<LeMultiAdvtCompleteView>), module_handler_);
+        le_advertising_interface_->EnqueueCommand(hci::LeMultiAdvtSetEnableBuilder::Create(Enable::ENABLED, id),
+                                                  common::BindOnce(impl::check_status<LeMultiAdvtCompleteView>),
+                                                  module_handler_);
+        break;
+      case (AdvertisingApiType::LE_5_0): {
+        ExtendedAdvertisingConfig new_config;
+        AdvertisingConfig* base_config_ptr = &new_config;
+        *(base_config_ptr) = config;
+        create_extended_advertiser(id, new_config, scan_callback, set_terminated_callback, handler);
+      } break;
     }
-    le_advertising_interface_->EnqueueCommand(
-        hci::LeMultiAdvtParamBuilder::Create(config.interval_min, config.interval_max, config.event_type,
-                                             config.address_type, config.peer_address_type, config.peer_address,
-                                             config.channel_map, config.filter_policy, id, config.tx_power),
-        common::BindOnce(impl::check_enable_status), module_handler_);
-    le_advertising_interface_->EnqueueCommand(hci::LeSetAdvertisingEnableBuilder::Create(Enable::ENABLED),
-                                              common::BindOnce(impl::check_enable_status), module_handler_);
   }
 
   void create_extended_advertiser(AdvertiserId id, const ExtendedAdvertisingConfig& config,
                                   const common::Callback<void(Address, AddressType)>& scan_callback,
                                   const common::Callback<void(ErrorCode, uint8_t, uint8_t)>& set_terminated_callback,
                                   os::Handler* handler) {
-    if (!controller_->IsSupported(hci::OpCode::LE_SET_EXTENDED_ADVERTISING_PARAMETERS)) {
+    if (advertising_api_type_ != AdvertisingApiType::LE_5_0) {
       create_advertiser(id, config, scan_callback, set_terminated_callback, handler);
       return;
-    } else {
-      LOG_ALWAYS_FATAL("LE_SET_EXTENDED_ADVERTISING_PARAMETERS isn't implemented.");
     }
+    LOG_ALWAYS_FATAL("LE_SET_EXTENDED_ADVERTISING_PARAMETERS isn't implemented.");
 
     /*
     le_advertising_interface_->EnqueueCommand(hci::LeSetExtendedAdvertisingParametersBuilder::Create(config.interval_min,
     config.interval_max, config.event_type, config.address_type, config.peer_address_type, config.peer_address,
-    config.channel_map, config.filter_policy, id, config.tx_power), common::BindOnce(impl::check_enable_status),
+    config.channel_map, config.filter_policy, id, config.tx_power), common::BindOnce(impl::check_status),
     module_handler_);
      */
     advertising_sets_[id].scan_callback = scan_callback;
@@ -167,14 +205,15 @@ struct LeAdvertisingManager::impl {
       return;
     }
     le_advertising_interface_->EnqueueCommand(hci::LeSetAdvertisingEnableBuilder::Create(Enable::DISABLED),
-                                              common::BindOnce(impl::check_enable_status), module_handler_);
+                                              common::BindOnce(impl::check_status<LeSetAdvertisingEnableCompleteView>),
+                                              module_handler_);
     std::unique_lock lock(id_mutex_);
     advertising_sets_.erase(advertising_set);
   }
 
   common::Callback<void(Address, AddressType)> scan_callback_;
   common::Callback<void(ErrorCode, uint8_t, uint8_t)> set_terminated_callback_;
-  os::Handler* registered_handler_;
+  os::Handler* registered_handler_{nullptr};
   Module* module_;
   os::Handler* module_handler_;
   hci::HciLayer* hci_layer_;
@@ -185,21 +224,21 @@ struct LeAdvertisingManager::impl {
   std::mutex id_mutex_;
   size_t num_instances_;
 
-  static void check_enable_status(CommandCompleteView view) {
+  AdvertisingApiType advertising_api_type_{0};
+
+  template <class View>
+  static void check_status(CommandCompleteView view) {
     ASSERT(view.IsValid());
-    auto status_view = LeSetAdvertisingEnableCompleteView::Create(view);
+    auto status_view = View::Create(view);
     ASSERT(status_view.IsValid());
     if (status_view.GetStatus() != ErrorCode::SUCCESS) {
       LOG_INFO("SetEnable returned status %s", ErrorCodeText(status_view.GetStatus()).c_str());
-      return;
     }
   }
 };
 
-const AdvertiserId LeAdvertisingManager::kInvalidId = -1;
-
 LeAdvertisingManager::LeAdvertisingManager() {
-  pimpl_ = std::make_unique<impl>(this, GetHandler(), GetDependency<hci::HciLayer>(), GetDependency<hci::Controller>());
+  pimpl_ = std::make_unique<impl>(this);
 }
 
 void LeAdvertisingManager::ListDependencies(ModuleList* list) {
@@ -208,7 +247,7 @@ void LeAdvertisingManager::ListDependencies(ModuleList* list) {
 }
 
 void LeAdvertisingManager::Start() {
-  pimpl_->start();
+  pimpl_->start(GetHandler(), GetDependency<hci::HciLayer>(), GetDependency<hci::Controller>());
 }
 
 void LeAdvertisingManager::Stop() {
@@ -225,10 +264,12 @@ AdvertiserId LeAdvertisingManager::CreateAdvertiser(
   if (config.peer_address == Address::kEmpty) {
     if (config.address_type == hci::AddressType::PUBLIC_IDENTITY_ADDRESS ||
         config.address_type == hci::AddressType::RANDOM_IDENTITY_ADDRESS) {
+      LOG_WARN("Peer address can not be empty");
       return kInvalidId;
     }
     if (config.event_type == hci::AdvertisingEventType::ADV_DIRECT_IND ||
         config.event_type == hci::AdvertisingEventType::ADV_DIRECT_IND_LOW) {
+      LOG_WARN("Peer address can not be empty for directed advertising");
       return kInvalidId;
     }
   }
@@ -244,11 +285,34 @@ AdvertiserId LeAdvertisingManager::CreateAdvertiser(
 AdvertiserId LeAdvertisingManager::CreateAdvertiser(
     const ExtendedAdvertisingConfig& config, const common::Callback<void(Address, AddressType)>& scan_callback,
     const common::Callback<void(ErrorCode, uint8_t, uint8_t)>& set_terminated_callback, os::Handler* handler) {
+  if (config.directed) {
+    if (config.peer_address == Address::kEmpty) {
+      LOG_INFO("Peer address can not be empty for directed advertising");
+      return kInvalidId;
+    }
+  }
+  if (config.channel_map == 0) {
+    LOG_INFO("At least one channel must be set in the map");
+    return kInvalidId;
+  }
+  if (!config.legacy_pdus) {
+    if (config.connectable && config.scannable) {
+      LOG_INFO("Extended advertising PDUs can not be connectable and scannable");
+      return kInvalidId;
+    }
+    if (config.high_duty_directed_connectable) {
+      LOG_INFO("Extended advertising PDUs can not be high duty cycle");
+      return kInvalidId;
+    }
+  }
+  if (config.interval_min > config.interval_max) {
+    LOG_INFO("Advertising interval: min (%hu) > max (%hu)", config.interval_min, config.interval_max);
+    return kInvalidId;
+  }
   AdvertiserId id = pimpl_->allocate_advertiser();
   if (id == kInvalidId) {
     return id;
   }
-  // Add error checking here
   GetHandler()->Post(common::BindOnce(&impl::create_extended_advertiser, common::Unretained(pimpl_.get()), id, config,
                                       scan_callback, set_terminated_callback, handler));
   return id;
index 90199e6..2cbfc59 100644 (file)
@@ -59,7 +59,7 @@ using AdvertiserId = int32_t;
 
 class LeAdvertisingManager : public bluetooth::Module {
  public:
-  static const AdvertiserId kInvalidId;
+  static constexpr AdvertiserId kInvalidId = -1;
   LeAdvertisingManager();
 
   size_t GetNumberOfAdvertisingInstances() const;
diff --git a/gd/hci/le_advertising_manager_test.cc b/gd/hci/le_advertising_manager_test.cc
new file mode 100644 (file)
index 0000000..c4f40ad
--- /dev/null
@@ -0,0 +1,356 @@
+/*
+ * 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 "hci/le_advertising_manager.h"
+
+#include <algorithm>
+#include <chrono>
+#include <future>
+#include <map>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "common/bind.h"
+#include "hci/address.h"
+#include "hci/controller.h"
+#include "hci/hci_layer.h"
+#include "os/thread.h"
+#include "packet/raw_builder.h"
+
+namespace bluetooth {
+namespace hci {
+namespace {
+
+using packet::kLittleEndian;
+using packet::PacketView;
+using packet::RawBuilder;
+
+PacketView<kLittleEndian> GetPacketView(std::unique_ptr<packet::BasePacketBuilder> packet) {
+  auto bytes = std::make_shared<std::vector<uint8_t>>();
+  BitInserter i(*bytes);
+  bytes->reserve(packet->size());
+  packet->Serialize(i);
+  return packet::PacketView<packet::kLittleEndian>(bytes);
+}
+
+class TestController : public Controller {
+ public:
+  bool IsSupported(OpCode op_code) const override {
+    return supported_opcodes_.count(op_code) == 1;
+  }
+
+  void AddSupported(OpCode op_code) {
+    supported_opcodes_.insert(op_code);
+  }
+
+  uint16_t GetControllerLeNumberOfSupportedAdverisingSets() const override {
+    return num_advertisers;
+  }
+
+  uint16_t num_advertisers{0};
+
+ protected:
+  void Start() override {}
+  void Stop() override {}
+  void ListDependencies(ModuleList* list) override {}
+
+ private:
+  std::set<OpCode> supported_opcodes_{};
+};
+
+class TestHciLayer : public HciLayer {
+ public:
+  TestHciLayer() {
+    RegisterEventHandler(EventCode::COMMAND_COMPLETE,
+                         base::Bind(&TestHciLayer::CommandCompleteCallback, common::Unretained(this)), nullptr);
+    RegisterEventHandler(EventCode::COMMAND_STATUS,
+                         base::Bind(&TestHciLayer::CommandStatusCallback, common::Unretained(this)), nullptr);
+  }
+
+  void EnqueueCommand(std::unique_ptr<CommandPacketBuilder> command,
+                      common::OnceCallback<void(CommandStatusView)> on_status, os::Handler* handler) override {
+    command_queue_.push_back(std::move(command));
+    command_status_callbacks.push_back(std::move(on_status));
+    if (command_promise_ != nullptr) {
+      command_promise_->set_value(command_queue_.size());
+      command_promise_.reset();
+    }
+  }
+
+  void EnqueueCommand(std::unique_ptr<CommandPacketBuilder> command,
+                      common::OnceCallback<void(CommandCompleteView)> on_complete, os::Handler* handler) override {
+    command_queue_.push_back(std::move(command));
+    command_complete_callbacks.push_back(std::move(on_complete));
+    if (command_promise_ != nullptr) {
+      command_promise_->set_value(command_queue_.size());
+      command_promise_.reset();
+    }
+  }
+
+  std::future<size_t> GetCommandFuture() {
+    ASSERT_LOG(command_promise_ == nullptr, "Promises promises ... Only one at a time");
+    command_promise_ = std::make_unique<std::promise<size_t>>();
+    return command_promise_->get_future();
+  }
+
+  std::unique_ptr<CommandPacketBuilder> GetLastCommand() {
+    ASSERT(!command_queue_.empty());
+    auto last = std::move(command_queue_.front());
+    command_queue_.pop_front();
+    return last;
+  }
+
+  ConnectionManagementCommandView GetCommandPacket(OpCode op_code) {
+    auto packet_view = GetPacketView(GetLastCommand());
+    CommandPacketView command_packet_view = CommandPacketView::Create(packet_view);
+    ConnectionManagementCommandView command = ConnectionManagementCommandView::Create(command_packet_view);
+    ASSERT(command.IsValid());
+    EXPECT_EQ(command.GetOpCode(), op_code);
+
+    return command;
+  }
+
+  void RegisterEventHandler(EventCode event_code, common::Callback<void(EventPacketView)> event_handler,
+                            os::Handler* handler) override {
+    registered_events_[event_code] = event_handler;
+  }
+
+  void RegisterLeEventHandler(SubeventCode subevent_code, common::Callback<void(LeMetaEventView)> event_handler,
+                              os::Handler* handler) override {
+    registered_le_events_[subevent_code] = event_handler;
+  }
+
+  void IncomingEvent(std::unique_ptr<EventPacketBuilder> event_builder) {
+    auto packet = GetPacketView(std::move(event_builder));
+    EventPacketView event = EventPacketView::Create(packet);
+    ASSERT_TRUE(event.IsValid());
+    EventCode event_code = event.GetEventCode();
+    ASSERT_TRUE(registered_events_.find(event_code) != registered_events_.end()) << EventCodeText(event_code);
+    registered_events_[event_code].Run(event);
+  }
+
+  void IncomingLeMetaEvent(std::unique_ptr<LeMetaEventBuilder> event_builder) {
+    auto packet = GetPacketView(std::move(event_builder));
+    EventPacketView event = EventPacketView::Create(packet);
+    LeMetaEventView meta_event_view = LeMetaEventView::Create(event);
+    ASSERT_TRUE(meta_event_view.IsValid());
+    SubeventCode subevent_code = meta_event_view.GetSubeventCode();
+    ASSERT_TRUE(registered_le_events_.find(subevent_code) != registered_le_events_.end())
+        << SubeventCodeText(subevent_code);
+    registered_le_events_[subevent_code].Run(meta_event_view);
+  }
+
+  void CommandCompleteCallback(EventPacketView event) {
+    CommandCompleteView complete_view = CommandCompleteView::Create(event);
+    ASSERT(complete_view.IsValid());
+    std::move(command_complete_callbacks.front()).Run(complete_view);
+    command_complete_callbacks.pop_front();
+  }
+
+  void CommandStatusCallback(EventPacketView event) {
+    CommandStatusView status_view = CommandStatusView::Create(event);
+    ASSERT(status_view.IsValid());
+    std::move(command_status_callbacks.front()).Run(status_view);
+    command_status_callbacks.pop_front();
+  }
+
+  void ListDependencies(ModuleList* list) override {}
+  void Start() override {}
+  void Stop() override {}
+
+ private:
+  std::map<EventCode, common::Callback<void(EventPacketView)>> registered_events_;
+  std::map<SubeventCode, common::Callback<void(LeMetaEventView)>> registered_le_events_;
+  std::list<base::OnceCallback<void(CommandCompleteView)>> command_complete_callbacks;
+  std::list<base::OnceCallback<void(CommandStatusView)>> command_status_callbacks;
+
+  std::list<std::unique_ptr<CommandPacketBuilder>> command_queue_;
+  mutable std::mutex mutex_;
+  std::unique_ptr<std::promise<size_t>> command_promise_{};
+};
+
+class LeAdvertisingManagerTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    test_hci_layer_ = new TestHciLayer;  // Ownership is transferred to registry
+    test_controller_ = new TestController;
+    test_controller_->AddSupported(param_opcode_);
+    fake_registry_.InjectTestModule(&HciLayer::Factory, test_hci_layer_);
+    fake_registry_.InjectTestModule(&Controller::Factory, test_controller_);
+    client_handler_ = fake_registry_.GetTestModuleHandler(&HciLayer::Factory);
+    ASSERT_NE(client_handler_, nullptr);
+    test_controller_->num_advertisers = 1;
+    fake_registry_.Start<LeAdvertisingManager>(&thread_);
+    le_advertising_manager_ =
+        static_cast<LeAdvertisingManager*>(fake_registry_.GetModuleUnderTest(&LeAdvertisingManager::Factory));
+  }
+
+  void TearDown() override {
+    fake_registry_.SynchronizeModuleHandler(&LeAdvertisingManager::Factory, std::chrono::milliseconds(20));
+    fake_registry_.StopAll();
+  }
+
+  TestModuleRegistry fake_registry_;
+  TestHciLayer* test_hci_layer_ = nullptr;
+  TestController* test_controller_ = nullptr;
+  os::Thread& thread_ = fake_registry_.GetTestThread();
+  LeAdvertisingManager* le_advertising_manager_ = nullptr;
+  os::Handler* client_handler_ = nullptr;
+
+  const common::Callback<void(Address, AddressType)> scan_callback =
+      common::Bind(&LeAdvertisingManagerTest::on_scan, common::Unretained(this));
+  const common::Callback<void(ErrorCode, uint8_t, uint8_t)> set_terminated_callback =
+      common::Bind(&LeAdvertisingManagerTest::on_set_terminated, common::Unretained(this));
+
+  std::future<Address> GetOnScanPromise() {
+    ASSERT_LOG(address_promise_ == nullptr, "Promises promises ... Only one at a time");
+    address_promise_ = std::make_unique<std::promise<Address>>();
+    return address_promise_->get_future();
+  }
+  void on_scan(Address address, AddressType address_type) {
+    if (address_promise_ == nullptr) {
+      return;
+    }
+    address_promise_->set_value(address);
+    address_promise_.reset();
+  }
+
+  std::future<ErrorCode> GetSetTerminatedPromise() {
+    ASSERT_LOG(set_terminated_promise_ == nullptr, "Promises promises ... Only one at a time");
+    set_terminated_promise_ = std::make_unique<std::promise<ErrorCode>>();
+    return set_terminated_promise_->get_future();
+  }
+  void on_set_terminated(ErrorCode error_code, uint8_t, uint8_t) {
+    if (set_terminated_promise_ != nullptr) {
+      return;
+    }
+    set_terminated_promise_->set_value(error_code);
+    set_terminated_promise_.reset();
+  }
+
+  std::unique_ptr<std::promise<Address>> address_promise_{};
+  std::unique_ptr<std::promise<ErrorCode>> set_terminated_promise_{};
+
+  OpCode param_opcode_{OpCode::LE_SET_ADVERTISING_PARAMETERS};
+};
+
+class LeAndroidHciAdvertisingManagerTest : public LeAdvertisingManagerTest {
+ protected:
+  void SetUp() override {
+    param_opcode_ = OpCode::LE_MULTI_ADVT;
+    LeAdvertisingManagerTest::SetUp();
+    test_controller_->num_advertisers = 3;
+  }
+};
+
+class LeExtendedAdvertisingManagerTest : public LeAdvertisingManagerTest {
+ protected:
+  void SetUp() override {
+    param_opcode_ = OpCode::LE_SET_EXTENDED_ADVERTISING_PARAMETERS;
+    LeAdvertisingManagerTest::SetUp();
+    test_controller_->num_advertisers = 5;
+  }
+};
+
+TEST_F(LeAdvertisingManagerTest, startup_teardown) {}
+
+TEST_F(LeAndroidHciAdvertisingManagerTest, startup_teardown) {}
+
+TEST_F(LeExtendedAdvertisingManagerTest, startup_teardown) {}
+
+TEST_F(LeAdvertisingManagerTest, create_advertiser_test) {
+  AdvertisingConfig advertising_config{};
+  advertising_config.event_type = AdvertisingEventType::ADV_IND;
+  advertising_config.address_type = AddressType::PUBLIC_DEVICE_ADDRESS;
+  std::vector<GapData> gap_data{};
+  GapData data_item{};
+  data_item.data_type_ = GapDataType::FLAGS;
+  data_item.data_ = {0x34};
+  gap_data.push_back(data_item);
+  data_item.data_type_ = GapDataType::COMPLETE_LOCAL_NAME;
+  data_item.data_ = {'r', 'a', 'n', 'd', 'o', 'm', ' ', 'd', 'e', 'v', 'i', 'c', 'e'};
+  gap_data.push_back(data_item);
+  advertising_config.advertisement = gap_data;
+  advertising_config.scan_response = gap_data;
+
+  auto next_command_future = test_hci_layer_->GetCommandFuture();
+  auto id = le_advertising_manager_->CreateAdvertiser(advertising_config, scan_callback, set_terminated_callback,
+                                                      client_handler_);
+  ASSERT_NE(LeAdvertisingManager::kInvalidId, id);
+  std::vector<OpCode> adv_opcodes = {
+      OpCode::LE_SET_ADVERTISING_PARAMETERS, OpCode::LE_SET_RANDOM_ADDRESS,     OpCode::LE_SET_SCAN_RESPONSE_DATA,
+      OpCode::LE_SET_ADVERTISING_DATA,       OpCode::LE_SET_ADVERTISING_ENABLE,
+  };
+  auto result = next_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
+  ASSERT_NE(std::future_status::timeout, result);
+  size_t num_commands = next_command_future.get();
+  for (size_t i = 0; i < adv_opcodes.size(); i++) {
+    auto packet = test_hci_layer_->GetCommandPacket(adv_opcodes[i]);
+    std::vector<uint8_t> success_vector{static_cast<uint8_t>(ErrorCode::SUCCESS)};
+    test_hci_layer_->IncomingEvent(
+        CommandCompleteBuilder::Create(uint8_t{1}, adv_opcodes[i], std::make_unique<RawBuilder>(success_vector)));
+    if (i < adv_opcodes.size() - 1 && --num_commands == 1) {
+      next_command_future = test_hci_layer_->GetCommandFuture();
+      result = next_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
+      ASSERT_NE(std::future_status::timeout, result);
+      num_commands = next_command_future.get();
+    }
+  }
+}
+
+TEST_F(LeAndroidHciAdvertisingManagerTest, create_advertiser_test) {
+  AdvertisingConfig advertising_config{};
+  advertising_config.event_type = AdvertisingEventType::ADV_IND;
+  advertising_config.address_type = AddressType::PUBLIC_DEVICE_ADDRESS;
+  std::vector<GapData> gap_data{};
+  GapData data_item{};
+  data_item.data_type_ = GapDataType::FLAGS;
+  data_item.data_ = {0x34};
+  gap_data.push_back(data_item);
+  data_item.data_type_ = GapDataType::COMPLETE_LOCAL_NAME;
+  data_item.data_ = {'r', 'a', 'n', 'd', 'o', 'm', ' ', 'd', 'e', 'v', 'i', 'c', 'e'};
+  gap_data.push_back(data_item);
+  advertising_config.advertisement = gap_data;
+  advertising_config.scan_response = gap_data;
+
+  auto next_command_future = test_hci_layer_->GetCommandFuture();
+  auto id = le_advertising_manager_->CreateAdvertiser(advertising_config, scan_callback, set_terminated_callback,
+                                                      client_handler_);
+  ASSERT_NE(LeAdvertisingManager::kInvalidId, id);
+  std::vector<SubOcf> sub_ocf = {
+      SubOcf::SET_PARAM, SubOcf::SET_DATA, SubOcf::SET_SCAN_RESP, SubOcf::SET_RANDOM_ADDR, SubOcf::SET_ENABLE,
+  };
+  auto result = next_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
+  ASSERT_NE(std::future_status::timeout, result);
+  size_t num_commands = next_command_future.get();
+  for (size_t i = 0; i < sub_ocf.size(); i++) {
+    auto packet = test_hci_layer_->GetCommandPacket(OpCode::LE_MULTI_ADVT);
+    std::vector<uint8_t> success_vector{static_cast<uint8_t>(ErrorCode::SUCCESS), static_cast<uint8_t>(sub_ocf[i])};
+    test_hci_layer_->IncomingEvent(CommandCompleteBuilder::Create(uint8_t{1}, OpCode::LE_MULTI_ADVT,
+                                                                  std::make_unique<RawBuilder>(success_vector)));
+    if (i < sub_ocf.size() - 1 && --num_commands == 1) {
+      next_command_future = test_hci_layer_->GetCommandFuture();
+      result = next_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
+      ASSERT_NE(std::future_status::timeout, result);
+      num_commands = next_command_future.get();
+    }
+  }
+}
+
+}  // namespace
+}  // namespace hci
+}  // namespace bluetooth