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

Commit d7096be8 authored by Łukasz Rymanowski's avatar Łukasz Rymanowski Committed by Android Build Coastguard Worker
Browse files

leaudio: Fix data path removal when ACL disconnect event arrives first

Even on the controller side, Disconnect Event for CIS arrives before
Disconnect Event for ACL, it might happen that on the profile layer,
those events will come in different order.
It happens usually when GATT layer decides to notify profile and ACL
disconnection before it actually happens e.g. on GATT response timeout.

Stack already handles removing CIS from the streaming in such a case,
but datapath was not removed.

This patch fixes that.

Bug: 355767463
Flag: Exempt, regression verified with unit tests, new test added
Test: atest bluetooth_le_audio_test
(cherry picked from https://android-review.googlesource.com/q/commit:82525286810e81e7d2fbf1606e83b3abd5616664)
Merged-In: I36e342e8fb246b941e6454c321f19b2bb86a1241
Change-Id: I36e342e8fb246b941e6454c321f19b2bb86a1241
parent 014cc34c
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -766,6 +766,10 @@ public:

    /* It is possible that ACL disconnection came before CIS disconnect event */
    for (auto& ase : leAudioDevice->ases_) {
      if (ase.data_path_state == DataPathState::CONFIGURED ||
          ase.data_path_state == DataPathState::CONFIGURING) {
        RemoveDataPathByCisHandle(leAudioDevice, ase.cis_conn_hdl);
      }
      group->RemoveCisFromStreamIfNeeded(leAudioDevice, ase.cis_conn_hdl);
    }

+55 −0
Original line number Diff line number Diff line
@@ -4701,6 +4701,61 @@ TEST_F(StateMachineTest, testConfigureDataPathForHost) {
           .source = types::AudioContexts(context_type)}));
}

TEST_F(StateMachineTest, testRemoveDataPathWhenSingleBudDisconnectsOnGattTimeout) {
  const auto context_type = kContextTypeConversational;
  const int leaudio_group_id = 4;
  const auto num_devices = 2;
  channel_count_ = kLeAudioCodecChannelCountSingleChannel | kLeAudioCodecChannelCountTwoChannel;

  /* Scenario
   * 1. Two buds are streaming
   * 2. There is a GATT timeout on one of the device which cause disconnection but profile will get
   * fist GATT Close and later CIS Disconnection Timeout
   *
   * 3. Verify that Data Path is removed for the disconnected CIS
   */

  ContentControlIdKeeper::GetInstance()->SetCcid(kContextTypeConversational, call_ccid);

  // Prepare multiple fake connected devices in a group
  auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
  ASSERT_EQ(group->Size(), num_devices);

  /* Since we prepared device with Ringtone context in mind, only one ASE
   * should have been configured.
   */
  PrepareConfigureCodecHandler(group);
  PrepareConfigureQosHandler(group);
  PrepareEnableHandler(group);
  PrepareReceiverStartReadyHandler(group);

  EXPECT_CALL(*mock_iso_manager_,
              SetupIsoDataPath(_, dataPathIsEq(bluetooth::hci::iso_manager::kIsoDataPathHci)))
          .Times(4);

  InjectInitialIdleNotification(group);

  // Start the configuration and stream Media content
  ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
          group, context_type,
          {.sink = types::AudioContexts(context_type),
           .source = types::AudioContexts(context_type)}));

  testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);

  EXPECT_CALL(*mock_iso_manager_,
              RemoveIsoDataPath(
                      _, bluetooth::hci::iso_manager::kRemoveIsoDataPathDirectionOutput |
                                 bluetooth::hci::iso_manager::kRemoveIsoDataPathDirectionInput))
          .Times(1);

  auto device = group->GetFirstDevice();
  InjectAclDisconnected(group, device);
  InjectCisDisconnected(group, device, HCI_ERR_CONN_CAUSE_LOCAL_HOST);

  testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
}

TEST_F(StateMachineTestAdsp, testConfigureDataPathForAdsp) {
  const auto context_type = kContextTypeRingtone;
  const int leaudio_group_id = 4;