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

Commit 230e3102 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "leaudio: Fix CIG not remove usecase" into main

parents 7302c97d 230c03d7
Loading
Loading
Loading
Loading
+4 −6
Original line number Diff line number Diff line
@@ -2905,12 +2905,8 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine {
    }

    switch (ase->state) {
      case AseState::BTA_LE_AUDIO_ASE_STATE_DISABLING:
      case AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED:
      case AseState::BTA_LE_AUDIO_ASE_STATE_DISABLING: {
        SetAseState(leAudioDevice, ase,
                    AseState::BTA_LE_AUDIO_ASE_STATE_RELEASING);
        break;
      }
      case AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED:
        SetAseState(leAudioDevice, ase,
                    AseState::BTA_LE_AUDIO_ASE_STATE_RELEASING);
@@ -2918,8 +2914,10 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine {
        if (group->HaveAllActiveDevicesAsesTheSameState(
                AseState::BTA_LE_AUDIO_ASE_STATE_RELEASING)) {
          group->SetState(AseState::BTA_LE_AUDIO_ASE_STATE_RELEASING);
        }

          /* At this point all of the active ASEs within group are released. */
        if (group->cig.GetState() == CigState::CREATED &&
            group->HaveAllCisesDisconnected()) {
          RemoveCigForGroup(group);
        }

+68 −3
Original line number Diff line number Diff line
@@ -239,6 +239,13 @@ class StateMachineTestBase : public Test {

    ContentControlIdKeeper::GetInstance()->Start();

    ON_CALL(mock_callbacks_, StatusReportCb(_, _))
        .WillByDefault(Invoke(
            [](int group_id, bluetooth::le_audio::GroupStreamStatus status) {
              LOG_DEBUG(" [Testing] StatusReportCb: group id: %d, status: %d",
                        group_id, status);
            }));

    MockCsisClient::SetMockInstanceForTesting(&mock_csis_client_module_);
    ON_CALL(mock_csis_client_module_, Get())
        .WillByDefault(Return(&mock_csis_client_module_));
@@ -1741,6 +1748,60 @@ TEST_F(StateMachineTest, testConfigureQosMultiple) {
  ASSERT_EQ(0, get_func_call_count("alarm_cancel"));
}

TEST_F(StateMachineTest, testConfigureQosFailed) {
  const auto context_type = kContextTypeMedia;
  const auto leaudio_group_id = 3;
  const auto num_devices = 2;

  // Check if CIG is properly cleared when QoS failed

  // 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);
  PrepareCtpNotificationError(
      group, client_parser::ascs::kCtpOpcodeQosConfiguration,
      client_parser::ascs::kCtpResponseCodeInvalidConfigurationParameterValue,
      client_parser::ascs::kCtpResponsePhy);
  PrepareReleaseHandler(group);

  auto* leAudioDevice = group->GetFirstDevice();
  auto expected_devices_written = 0;
  while (leAudioDevice) {
    EXPECT_CALL(gatt_queue,
                WriteCharacteristic(leAudioDevice->conn_id_,
                                    leAudioDevice->ctp_hdls_.val_hdl, _,
                                    GATT_WRITE_NO_RSP, _, _))
        .Times(AtLeast(2));
    expected_devices_written++;
    leAudioDevice = group->GetNextDevice(leAudioDevice);
  }
  ASSERT_EQ(expected_devices_written, num_devices);

  EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
  EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(0);
  EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(0);
  EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(0);
  EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(0);
  EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(1);

  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)}));

  // Check if group has transitioned to a proper state
  ASSERT_EQ(group->GetState(), types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
  ASSERT_EQ(2, get_func_call_count("alarm_cancel"));

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

TEST_F(StateMachineTest, testStreamCreationError) {
  /* Device is banded headphones with 1x snk + 0x src ase
   * (1xunidirectional CIS) with channel count 2 (for stereo
@@ -5602,19 +5663,23 @@ TEST_F(StateMachineTest, StartStreamCachedConfigReconfigInvalidBehavior) {
  EXPECT_CALL(mock_callbacks_,
              StatusReportCb(leaudio_group_id,
                             bluetooth::le_audio::GroupStreamStatus::RELEASING))
      .Times(1);
      .Times(0);

  EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(0);

  // Block the fallback Release which will happen when CreateCig will faile
  // Block the fallback Release which will happen when CreateCig will fail
  stay_in_releasing_state_ = true;

  // Start the configuration and stream Live content
  LeAudioGroupStateMachine::Get()->StartStream(
  bool result = LeAudioGroupStateMachine::Get()->StartStream(
      group, kContextTypeLive,
      {.sink = types::AudioContexts(kContextTypeLive),
       .source = types::AudioContexts(kContextTypeLive)});

  // Group internally in releasing state. StartStrean should faile.

  ASSERT_FALSE(result);

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