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

Commit 3648eec8 authored by Hansong Zhang's avatar Hansong Zhang
Browse files

AclManager: Unregister ACL Credit during Stop()

If Controller received ACL credit, but the listener (AclManager) is
stopped, it should not post event to the invalid Handler.

Bug: 150003349
Test: bluetooth_test_gd and cert/run_cert_facade_only.sh
Change-Id: Idbae0672897273542a009c8df9fbf9f6f00db298
parent 5f974548
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -225,6 +225,7 @@ struct AclManager::impl {
    hci_layer_->UnregisterEventHandler(EventCode::READ_REMOTE_EXTENDED_FEATURES_COMPLETE);
    hci_queue_end_->UnregisterDequeue();
    unregister_all_connections();
    controller_->UnregisterCompletedAclPacketsCallback();
    acl_connections_.clear();
    hci_queue_end_ = nullptr;
    handler_ = nullptr;
+5 −0
Original line number Diff line number Diff line
@@ -75,6 +75,11 @@ class TestController : public Controller {
    acl_cb_handler_ = handler;
  }

  void UnregisterCompletedAclPacketsCallback() override {
    acl_cb_ = {};
    acl_cb_handler_ = nullptr;
  }

  uint16_t GetControllerAclPacketLength() const override {
    return acl_buffer_length_;
  }
+14 −1
Original line number Diff line number Diff line
@@ -125,7 +125,10 @@ struct Controller::impl {
  }

  void NumberOfCompletedPackets(EventPacketView event) {
    ASSERT(acl_credits_handler_ != nullptr);
    if (acl_credits_handler_ == nullptr) {
      LOG_WARN("Received event when AclManager is not listening");
      return;
    }
    auto complete_view = NumberOfCompletedPacketsView::Create(event);
    ASSERT(complete_view.IsValid());
    for (auto completed_packets : complete_view.GetCompletedPackets()) {
@@ -142,6 +145,12 @@ struct Controller::impl {
    acl_credits_handler_ = handler;
  }

  void UnregisterCompletedAclPacketsCallback() {
    ASSERT(acl_credits_handler_ != nullptr);
    acl_credits_callback_ = {};
    acl_credits_handler_ = nullptr;
  }

  void read_local_name_complete_handler(CommandCompleteView view) {
    auto complete_view = ReadLocalNameCompleteView::Create(view);
    ASSERT(complete_view.IsValid());
@@ -700,6 +709,10 @@ void Controller::RegisterCompletedAclPacketsCallback(Callback<void(uint16_t /* h
  impl_->RegisterCompletedAclPacketsCallback(cb, handler);  // TODO hsz: why here?
}

void Controller::UnregisterCompletedAclPacketsCallback() {
  impl_->UnregisterCompletedAclPacketsCallback();  // TODO hsz: why here?
}

std::string Controller::GetControllerLocalName() const {
  return impl_->local_name_;
}
+2 −0
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@ class Controller : public Module {
  virtual void RegisterCompletedAclPacketsCallback(
      common::Callback<void(uint16_t /* handle */, uint16_t /* num_packets */)> cb, os::Handler* handler);

  virtual void UnregisterCompletedAclPacketsCallback();

  virtual std::string GetControllerLocalName() const;

  virtual LocalVersionInformation GetControllerLocalVersionInformation() const;
+12 −0
Original line number Diff line number Diff line
@@ -460,6 +460,18 @@ TEST_F(ControllerTest, aclCreditCallbacksTest) {
  credits1_set.get_future().wait();
  credits2_set.get_future().wait();
}

TEST_F(ControllerTest, aclCreditCallbackListenerUnregistered) {
  os::Thread thread("test_thread", os::Thread::Priority::NORMAL);
  os::Handler handler(&thread);
  controller_->RegisterCompletedAclPacketsCallback(common::Bind(&CheckReceivedCredits), &handler);

  handler.Clear();
  handler.WaitUntilStopped(std::chrono::milliseconds(100));
  controller_->UnregisterCompletedAclPacketsCallback();

  test_hci_layer_->IncomingCredit();
}
}  // namespace
}  // namespace hci
}  // namespace bluetooth