Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8a971593 authored by Chris Manton's avatar Chris Manton
Browse files

gd_acl: Ensure acl is running prior to shutdown

Synchronize stack shutdown

Bug: 176960731
Test: bluetooth_test_gd --gtest_filter=AclManagerLifeCycleTest.*
Test: gd/cert/run
Tag: #refactor
BYPASS_LONG_LINES_REASON: Bluetooth likes 120 lines

Change-Id: I8a2a321f9605e26da8ce340badc87e2f7208209d
parent fb838d54
Loading
Loading
Loading
Loading
+42 −1
Original line number Diff line number Diff line
@@ -306,7 +306,7 @@ class ShimAclConnection {

  void Shutdown() {
    Disconnect();
    LOG_INFO("Shutdown ACL connection handle:0x%04x", handle_);
    LOG_INFO("Shutdown and disconnect ACL connection handle:0x%04x", handle_);
  }

 protected:
@@ -703,6 +703,27 @@ struct shim::legacy::Acl::impl {
    promise.set_value();
  }

  void FinalShutdown(std::promise<void> promise) {
    if (!handle_to_classic_connection_map_.empty()) {
      for (auto& connection : handle_to_classic_connection_map_) {
        connection.second->Shutdown();
      }
      handle_to_classic_connection_map_.clear();
      LOG_INFO("Cleared all classic connections count:%zu",
               handle_to_classic_connection_map_.size());
    }

    if (!handle_to_le_connection_map_.empty()) {
      for (auto& connection : handle_to_le_connection_map_) {
        connection.second->Shutdown();
      }
      handle_to_le_connection_map_.clear();
      LOG_INFO("Cleared all le connections count:%zu",
               handle_to_le_connection_map_.size());
    }
    promise.set_value();
  }

  void HoldMode(HciHandle handle, uint16_t max_interval,
                uint16_t min_interval) {
    ASSERT_LOG(IsClassicAcl(handle), "handle %d is not a classic connection",
@@ -1329,6 +1350,26 @@ void shim::legacy::Acl::Shutdown() {
  }
}

void shim::legacy::Acl::FinalShutdown() {
  std::promise<void> promise;
  auto future = promise.get_future();
  GetAclManager()->UnregisterCallbacks(this, std::move(promise));
  future.wait();
  LOG_DEBUG("Unregistered classic callbacks from gd acl manager");

  promise = std::promise<void>();
  future = promise.get_future();
  GetAclManager()->UnregisterLeCallbacks(this, std::move(promise));
  future.wait();
  LOG_DEBUG("Unregistered le callbacks from gd acl manager");

  promise = std::promise<void>();
  future = promise.get_future();
  handler_->CallOn(pimpl_.get(), &Acl::impl::FinalShutdown, std::move(promise));
  future.wait();
  LOG_INFO("Unregistered and cleared any orphaned ACL connections");
}

void shim::legacy::Acl::ClearAcceptList() {
  handler_->CallOn(pimpl_.get(), &Acl::impl::clear_acceptlist);
}
+1 −0
Original line number Diff line number Diff line
@@ -90,6 +90,7 @@ class Acl : public hci::acl_manager::ConnectionCallbacks,
  void DumpConnectionHistory(int fd) const;

  void Shutdown();
  void FinalShutdown();

  void ClearAcceptList();

+7 −2
Original line number Diff line number Diff line
@@ -193,8 +193,13 @@ void Stack::Stop() {
  if (!common::init_flags::gd_core_is_enabled()) {
    bluetooth::shim::hci_on_shutting_down();
  }

  // Make sure gd acl flag is enabled and we started it up
  if (common::init_flags::gd_acl_is_enabled() && acl_ != nullptr) {
    acl_->FinalShutdown();
    delete acl_;
    acl_ = nullptr;
  }

  ASSERT_LOG(is_running_, "%s Gd stack not running", __func__);
  is_running_ = false;