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

Commit 0aa51297 authored by Łukasz Rymanowski's avatar Łukasz Rymanowski
Browse files

leaudio: Fix attaching late device to the stream

Make sure, the stream state and target state are STREAMING before
attaching device to the stream.
By checking TargetState we are making sure that stream is no in
transition to Idle.

Bug: 287260361
Test: atest  BluetoothInstrumentationTest
Test: manual
Tag: #feature
Change-Id: I53615d194c20cccb183105d9896498a5d0f32b8a
parent 6e2d7ef2
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -146,9 +146,12 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine {
     * Limitation here is that device should be previously in the streaming
     * group and just got reconnected.
     */
    if (group->GetState() != AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
      LOG_ERROR(" group not in the streaming state: %s",
                ToString(group->GetState()).c_str());
    if (group->GetState() != AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING ||
        group->GetTargetState() != AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
      LOG_ERROR(
          " group %d no in correct streaming state: %s or target state: %s",
          group->group_id_, ToString(group->GetState()).c_str(),
          ToString(group->GetTargetState()).c_str());
      return false;
    }

+64 −0
Original line number Diff line number Diff line
@@ -3353,6 +3353,70 @@ TEST_F(StateMachineTest, testAttachDeviceToTheStream) {
  ASSERT_NE(ase->retrans_nb, 0);
}

TEST_F(StateMachineTest, testAttachDeviceToTheStreamDoNotAttach) {
  const auto context_type = kContextTypeMedia;
  const auto leaudio_group_id = 6;
  const auto num_devices = 2;

  ContentControlIdKeeper::GetInstance()->SetCcid(media_context, media_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);

  PrepareConfigureCodecHandler(group);
  PrepareConfigureQosHandler(group);
  PrepareEnableHandler(group);

  auto* leAudioDevice = group->GetFirstDevice();
  LeAudioDevice* lastDevice;

  while (leAudioDevice) {
    lastDevice = leAudioDevice;
    leAudioDevice = group->GetNextDevice(leAudioDevice);
  }

  InjectInitialIdleNotification(group);

  // Inject CIS and ACL disconnection of first device
  InjectCisDisconnected(group, lastDevice, HCI_ERR_CONNECTION_TOUT);
  InjectAclDisconnected(group, lastDevice);

  // Start the configuration and stream Media content
  EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
  EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
  EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(1);
  LeAudioGroupStateMachine::Get()->StartStream(
      group, context_type,
      {.sink = types::AudioContexts(context_type),
       .source = types::AudioContexts(context_type)});

  // Check if group has transitioned to a proper state
  ASSERT_EQ(group->GetState(),
            types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
  testing::Mock::VerifyAndClearExpectations(&mock_iso_manager_);

  // Check if group keeps streaming
  ASSERT_EQ(group->GetState(),
            types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);

  lastDevice->conn_id_ = 3;
  lastDevice->SetConnectionState(DeviceConnectState::CONNECTED);

  group->UpdateAudioContextTypeAvailability();

  EXPECT_CALL(
      mock_callbacks_,
      StatusReportCb(leaudio_group_id,
                     bluetooth::le_audio::GroupStreamStatus::RELEASING));
  LeAudioGroupStateMachine::Get()->StopStream(group);
  testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);

  ASSERT_FALSE(
      LeAudioGroupStateMachine::Get()->AttachToStream(group, lastDevice));
}

TEST_F(StateMachineTest, testReconfigureAfterLateDeviceAttached) {
  const auto context_type = kContextTypeMedia;
  const auto leaudio_group_id = 6;