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

Commit a28cb6b0 authored by Grzegorz Kołodziejczyk's avatar Grzegorz Kołodziejczyk Committed by Grzegorz Kolodziejczyk
Browse files

le_audio: Introduce source streaming request with no context validation

This request would help some devices that does not expose requested
available context wile receiving broadcast. Broadcast sink which loses
synchronization most probably would expose requested available contexts
again.

Tag: #bug
Bug: 329189979
Bug: 336466406
Test: atest LeAudioBroadcastServiceTest
Change-Id: I33ba1b0efdca6a589f23d30ade60be2b9be935a7
parent 2205741d
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ public class BassClientService extends ProfileService {
    private static final int STATUS_LOCAL_STREAM_REQUESTED = 0;
    private static final int STATUS_LOCAL_STREAM_STREAMING = 1;
    private static final int STATUS_LOCAL_STREAM_SUSPENDED = 2;
    private static final int STATUS_LOCAL_STREAM_REQUESTED_NO_CONTEXT_VALIDATE = 3;

    // Do not modify without updating the HAL bt_le_audio.h files.
    // Match up with BroadcastState enum of bt_le_audio.h
@@ -2308,6 +2309,8 @@ public class BassClientService extends ProfileService {
            }
        } else if (status == STATUS_LOCAL_STREAM_STREAMING) {
            Log.d(TAG, "Ignore STREAMING source status");
        } else if (status == STATUS_LOCAL_STREAM_REQUESTED_NO_CONTEXT_VALIDATE) {
            suspendAllReceiversSourceSynchronization();
        }
    }

+3 −0
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ public class LeAudioStackEvent {
    static final int STATUS_LOCAL_STREAM_REQUESTED = 0;
    static final int STATUS_LOCAL_STREAM_STREAMING = 1;
    static final int STATUS_LOCAL_STREAM_SUSPENDED = 2;
    static final int STATUS_LOCAL_STREAM_REQUESTED_NO_CONTEXT_VALIDATE = 3;

    // Do not modify without updating le_audio_types.h
    // Match up with defines of le_audio_types.h
@@ -307,6 +308,8 @@ public class LeAudioStackEvent {
                        return "STATUS_LOCAL_STREAM_STREAMING";
                    case STATUS_LOCAL_STREAM_SUSPENDED:
                        return "STATUS_LOCAL_STREAM_SUSPENDED";
                    case STATUS_LOCAL_STREAM_REQUESTED_NO_CONTEXT_VALIDATE:
                        return "STATUS_LOCAL_STREAM_REQUESTED_NO_CONTEXT_VALIDATE";
                    default:
                        return "UNKNOWN";
                }
+10 −0
Original line number Diff line number Diff line
@@ -3967,6 +3967,16 @@ class LeAudioClientImpl : public LeAudioClient {

    if (!remote_contexts.sink.any() && !remote_contexts.source.any()) {
      log::warn("Requested context type not available on the remote side");

      if (com::android::bluetooth::flags::leaudio_no_context_validate_streaming_request() &&
          source_monitor_mode_) {
        callbacks_->OnUnicastMonitorModeStatus(
            bluetooth::le_audio::types::kLeAudioDirectionSource,
            UnicastMonitorModeStatus::STREAMING_REQUESTED_NO_CONTEXT_VALIDATE);

        return false;
      }

      if (leAudioHealthStatus_) {
        leAudioHealthStatus_->AddStatisticForGroup(
            group, LeAudioHealthGroupStatType::STREAM_CONTEXT_NOT_AVAILABLE);
+71 −0
Original line number Diff line number Diff line
@@ -10590,4 +10590,75 @@ TEST_F(UnicastTestHandoverMode, SetAllowedContextMask) {
  Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
  Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
}

TEST_F_WITH_FLAGS(UnicastTest, NoContextvalidateStreamingRequest,
                  REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(
                      TEST_BT,
                      leaudio_no_context_validate_streaming_request))) {
  const RawAddress test_address0 = GetTestAddress(0);
  int group_id = bluetooth::groups::kGroupUnknown;

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

  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_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
  types::BidirectionalPair<types::AudioContexts> metadata = {
      .sink = types::AudioContexts(), .source = types::AudioContexts()};
  EXPECT_CALL(
      mock_state_machine_,
      StartStream(_, types::LeAudioContextType::SOUNDEFFECTS, metadata, _))
      .Times(0);

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

  // Imitate activation of monitor mode
  do_in_main_thread(
      FROM_HERE,
      base::BindOnce(&LeAudioClient::SetUnicastMonitorMode,
                     base::Unretained(LeAudioClient::Get()),
                     bluetooth::le_audio::types::kLeAudioDirectionSource,
                     true /* enable */));
  Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
  SyncOnMainLoop();

  // Stop streaming and expect Service to be informed about straming suspension
  EXPECT_CALL(
      mock_audio_hal_client_callbacks_,
      OnUnicastMonitorModeStatus(
          bluetooth::le_audio::types::kLeAudioDirectionSource,
          UnicastMonitorModeStatus::STREAMING_REQUESTED_NO_CONTEXT_VALIDATE))
      .Times(1);

  StartStreaming(AUDIO_USAGE_ASSISTANCE_SONIFICATION,
                 AUDIO_CONTENT_TYPE_UNKNOWN, group_id, AUDIO_SOURCE_INVALID,
                 false, false);

  SyncOnMainLoop();
  Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
  Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
}
}  // namespace bluetooth::le_audio
+1 −0
Original line number Diff line number Diff line
@@ -92,6 +92,7 @@ enum class UnicastMonitorModeStatus {
  STREAMING_REQUESTED = 0,
  STREAMING,
  STREAMING_SUSPENDED,
  STREAMING_REQUESTED_NO_CONTEXT_VALIDATE,
};

typedef enum {