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

Commit 18429f61 authored by Jakub Tyszkowski's avatar Jakub Tyszkowski
Browse files

LeAudio: Do not reconfigure to UNSPECIFIED scenario

When a remote does not declare support for  contexts like
NOTIFICATIONS, ALERTS, EMERGENCYALARM, INSTRUCTIONAL,
SOUNDEFFECTS and we would like to play them, we usually end
up using UNSPECIFIED context. In such case it is ok to use the
existing configuration and do not reconfigure for HQ playback
only configuration.

Bug: 269394021
Tag: #feature
Test: atest --host bluetooth_le_audio_client_test bluetooth_le_audio_test --no-bazel-mode
Change-Id: I050f310b50e6b1560a4b8bfc67aca170730f7c7d
parent 8e65af97
Loading
Loading
Loading
Loading
+13 −9
Original line number Original line Diff line number Diff line
@@ -3640,16 +3640,17 @@ class LeAudioClientImpl : public LeAudioClient {
      }
      }
    }
    }


    /* We keepo the existing configuration, when not in a call, but the user
    /* Use BAP mandated UNSPECIFIED only if we don't have any other valid
     * adjusts the ringtone volume while there is no other valid audio stream.
     * configuration
     */
     */
    if (available_remote_contexts.test(LeAudioContextType::RINGTONE)) {
    auto fallback_config = LeAudioContextType::UNSPECIFIED;
      return configuration_context_type_;
    if (configuration_context_type_ != LeAudioContextType::UNINITIALIZED) {
      fallback_config = configuration_context_type_;
    }
    }


    /* Fallback to BAP mandated context type */
    LOG_DEBUG("Selecting configuration context type: %s",
    LOG_WARN("Invalid/unknown context, using 'UNSPECIFIED'");
              ToString(fallback_config).c_str());
    return LeAudioContextType::UNSPECIFIED;
    return fallback_config;
  }
  }


  bool SetConfigurationAndStopStreamWhenNeeded(
  bool SetConfigurationAndStopStreamWhenNeeded(
@@ -3797,14 +3798,17 @@ class LeAudioClientImpl : public LeAudioClient {
     * LeAudioContextType::INSTRUCTIONAL
     * LeAudioContextType::INSTRUCTIONAL
     * LeAudioContextType::ALERTS
     * LeAudioContextType::ALERTS
     * LeAudioContextType::EMERGENCYALARM
     * LeAudioContextType::EMERGENCYALARM
     * LeAudioContextType::UNSPECIFIED
     * So do not reconfigure if the remote sink is already available at any
     * 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.
     * quality and these are the only contributors to the current audio stream.
     */
     */
    auto no_reconfigure_contexts =
    auto no_reconfigure_contexts =
        LeAudioContextType::NOTIFICATIONS | LeAudioContextType::SOUNDEFFECTS |
        LeAudioContextType::NOTIFICATIONS | LeAudioContextType::SOUNDEFFECTS |
        LeAudioContextType::INSTRUCTIONAL | LeAudioContextType::ALERTS |
        LeAudioContextType::INSTRUCTIONAL | LeAudioContextType::ALERTS |
        LeAudioContextType::EMERGENCYALARM;
        LeAudioContextType::EMERGENCYALARM | LeAudioContextType::UNSPECIFIED;
    if ((configuration_context_candidates & ~no_reconfigure_contexts).none() &&
    if (configuration_context_candidates.any() &&
        (configuration_context_candidates & ~no_reconfigure_contexts).none() &&
        (configuration_context_type_ != LeAudioContextType::UNINITIALIZED) &&
        IsDirectionAvailableForCurrentConfiguration(
        IsDirectionAvailableForCurrentConfiguration(
            group, le_audio::types::kLeAudioDirectionSink)) {
            group, le_audio::types::kLeAudioDirectionSink)) {
      LOG_INFO(
      LOG_INFO(
+67 −8
Original line number Original line Diff line number Diff line
@@ -3925,7 +3925,7 @@ TEST_F(UnicastTest, MicrophoneAttachToCurrentMediaScenario) {
  Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
  Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
}
}


TEST_F(UnicastTest, StartNotSupportedContextType) {
TEST_F(UnicastTest, UpdateNotSupportedContextType) {
  const RawAddress test_address0 = GetTestAddress(0);
  const RawAddress test_address0 = GetTestAddress(0);
  int group_id = bluetooth::groups::kGroupUnknown;
  int group_id = bluetooth::groups::kGroupUnknown;


@@ -3975,18 +3975,77 @@ TEST_F(UnicastTest, StartNotSupportedContextType) {


  LeAudioClient::Get()->SetInCall(false);
  LeAudioClient::Get()->SetInCall(false);


  /* Fallback scenario now supports 48Khz just like Media so we will reconfigure
  /* We should stay on the existing configuration as there is no GAME
   * Note: Fallback is forced by supported_snk_context_types_ not having GAME on
   * context available on the remote device.
   * the remote device.
   */
   */
  EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1);
  EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
  UpdateMetadata(AUDIO_USAGE_GAME, AUDIO_CONTENT_TYPE_UNKNOWN, true);
  types::BidirectionalPair<types::AudioContexts> contexts = {
      .sink = types::AudioContexts(types::LeAudioContextType::UNSPECIFIED),
      .source = types::AudioContexts()};
  EXPECT_CALL(
      mock_state_machine_,
      StartStream(_, types::LeAudioContextType::CONVERSATIONAL, contexts, _))
      .Times(1);
  UpdateMetadata(AUDIO_USAGE_GAME, AUDIO_CONTENT_TYPE_UNKNOWN, false);


  /* The above will trigger reconfiguration. After that Audio Hal action
  /* If the above triggers reconfiguration, Audio Hal action is needed to
   * is needed to restart the stream */
   * restart the stream.
   */
  SinkAudioResume();
  SinkAudioResume();
}
}


TEST_F(UnicastTest, StartNotSupportedContextType) {
  const RawAddress test_address0 = GetTestAddress(0);
  int group_id = bluetooth::groups::kGroupUnknown;

  supported_snk_context_types_ = (types::LeAudioContextType::RINGTONE |
                                  types::LeAudioContextType::CONVERSATIONAL |
                                  types::LeAudioContextType::UNSPECIFIED |
                                  types::LeAudioContextType::MEDIA)
                                     .value();
  supported_src_context_types_ = supported_snk_context_types_;

  SetSampleDatabaseEarbudsValid(
      1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
      codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
      default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
      true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
      0 /*rank*/);
  EXPECT_CALL(mock_audio_hal_client_callbacks_,
              OnConnectionState(ConnectionState::CONNECTED, test_address0))
      .Times(1);
  EXPECT_CALL(mock_audio_hal_client_callbacks_,
              OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
      .WillOnce(DoAll(SaveArg<1>(&group_id)));

  ConnectLeAudio(test_address0);
  ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);

  // Expect configuring to the default config since the EMERGENCYALARM is
  // not on the list of supported contexts and UNSPECIFIED will be used in
  // the metadata.
  auto default_config = types::LeAudioContextType::MEDIA;
  EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _)).Times(1);
  types::BidirectionalPair<types::AudioContexts> metadata = {
      .sink = types::AudioContexts(types::LeAudioContextType::UNSPECIFIED),
      .source = types::AudioContexts()};
  EXPECT_CALL(mock_state_machine_, StartStream(_, default_config, metadata, _))
      .Times(1);

  LeAudioClient::Get()->GroupSetActive(group_id);

  StartStreaming(AUDIO_USAGE_EMERGENCY, AUDIO_CONTENT_TYPE_UNKNOWN, group_id);

  SyncOnMainLoop();
  Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
  Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);

  // Verify Data transfer on one audio source cis
  uint8_t cis_count_out = 1;
  uint8_t cis_count_in = 0;
  TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
}

TEST_F(UnicastTest, NotifyAboutGroupTunrnedIdleEnabled) {
TEST_F(UnicastTest, NotifyAboutGroupTunrnedIdleEnabled) {
  const RawAddress test_address0 = GetTestAddress(0);
  const RawAddress test_address0 = GetTestAddress(0);
  int group_id = bluetooth::groups::kGroupUnknown;
  int group_id = bluetooth::groups::kGroupUnknown;