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

Commit dbd08078 authored by Łukasz Rymanowski's avatar Łukasz Rymanowski
Browse files

leaudio: Refactor unidirectional handling for VOICE ASSISTANT

Change the way unidirectional configuration is choosen when remote
device has no support for ASSISTANT context on a single direction.

This is needed for simialar change in GAME context.

Note: Some cleaning on duplicated json configuration has been done in
this CL as well.

Bug: 351974325
Bug: 332510824
Test: atest bluetooth_le_audio_client_test bluetooth_le_audio_test
Flag: com.android.bluetooth.flags.le_audio_support_unidirectional_voice_assistant
Change-Id: I3bda2a1b182fadac805e1a9a3614ce43587823cb
parent bed497a1
Loading
Loading
Loading
Loading
+8304 −7487

File changed.

Preview size limit exceeded, changes collapsed.

+293 −257
Original line number Diff line number Diff line
@@ -207,7 +207,43 @@
        "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
        "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
        "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
                "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability"
        "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
        "Two-OneChan-SnkAse-Lc3_48_2_Low_Latency",
        "Two-OneChan-SnkAse-Lc3_48_3_Low_Latency",
        "Two-OneChan-SnkAse-Lc3_48_1_Low_Latency",
        "Two-OneChan-SnkAse-Lc3_32_2_Low_Latency",
        "Two-OneChan-SnkAse-Lc3_32_1_Low_Latency",
        "Two-OneChan-SnkAse-Lc3_24_2_Low_Latency",
        "Two-OneChan-SnkAse-Lc3_24_1_Low_Latency",
        "Two-OneChan-SnkAse-Lc3_16_2_Low_Latency",
        "Two-OneChan-SnkAse-Lc3_16_1_Low_Latency",
        "One-TwoChan-SnkAse-Lc3_48_2_Low_Latency",
        "One-TwoChan-SnkAse-Lc3_48_3_Low_Latency",
        "One-TwoChan-SnkAse-Lc3_48_1_Low_Latency",
        "One-TwoChan-SnkAse-Lc3_32_2_Low_Latency",
        "One-TwoChan-SnkAse-Lc3_32_1_Low_Latency",
        "One-TwoChan-SnkAse-Lc3_24_2_Low_Latency",
        "One-TwoChan-SnkAse-Lc3_24_1_Low_Latency",
        "One-TwoChan-SnkAse-Lc3_16_2_Low_Latency",
        "One-TwoChan-SnkAse-Lc3_16_1_Low_Latency",
        "Two-OneChan-SrcAse-Lc3_32_2_Low_Latency",
        "Two-OneChan-SrcAse-Lc3_32_1_Low_Latency",
        "Two-OneChan-SrcAse-Lc3_24_2_Low_Latency",
        "Two-OneChan-SrcAse-Lc3_24_1_Low_Latency",
        "Two-OneChan-SrcAse-Lc3_16_2_Low_Latency",
        "Two-OneChan-SrcAse-Lc3_16_1_Low_Latency",
        "One-TwoChan-SrcAse-Lc3_32_2_Low_Latency",
        "One-TwoChan-SrcAse-Lc3_32_1_Low_Latency",
        "One-TwoChan-SrcAse-Lc3_24_2_Low_Latency",
        "One-TwoChan-SrcAse-Lc3_24_1_Low_Latency",
        "One-TwoChan-SrcAse-Lc3_16_2_Low_Latency",
        "One-TwoChan-SrcAse-Lc3_16_1_Low_Latency",
        "One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
        "One-OneChan-SrcAse-Lc3_32_1_Low_Latency",
        "One-OneChan-SrcAse-Lc3_24_2_Low_Latency",
        "One-OneChan-SrcAse-Lc3_24_1_Low_Latency",
        "One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
        "One-OneChan-SrcAse-Lc3_16_1_Low_Latency"
      ]
    },
    {
+4 −49
Original line number Diff line number Diff line
@@ -317,8 +317,8 @@ public:
    }

    /* Choose the right configuration context */
    auto new_configuration_context = AdjustForVoiceAssistant(
            group, ChooseConfigurationContextType(local_metadata_context_types_.source));
    auto new_configuration_context =
            ChooseConfigurationContextType(local_metadata_context_types_.source);

    log::debug("new_configuration_context= {}", ToString(new_configuration_context));
    ReconfigureOrUpdateMetadata(group, new_configuration_context,
@@ -4374,9 +4374,6 @@ public:
      LeAudioContextType context_priority_list[] = {
              /* Highest priority first */
              LeAudioContextType::CONVERSATIONAL,
              /* Handling RINGTONE will cause the ringtone volume slider to trigger
               * reconfiguration. This will be fixed in b/283349711.
               */
              LeAudioContextType::RINGTONE,
              LeAudioContextType::LIVE,
              LeAudioContextType::VOICEASSISTANTS,
@@ -4755,46 +4752,6 @@ public:
    return remote_metadata;
  }

  LeAudioContextType AdjustForVoiceAssistant(LeAudioDeviceGroup* group,
                                             LeAudioContextType new_configuration_context) {
    if (!com::android::bluetooth::flags::le_audio_support_unidirectional_voice_assistant()) {
      log::debug("Flag le_audio_support_unidirectional_voice_assistant NOT enabled");
      return new_configuration_context;
    }

    /* Some remote devices expect VOICE ASSISTANT to be unidirectional Phone is
     * Source and Earbuds are Sink */
    if (new_configuration_context != LeAudioContextType::VOICEASSISTANTS) {
      return new_configuration_context;
    }

    auto sink_supported_contexts =
            group->GetSupportedContexts(bluetooth::le_audio::types::kLeAudioDirectionSink);
    auto source_supported_contexts =
            group->GetSupportedContexts(bluetooth::le_audio::types::kLeAudioDirectionSource);

    log::debug("group_id: {}, sink_supported: {}, source_supported {}", group->group_id_,
               ToString(sink_supported_contexts), ToString(source_supported_contexts));
    if (sink_supported_contexts.test(LeAudioContextType::VOICEASSISTANTS) &&
        source_supported_contexts.test(LeAudioContextType::VOICEASSISTANTS)) {
      return new_configuration_context;
    }

    if (sink_supported_contexts.test(LeAudioContextType::VOICEASSISTANTS)) {
      log::info(
              "group_id {} supports only Sink direction for Voice Assistant. "
              "Selecting configurarion context type {}",
              group->group_id_, ToString(LeAudioContextType::INSTRUCTIONAL));

      return LeAudioContextType::INSTRUCTIONAL;
    }

    log::warn("group_id: {},  unexpected configuration, sink_supported: {}, source_supported {}",
              group->group_id_, ToString(sink_supported_contexts),
              ToString(source_supported_contexts));
    return new_configuration_context;
  }

  /* Return true if stream is started */
  bool ReconfigureOrUpdateRemote(LeAudioDeviceGroup* group, int remote_direction) {
    if (stack_config_get_interface()->get_pts_force_le_audio_multiple_contexts_metadata()) {
@@ -4811,8 +4768,7 @@ public:
                local_metadata_context_types_.source.to_string(), override_contexts.to_string());

      /* Choose the right configuration context */
      auto new_configuration_context =
              AdjustForVoiceAssistant(group, ChooseConfigurationContextType(override_contexts));
      auto new_configuration_context = ChooseConfigurationContextType(override_contexts);

      log::debug("new_configuration_context= {}.", ToString(new_configuration_context));
      BidirectionalPair<AudioContexts> remote_contexts = {.sink = override_contexts,
@@ -4829,8 +4785,7 @@ public:

    /* Choose the right configuration context */
    auto config_context_candids = get_bidirectional(remote_metadata);
    auto new_config_context =
            AdjustForVoiceAssistant(group, ChooseConfigurationContextType(config_context_candids));
    auto new_config_context = ChooseConfigurationContextType(config_context_candids);
    log::debug("config_context_candids= {}, new_config_context= {}",
               ToString(config_context_candids), ToString(new_config_context));

+30 −0
Original line number Diff line number Diff line
@@ -828,6 +828,21 @@ LeAudioDeviceGroup::GetAudioSetConfigurationRequirements(types::LeAudioContextTy
        continue;
      }

      if (com::android::bluetooth::flags::le_audio_support_unidirectional_voice_assistant() &&
          ctx_type == types::LeAudioContextType::VOICEASSISTANTS) {
        // For GAME and VOICE ASSISTANT, ignore direction if it is not supported only on a single
        // direction.
        auto group_contexts = GetSupportedContexts(types::kLeAudioDirectionBoth);
        if (group_contexts.test(ctx_type)) {
          auto direction_contexs = device->GetSupportedContexts(direction);
          if (!direction_contexs.test(ctx_type)) {
            log::warn("Device {} has no {} context support", device->address_,
                      common::ToString(ctx_type));
            continue;
          }
        }
      }

      auto& dev_locations = (direction == types::kLeAudioDirectionSink)
                                    ? device->snk_audio_locations_
                                    : device->src_audio_locations_;
@@ -1399,6 +1414,21 @@ bool LeAudioDeviceGroup::IsAudioSetConfigurationSupported(
      continue;
    }

    if (com::android::bluetooth::flags::le_audio_support_unidirectional_voice_assistant()) {
      // Verify the direction requirements.
      if (direction == types::kLeAudioDirectionSink &&
          requirements.sink_requirements->size() == 0) {
        log::debug("There is no requirement for Sink direction.");
        return false;
      }

      if (direction == types::kLeAudioDirectionSource &&
          requirements.source_requirements->size() == 0) {
        log::debug("There is no requirement for source direction.");
        return false;
      }
    }

    // In some tests we expect the configuration to be there even when the
    // contexts are not supported. Then we might want to configure the device
    // but use UNSPECIFIED which is always supported (but can be unavailable)
+13 −8
Original line number Diff line number Diff line
@@ -5838,14 +5838,16 @@ TEST_F(UnicastTest, TestUnidirectionalVoiceAssistant_Sink) {

  types::BidirectionalPair<types::AudioContexts> metadata_contexts = {
          .sink = types::AudioContexts(types::LeAudioContextType::VOICEASSISTANTS),
          .source = types::AudioContexts()};
          .source = types::AudioContexts(types::LeAudioContextType::UNSPECIFIED)};
  EXPECT_CALL(mock_state_machine_,
              StartStream(_, types::LeAudioContextType::INSTRUCTIONAL, metadata_contexts, _))
              StartStream(_, types::LeAudioContextType::VOICEASSISTANTS, metadata_contexts, _))
          .Times(1);

  log::info("Connecting LeAudio to {}", test_address0);
  ConnectLeAudio(test_address0);
  ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);

  // Start streaming
  // We do expect only unidirectional CIS
  uint8_t cis_count_out = 1;
  uint8_t cis_count_in = 0;

@@ -5883,7 +5885,7 @@ TEST_F(UnicastTest, TestUnidirectionalVoiceAssistant_Source) {
   * Scenario test steps
   * 1. Configure group to support VOICEASSISTANT only on SOURCE
   * 2. Start stream
   * 5. Verify that bi-direction VOICEASSISTANT has been created
   * 5. Verify that uni-direction VOICEASSISTANT has been created
   */

  available_snk_context_types_ =
@@ -5915,11 +5917,14 @@ TEST_F(UnicastTest, TestUnidirectionalVoiceAssistant_Source) {
  EXPECT_CALL(mock_state_machine_,
              StartStream(_, types::LeAudioContextType::VOICEASSISTANTS, metadata_contexts, _))
          .Times(1);

  log::info("Connecting LeAudio device {}", test_address0);

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

  // Start streaming
  uint8_t cis_count_out = 1;
  // Expected only unidirectional CIS
  uint8_t cis_count_out = 0;
  uint8_t cis_count_in = 1;

  // Audio sessions are started only when device gets active
@@ -5928,8 +5933,8 @@ TEST_F(UnicastTest, TestUnidirectionalVoiceAssistant_Source) {
  LeAudioClient::Get()->GroupSetActive(group_id);
  SyncOnMainLoop();

  StartStreaming(AUDIO_USAGE_ASSISTANT, AUDIO_CONTENT_TYPE_UNKNOWN, group_id,
                 AUDIO_SOURCE_VOICE_RECOGNITION);
  UpdateLocalSinkMetadata(AUDIO_SOURCE_VOICE_RECOGNITION);
  LocalAudioSinkResume();

  // Verify Data transfer on one local audio source cis
  TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);