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

Commit 5dd87419 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "le_audio: Activate ASEs only configured for active context" into tm-d1-dev am: 17c4b9e0

parents d74b5e74 17c4b9e0
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -152,11 +152,11 @@ void LeAudioDeviceGroup::Deactivate(void) {
  }
}

void LeAudioDeviceGroup::Activate(void) {
void LeAudioDeviceGroup::Activate(LeAudioContextType context_type) {
  for (auto leAudioDevice : leAudioDevices_) {
    if (leAudioDevice.expired()) continue;

    leAudioDevice.lock()->ActivateConfiguredAses();
    leAudioDevice.lock()->ActivateConfiguredAses(context_type);
  }
}

@@ -1023,6 +1023,7 @@ bool LeAudioDevice::ConfigureAses(

  for (; needed_ase && ase; needed_ase--) {
    ase->active = true;
    ase->configured_for_context_type = context_type;
    active_ases++;

    if (ase->state == AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED)
@@ -1779,7 +1780,7 @@ AudioContexts LeAudioDevice::SetAvailableContexts(AudioContexts snk_contexts,
  return updated_contexts;
}

void LeAudioDevice::ActivateConfiguredAses(void) {
void LeAudioDevice::ActivateConfiguredAses(LeAudioContextType context_type) {
  if (conn_id_ == GATT_INVALID_CONN_ID) {
    LOG_DEBUG(" Device %s is not connected ", address_.ToString().c_str());
    return;
@@ -1788,7 +1789,8 @@ void LeAudioDevice::ActivateConfiguredAses(void) {
  LOG_DEBUG(" Configuring device %s", address_.ToString().c_str());
  for (auto& ase : ases_) {
    if (!ase.active &&
        ase.state == AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED) {
        ase.state == AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED &&
        ase.configured_for_context_type == context_type) {
      LOG_DEBUG(" Ase id %d, cis id %d activated.", ase.id, ase.cis_id);
      ase.active = true;
    }
+2 −2
Original line number Diff line number Diff line
@@ -143,7 +143,7 @@ class LeAudioDevice {
  types::AudioContexts SetAvailableContexts(types::AudioContexts snk_cont_val,
                                            types::AudioContexts src_cont_val);
  void DeactivateAllAses(void);
  void ActivateConfiguredAses(void);
  void ActivateConfiguredAses(types::LeAudioContextType context_type);
  void Dump(int fd);
  void DisconnectAcl(void);
  std::vector<uint8_t> GetMetadata(types::LeAudioContextType context_type,
@@ -217,7 +217,7 @@ class LeAudioDeviceGroup {
  int Size(void);
  int NumOfConnected(
      types::LeAudioContextType context_type = types::LeAudioContextType::RFU);
  void Activate(void);
  void Activate(types::LeAudioContextType context_type);
  void Deactivate(void);
  void Cleanup(void);
  LeAudioDevice* GetFirstDevice(void);
+2 −0
Original line number Diff line number Diff line
@@ -529,6 +529,7 @@ struct ase {
        active(false),
        reconfigure(false),
        data_path_state(AudioStreamDataPathState::IDLE),
        configured_for_context_type(LeAudioContextType::UNINITIALIZED),
        preferred_phy(0),
        state(AseState::BTA_LE_AUDIO_ASE_STATE_IDLE) {}

@@ -542,6 +543,7 @@ struct ase {
  bool active;
  bool reconfigure;
  AudioStreamDataPathState data_path_state;
  LeAudioContextType configured_for_context_type;

  /* Codec configuration */
  LeAudioCodecId codec_id;
+3 −1
Original line number Diff line number Diff line
@@ -153,7 +153,7 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine {
    switch (group->GetState()) {
      case AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED:
        if (group->GetCurrentContextType() == context_type) {
          group->Activate();
          group->Activate(context_type);
          SetTargetState(group, AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
          CigCreate(group);
          return true;
@@ -1129,6 +1129,8 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine {
        LeAudioDevice* leAudioDeviceNext;
        ase->state = AseState::BTA_LE_AUDIO_ASE_STATE_IDLE;
        ase->active = false;
        ase->configured_for_context_type =
            le_audio::types::LeAudioContextType::UNINITIALIZED;

        if (!leAudioDevice->HaveAllActiveAsesSameState(
                AseState::BTA_LE_AUDIO_ASE_STATE_IDLE)) {
+99 −7
Original line number Diff line number Diff line
@@ -644,6 +644,7 @@ class StateMachineTest : public Test {

  void MultipleTestDevicePrepare(int leaudio_group_id, uint16_t context_type,
                                 uint16_t device_cnt,
                                 uint16_t update_context_type,
                                 bool insert_default_pac_records = true) {
    // Prepare fake connected device group
    bool first_connections = true;
@@ -680,8 +681,10 @@ class StateMachineTest : public Test {
        uint16_t attr_handle = ATTR_HANDLE_PACS_POOL_START;

        /* As per spec, unspecified shall be supported */
        types::AudioContexts snk_context_type = kContextTypeUnspecified;
        types::AudioContexts src_context_type = kContextTypeUnspecified;
        types::AudioContexts snk_context_type =
            kContextTypeUnspecified | update_context_type;
        types::AudioContexts src_context_type =
            kContextTypeUnspecified | update_context_type;

        // Prepare Sink Published Audio Capability records
        if ((context_type & kContextTypeRingtone) ||
@@ -743,17 +746,20 @@ class StateMachineTest : public Test {
    }

    /* Stimulate update of active context map */
    types::AudioContexts type_set = static_cast<uint16_t>(context_type);
    types::AudioContexts type_set = static_cast<uint16_t>(
        update_context_type == 0 ? context_type
                                 : context_type | update_context_type);
    group->UpdateActiveContextsMap(type_set);

    ASSERT_NE(group, nullptr);
    ASSERT_EQ(group->Size(), total_devices);
  }

  LeAudioDeviceGroup* PrepareSingleTestDeviceGroup(int leaudio_group_id,
                                                   uint16_t context_type,
                                                   uint16_t device_cnt = 1) {
    MultipleTestDevicePrepare(leaudio_group_id, context_type, device_cnt);
  LeAudioDeviceGroup* PrepareSingleTestDeviceGroup(
      int leaudio_group_id, uint16_t context_type, uint16_t device_cnt = 1,
      uint16_t update_context_type = 0) {
    MultipleTestDevicePrepare(leaudio_group_id, context_type, device_cnt,
                              update_context_type);
    return le_audio_device_groups_.count(leaudio_group_id)
               ? le_audio_device_groups_[leaudio_group_id].get()
               : nullptr;
@@ -1896,6 +1902,92 @@ TEST_F(StateMachineTest, testStreamCachingSingle) {
            types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
}

TEST_F(StateMachineTest, testActivateStreamCachingSingle) {
  auto context_type = kContextTypeConversational;
  const int leaudio_group_id = 4;

  additional_ases = 2;
  /* Prepare fake connected device group with update of Media and Conversational
   * contexts
   */
  auto* group = PrepareSingleTestDeviceGroup(
      leaudio_group_id, context_type, 1,
      kContextTypeConversational | kContextTypeMedia);

  /* Since we prepared device with Conversational context in mind, only one ASE
   * should have been configured.
   */
  PrepareConfigureCodecHandler(group, 0, true);
  PrepareConfigureQosHandler(group, 0, true);
  PrepareEnableHandler(group);
  PrepareReceiverStartReady(group);
  PrepareReleaseHandler(group);

  /* Ctp messages we expect:
   * 1. Codec Config
   * 2. QoS Config
   * 3. Enable
   * 4. Release
   * 5. QoS Config (because device stays in Configured state)
   * 6. Enable
   */
  auto* leAudioDevice = group->GetFirstDevice();
  EXPECT_CALL(gatt_queue,
              WriteCharacteristic(1, leAudioDevice->ctp_hdls_.val_hdl, _,
                                  GATT_WRITE_NO_RSP, _, _))
      .Times(8);

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

  InjectInitialIdleNotification(group);

  // Validate GroupStreamStatus
  EXPECT_CALL(
      mock_callbacks_,
      StatusReportCb(leaudio_group_id,
                     bluetooth::le_audio::GroupStreamStatus::RELEASING));

  EXPECT_CALL(
      mock_callbacks_,
      StatusReportCb(
          leaudio_group_id,
          bluetooth::le_audio::GroupStreamStatus::CONFIGURED_AUTONOMOUS));

  EXPECT_CALL(mock_callbacks_,
              StatusReportCb(leaudio_group_id,
                             bluetooth::le_audio::GroupStreamStatus::STREAMING))
      .Times(2);

  // Start the configuration and stream Conversational content
  LeAudioGroupStateMachine::Get()->StartStream(
      group, static_cast<types::LeAudioContextType>(context_type));

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

  // Stop the stream
  LeAudioGroupStateMachine::Get()->StopStream(group);

  // Check if group has transitioned to a proper state
  ASSERT_EQ(group->GetState(),
            types::AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED);

  // Start the configuration and stream Media content
  context_type = kContextTypeMedia;
  LeAudioGroupStateMachine::Get()->StartStream(
      group, static_cast<types::LeAudioContextType>(context_type));

  // Check if group has transitioned to a proper state
  ASSERT_EQ(group->GetState(),
            types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
}

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