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

Commit 58eed36e authored by Jack He's avatar Jack He
Browse files

L2CAP: Call AclConnection.RegisterDisconnectCallback() in LinkManager

* LinkManager should get ACL disconnection callback from HCI since it
  needs to be able to free Link objects after tearing down Link states
* Previously, only Link is getting this callback, as result, there is a
  memory leak when ACL is disconnected as the Link object was never
  removed

Test: bluetooth_test_gd
Bug: 140938432
Change-Id: I28ed509cbaaa1c4917e1f632a6c35247f3ebe2ef
parent b54aa76d
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -43,8 +43,6 @@ Link::Link(os::Handler* l2cap_handler, std::unique_ptr<hci::AclConnection> acl_c
  ASSERT(acl_connection_ != nullptr);
  ASSERT(scheduler_ != nullptr);
  ASSERT(parameter_provider_ != nullptr);
  acl_connection_->RegisterDisconnectCallback(common::BindOnce(&Link::OnAclDisconnected, common::Unretained(this)),
                                              l2cap_handler_);
  link_idle_disconnect_alarm_.Schedule(common::BindOnce(&Link::Disconnect, common::Unretained(this)),
                                       parameter_provider_->GetClassicLinkIdleDisconnectTimeout());
}
+3 −0
Original line number Diff line number Diff line
@@ -104,6 +104,9 @@ void LinkManager::OnConnectSuccess(std::unique_ptr<hci::AclConnection> acl_conne
  hci::Address device = acl_connection->GetAddress();
  ASSERT_LOG(GetLink(device) == nullptr, "%s is connected twice without disconnection",
             acl_connection->GetAddress().ToString().c_str());
  // Register ACL disconnection callback in LinkManager so that we can clean up link resource properly
  acl_connection->RegisterDisconnectCallback(
      common::BindOnce(&LinkManager::OnDisconnect, common::Unretained(this), device), l2cap_handler_);
  auto* link_queue_up_end = acl_connection->GetAclQueueEnd();
  links_.try_emplace(device, l2cap_handler_, std::move(acl_connection),
                     std::make_unique<l2cap::internal::Fifo>(link_queue_up_end, l2cap_handler_), parameter_provider_,
+1 −0
Original line number Diff line number Diff line
@@ -121,6 +121,7 @@ TEST_F(L2capClassicLinkManagerTest, connect_fixed_channel_service_without_acl) {
  std::unique_ptr<MockAclConnection> acl_connection = std::make_unique<MockAclConnection>();
  hci::AclConnection::Queue link_queue{10};
  EXPECT_CALL(*acl_connection, GetAclQueueEnd()).WillRepeatedly((Return(link_queue.GetUpEnd())));
  EXPECT_CALL(*acl_connection, RegisterDisconnectCallback(_, l2cap_handler_)).Times(1);
  EXPECT_CALL(*acl_connection, GetAddress()).WillRepeatedly(Return(device));
  std::unique_ptr<FixedChannel> channel_1, channel_2;
  EXPECT_CALL(mock_service_1, NotifyChannelCreation(_)).WillOnce([&channel_1](std::unique_ptr<FixedChannel> channel) {
+0 −2
Original line number Diff line number Diff line
@@ -41,8 +41,6 @@ class Link {
    ASSERT(acl_connection_ != nullptr);
    ASSERT(scheduler_ != nullptr);
    ASSERT(parameter_provider_ != nullptr);
    acl_connection_->RegisterDisconnectCallback(common::BindOnce(&Link::OnAclDisconnected, common::Unretained(this)),
                                                l2cap_handler_);
    link_idle_disconnect_alarm_.Schedule(common::BindOnce(&Link::Disconnect, common::Unretained(this)),
                                         parameter_provider_->GetLeLinkIdleDisconnectTimeout());
  }
+4 −0
Original line number Diff line number Diff line
@@ -96,6 +96,10 @@ void LinkManager::OnLeConnectSuccess(hci::AddressWithType connecting_address_wit
  ASSERT_LOG(GetLink(connected_address_with_type) == nullptr, "%s is connected twice without disconnection",
             acl_connection->GetAddress().ToString().c_str());
  auto* link_queue_up_end = acl_connection->GetAclQueueEnd();
  // Register ACL disconnection callback in LinkManager so that we can clean up link resource properly
  acl_connection->RegisterDisconnectCallback(
      common::BindOnce(&LinkManager::OnDisconnect, common::Unretained(this), connected_address_with_type),
      l2cap_handler_);
  links_.try_emplace(connected_address_with_type, l2cap_handler_, std::move(acl_connection),
                     std::make_unique<l2cap::internal::Fifo>(link_queue_up_end, l2cap_handler_), parameter_provider_);
  auto* link = GetLink(connected_address_with_type);
Loading