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

Commit 333f2087 authored by Jakub Pawłowski's avatar Jakub Pawłowski Committed by Gerrit Code Review
Browse files

Merge changes I3662cb9e,I43b6377e,I5dbd66e3

* changes:
  LeAudio: Fix audio modes priority
  LeAudio: Fix timing issue on state machine reconfigure
  LeAudio: Reduce number of reconfigurations
parents 8f2c3bc6 a6e429e9
Loading
Loading
Loading
Loading
+39 −2
Original line number Diff line number Diff line
@@ -280,6 +280,19 @@ class LeAudioClientImpl : public LeAudioClient {
      return;
    }

    /* For sonification events we don't really need to reconfigure to HQ
     * configuration, but if the previous configuration was for HQ Media,
     * we might want to go back to that scenario.
     */

    if ((configuration_context_type_ != LeAudioContextType::MEDIA) &&
        (configuration_context_type_ != LeAudioContextType::GAME)) {
      LOG_INFO(
          "Keeping the old configuration as no HQ Media playback is needed "
          "right now.");
      return;
    }

    /* Test the existing metadata against the recent availability */
    metadata_context_types_.sink &= group->GetAvailableContexts();
    if (metadata_context_types_.sink.none()) {
@@ -735,14 +748,15 @@ class LeAudioClientImpl : public LeAudioClient {
          /* Highest priority first */
          LeAudioContextType::CONVERSATIONAL,
          LeAudioContextType::RINGTONE,
          LeAudioContextType::GAME,
          LeAudioContextType::LIVE,
          LeAudioContextType::VOICEASSISTANTS,
          LeAudioContextType::GAME,
          LeAudioContextType::MEDIA,
          LeAudioContextType::EMERGENCYALARM,
          LeAudioContextType::ALERTS,
          LeAudioContextType::INSTRUCTIONAL,
          LeAudioContextType::NOTIFICATIONS,
          LeAudioContextType::SOUNDEFFECTS,
      };
      for (auto ct : context_priority_list) {
        if (metadata_context_type.test(ct)) {
@@ -3506,14 +3520,15 @@ class LeAudioClientImpl : public LeAudioClient {
           * call volume slider while not in a call.
           * LeAudioContextType::RINGTONE,
           */
          LeAudioContextType::GAME,
          LeAudioContextType::LIVE,
          LeAudioContextType::VOICEASSISTANTS,
          LeAudioContextType::GAME,
          LeAudioContextType::MEDIA,
          LeAudioContextType::EMERGENCYALARM,
          LeAudioContextType::ALERTS,
          LeAudioContextType::INSTRUCTIONAL,
          LeAudioContextType::NOTIFICATIONS,
          LeAudioContextType::SOUNDEFFECTS,
      };
      for (auto ct : context_priority_list) {
        if (available_remote_contexts.test(ct)) {
@@ -3666,6 +3681,28 @@ class LeAudioClientImpl : public LeAudioClient {
    auto new_configuration_context =
        ChooseConfigurationContextType(new_metadata_context_types_);

    /* For the following contexts we don't actually need HQ audio:
     * LeAudioContextType::NOTIFICATIONS
     * LeAudioContextType::SOUNDEFFECTS
     * LeAudioContextType::INSTRUCTIONAL
     * LeAudioContextType::ALERTS
     * LeAudioContextType::EMERGENCYALARM
     * So do not reconfigure if the remote sink is already available at any
     * quality and these are the only contributors to the current audio stream.
     */
    auto no_reconfigure_contexts =
        LeAudioContextType::NOTIFICATIONS | LeAudioContextType::SOUNDEFFECTS |
        LeAudioContextType::INSTRUCTIONAL | LeAudioContextType::ALERTS |
        LeAudioContextType::EMERGENCYALARM;
    if ((new_metadata_context_types_ & ~no_reconfigure_contexts).none() &&
        IsDirectionAvailableForCurrentConfiguration(
            group, le_audio::types::kLeAudioDirectionSink)) {
      LOG_INFO(
          "There is no need to reconfigure for the sonification events. Keep "
          "the configuration unchanged.");
      new_configuration_context = configuration_context_type_;
    }

    LOG_DEBUG("new_configuration_context= %s",
              ToString(new_configuration_context).c_str());
    ReconfigureOrUpdateMetadata(group, new_configuration_context,
+17 −9
Original line number Diff line number Diff line
@@ -1478,8 +1478,18 @@ bool LeAudioDevice::ConfigureAses(
    types::AudioLocations& group_src_audio_locations, bool reuse_cis_id,
    AudioContexts metadata_context_type,
    const std::vector<uint8_t>& ccid_list) {
  struct ase* ase = GetFirstInactiveAse(ent.direction, reuse_cis_id);
  if (!ase) return false;
  /* First try to use the already configured ASE */
  auto ase = GetFirstActiveAseByDirection(ent.direction);
  if (ase) {
    LOG_INFO("Using an already active ASE id=%d", ase->id);
  } else {
    ase = GetFirstInactiveAse(ent.direction, reuse_cis_id);
  }

  if (!ase) {
    LOG_ERROR("Unable to find an ASE to configure");
    return false;
  }

  uint8_t active_ases = *number_of_already_active_group_ase;
  uint8_t max_required_ase_per_dev =
@@ -1551,8 +1561,12 @@ bool LeAudioDevice::ConfigureAses(
        (ent.direction == 1 ? "snk" : "src"), ase->max_sdu_size, ase->cis_id,
        ent.target_latency);

    /* Try to use the already active ASE */
    ase = GetNextActiveAseWithSameDirection(ase);
    if (ase == nullptr) {
      ase = GetFirstInactiveAse(ent.direction, reuse_cis_id);
    }
  }

  *number_of_already_active_group_ase = active_ases;
  return true;
@@ -1603,12 +1617,6 @@ bool LeAudioDeviceGroup::ConfigureAses(
    for (auto* device = GetFirstDeviceWithActiveContext(context_type);
         device != nullptr && required_device_cnt > 0;
         device = GetNextDeviceWithActiveContext(device, context_type)) {
      /* Skip if device has ASE configured in this direction already */
      if (device->GetFirstActiveAseByDirection(ent.direction)) {
        required_device_cnt--;
        continue;
      }

      /* For the moment, we configure only connected devices and when it is
       * ready to stream i.e. All ASEs are discovered and device is reported as
       * connected
+21 −9
Original line number Diff line number Diff line
@@ -3440,10 +3440,12 @@ TEST_F(UnicastTest, TwoEarbudsStreamingContextSwitchNoReconfigure) {
  LeAudioClient::Get()->GroupSetActive(group_id);
  Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);

  // Start streaming with reconfiguration from default media stream setup
  // Start streaming with new metadata, but use the existing configuration
  EXPECT_CALL(
      mock_state_machine_,
      StartStream(_, le_audio::types::LeAudioContextType::NOTIFICATIONS, _, _))
      StartStream(
          _, types::LeAudioContextType::MEDIA,
          types::AudioContexts(types::LeAudioContextType::NOTIFICATIONS), _))
      .Times(1);

  StartStreaming(AUDIO_USAGE_NOTIFICATION, AUDIO_CONTENT_TYPE_UNKNOWN,
@@ -3453,37 +3455,47 @@ TEST_F(UnicastTest, TwoEarbudsStreamingContextSwitchNoReconfigure) {
  Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
  SyncOnMainLoop();

  // Do a content switch to ALERTS
  // Do a metadata content switch to ALERTS but stay on MEDIA configuration
  EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(0);
  EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop).Times(0);
  EXPECT_CALL(*mock_le_audio_source_hal_client_, Start).Times(0);
  EXPECT_CALL(mock_state_machine_,
              StartStream(_, le_audio::types::LeAudioContextType::ALERTS, _, _))
  EXPECT_CALL(
      mock_state_machine_,
      StartStream(
          _, le_audio::types::LeAudioContextType::MEDIA,
          types::AudioContexts(le_audio::types::LeAudioContextType::ALERTS), _))
      .Times(1);
  UpdateMetadata(AUDIO_USAGE_ALARM, AUDIO_CONTENT_TYPE_UNKNOWN);
  Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
  Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);

  // Do a content switch to EMERGENCY
  // Do a metadata content switch to EMERGENCY but stay on MEDIA configuration
  EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(0);
  EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop).Times(0);
  EXPECT_CALL(*mock_le_audio_source_hal_client_, Start).Times(0);

  EXPECT_CALL(
      mock_state_machine_,
      StartStream(_, le_audio::types::LeAudioContextType::EMERGENCYALARM, _, _))
      StartStream(_, le_audio::types::LeAudioContextType::MEDIA,
                  types::AudioContexts(
                      le_audio::types::LeAudioContextType::EMERGENCYALARM),
                  _))
      .Times(1);
  UpdateMetadata(AUDIO_USAGE_EMERGENCY, AUDIO_CONTENT_TYPE_UNKNOWN);
  Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
  Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);

  // Do a content switch to INSTRUCTIONAL
  // Do a metadata content switch to INSTRUCTIONAL but stay on MEDIA
  // configuration
  EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(0);
  EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop).Times(0);
  EXPECT_CALL(*mock_le_audio_source_hal_client_, Start).Times(0);
  EXPECT_CALL(
      mock_state_machine_,
      StartStream(_, le_audio::types::LeAudioContextType::INSTRUCTIONAL, _, _))
      StartStream(_, le_audio::types::LeAudioContextType::MEDIA,
                  types::AudioContexts(
                      le_audio::types::LeAudioContextType::INSTRUCTIONAL),
                  _))
      .Times(1);
  UpdateMetadata(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
                 AUDIO_CONTENT_TYPE_UNKNOWN);
+2 −0
Original line number Diff line number Diff line
@@ -61,6 +61,8 @@ LeAudioContextType AudioContentToLeAudioContext(
      return LeAudioContextType::EMERGENCYALARM;
    case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
      return LeAudioContextType::INSTRUCTIONAL;
    case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
      return LeAudioContextType::SOUNDEFFECTS;
    default:
      break;
  }