OSDN Git Service

AclManager: Unregister ACL Credit during Stop()
authorHansong Zhang <hsz@google.com>
Fri, 21 Feb 2020 22:37:46 +0000 (14:37 -0800)
committerHansong Zhang <hsz@google.com>
Fri, 21 Feb 2020 22:48:41 +0000 (14:48 -0800)
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

gd/hci/acl_manager.cc
gd/hci/acl_manager_test.cc
gd/hci/controller.cc
gd/hci/controller.h
gd/hci/controller_test.cc

index 0271854..80439a2 100644 (file)
@@ -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;
index c741d45..1d4e67d 100644 (file)
@@ -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_;
   }
index abb0b5b..fde9ed6 100644 (file)
@@ -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_;
 }
index ba02dcb..6b6a8a4 100644 (file)
@@ -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;
index c77ed7b..1d74b20 100644 (file)
@@ -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