Loading system/audio_hal_interface/audio_linux.h +2 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,8 @@ /* Audio attributes */ #define AUDIO_ATTRIBUTES_TAGS_MAX_SIZE 256 static const char AUDIO_ATTRIBUTES_TAGS_SEPARATOR = ';'; typedef enum { AUDIO_SOURCE_DEFAULT = 0, AUDIO_SOURCE_MIC = 1, Loading system/bta/le_audio/le_audio_client_test.cc +71 −0 Original line number Diff line number Diff line Loading @@ -92,6 +92,8 @@ constexpr le_audio::types::LeAudioContextType static tGATT_STATUS gatt_read_ctp_ccc_status_ = GATT_SUCCESS; static uint8_t ccc_stored_byte_val_ = 0x01; static char* test_tags_ptr_ = nullptr; static constexpr char kNotifyUpperLayerAboutGroupBeingInIdleDuringCall[] = "persist.bluetooth.leaudio.notify.idle.during.call"; const char* test_flags[] = { Loading Loading @@ -1404,6 +1406,7 @@ class UnicastTestNoInit : public Test { gatt_read_ctp_ccc_status_ = GATT_SUCCESS; ccc_stored_byte_val_ = 0x01; test_tags_ptr_ = nullptr; controller::SetMockControllerInterface(&controller_interface_); bluetooth::manager::SetMockBtmInterface(&mock_btm_interface_); Loading Loading @@ -1787,6 +1790,10 @@ class UnicastTestNoInit : public Test { .gain = track.gain, }, }; if (test_tags_ptr_) { memcpy(desc_track.tags, test_tags_ptr_, strlen(test_tags_ptr_)); } tracks_vec.push_back(desc_track); } Loading Loading @@ -5262,6 +5269,70 @@ TEST_F(UnicastTest, TwoEarbudsStreaming) { .has_value()); } TEST_F(UnicastTest, StreamingVxAospSampleSound) { uint8_t group_size = 2; int group_id = 2; /* Test to verify that tag VX_AOSP_SAMPLESOUND is always mapped to * LeAudioContextType::SOUNDEFFECTS */ // Report working CSIS ON_CALL(mock_csis_client_module_, IsCsisClientRunning()) .WillByDefault(Return(true)); // First earbud const RawAddress test_address0 = GetTestAddress(0); EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)) .Times(1); ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft, codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/); // Second earbud const RawAddress test_address1 = GetTestAddress(1); EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)) .Times(1); ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight, codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/, true /*connect_through_csis*/); ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id)) .WillByDefault(Invoke([&](int group_id) { return 2; })); // Start streaming EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _)).Times(1); EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _)).Times(1); LeAudioClient::Get()->GroupSetActive(group_id); SyncOnMainLoop(); Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_); // Set a test TAG char test_tag[] = "TEST_TAG2;VX_AOSP_SAMPLESOUND;TEST_TAG1"; test_tags_ptr_ = test_tag; auto initial_context = types::LeAudioContextType::SOUNDEFFECTS; types::BidirectionalPair<std::vector<uint8_t>> ccids = {.sink = {}, .source = {}}; EXPECT_CALL(mock_state_machine_, StartStream(_, initial_context, _, ccids)) .Times(1); StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id); Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_); SyncOnMainLoop(); // Verify Data transfer on two peer sinks and one source uint8_t cis_count_out = 2; uint8_t cis_count_in = 0; TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 0); } TEST_F(UnicastTest, UpdateActiveAudioConfigForLocalSinkSource) { uint8_t group_size = 2; int group_id = 2; Loading system/bta/le_audio/le_audio_utils.cc +19 −2 Original line number Diff line number Diff line Loading @@ -150,6 +150,18 @@ static const char* audioSourceToStr(audio_source_t source) { return "UNKNOWN"; } static bool isMetadataTagPresent(const char* tags, const char* tag) { std::istringstream iss(tags); std::string t; while (std::getline(iss, t, AUDIO_ATTRIBUTES_TAGS_SEPARATOR)) { LOG_VERBOSE("Tag %s", t.c_str()); if (t.compare(tag) == 0) { return true; } } return false; } AudioContexts GetAudioContextsFromSourceMetadata( const source_metadata_v7& source_metadata) { AudioContexts track_contexts; Loading @@ -162,9 +174,14 @@ AudioContexts GetAudioContextsFromSourceMetadata( contentTypeToString(track.content_type).c_str(), track.content_type, track.gain, source_metadata.tracks[i].tags); if (isMetadataTagPresent(source_metadata.tracks[i].tags, "VX_AOSP_SAMPLESOUND")) { track_contexts.set(LeAudioContextType::SOUNDEFFECTS); } else { track_contexts.set( AudioContentToLeAudioContext(track.content_type, track.usage)); } } return track_contexts; } Loading Loading
system/audio_hal_interface/audio_linux.h +2 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,8 @@ /* Audio attributes */ #define AUDIO_ATTRIBUTES_TAGS_MAX_SIZE 256 static const char AUDIO_ATTRIBUTES_TAGS_SEPARATOR = ';'; typedef enum { AUDIO_SOURCE_DEFAULT = 0, AUDIO_SOURCE_MIC = 1, Loading
system/bta/le_audio/le_audio_client_test.cc +71 −0 Original line number Diff line number Diff line Loading @@ -92,6 +92,8 @@ constexpr le_audio::types::LeAudioContextType static tGATT_STATUS gatt_read_ctp_ccc_status_ = GATT_SUCCESS; static uint8_t ccc_stored_byte_val_ = 0x01; static char* test_tags_ptr_ = nullptr; static constexpr char kNotifyUpperLayerAboutGroupBeingInIdleDuringCall[] = "persist.bluetooth.leaudio.notify.idle.during.call"; const char* test_flags[] = { Loading Loading @@ -1404,6 +1406,7 @@ class UnicastTestNoInit : public Test { gatt_read_ctp_ccc_status_ = GATT_SUCCESS; ccc_stored_byte_val_ = 0x01; test_tags_ptr_ = nullptr; controller::SetMockControllerInterface(&controller_interface_); bluetooth::manager::SetMockBtmInterface(&mock_btm_interface_); Loading Loading @@ -1787,6 +1790,10 @@ class UnicastTestNoInit : public Test { .gain = track.gain, }, }; if (test_tags_ptr_) { memcpy(desc_track.tags, test_tags_ptr_, strlen(test_tags_ptr_)); } tracks_vec.push_back(desc_track); } Loading Loading @@ -5262,6 +5269,70 @@ TEST_F(UnicastTest, TwoEarbudsStreaming) { .has_value()); } TEST_F(UnicastTest, StreamingVxAospSampleSound) { uint8_t group_size = 2; int group_id = 2; /* Test to verify that tag VX_AOSP_SAMPLESOUND is always mapped to * LeAudioContextType::SOUNDEFFECTS */ // Report working CSIS ON_CALL(mock_csis_client_module_, IsCsisClientRunning()) .WillByDefault(Return(true)); // First earbud const RawAddress test_address0 = GetTestAddress(0); EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)) .Times(1); ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft, codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/); // Second earbud const RawAddress test_address1 = GetTestAddress(1); EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)) .Times(1); ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight, codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/, true /*connect_through_csis*/); ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id)) .WillByDefault(Invoke([&](int group_id) { return 2; })); // Start streaming EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _)).Times(1); EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _)).Times(1); LeAudioClient::Get()->GroupSetActive(group_id); SyncOnMainLoop(); Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_); // Set a test TAG char test_tag[] = "TEST_TAG2;VX_AOSP_SAMPLESOUND;TEST_TAG1"; test_tags_ptr_ = test_tag; auto initial_context = types::LeAudioContextType::SOUNDEFFECTS; types::BidirectionalPair<std::vector<uint8_t>> ccids = {.sink = {}, .source = {}}; EXPECT_CALL(mock_state_machine_, StartStream(_, initial_context, _, ccids)) .Times(1); StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id); Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_); SyncOnMainLoop(); // Verify Data transfer on two peer sinks and one source uint8_t cis_count_out = 2; uint8_t cis_count_in = 0; TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 0); } TEST_F(UnicastTest, UpdateActiveAudioConfigForLocalSinkSource) { uint8_t group_size = 2; int group_id = 2; Loading
system/bta/le_audio/le_audio_utils.cc +19 −2 Original line number Diff line number Diff line Loading @@ -150,6 +150,18 @@ static const char* audioSourceToStr(audio_source_t source) { return "UNKNOWN"; } static bool isMetadataTagPresent(const char* tags, const char* tag) { std::istringstream iss(tags); std::string t; while (std::getline(iss, t, AUDIO_ATTRIBUTES_TAGS_SEPARATOR)) { LOG_VERBOSE("Tag %s", t.c_str()); if (t.compare(tag) == 0) { return true; } } return false; } AudioContexts GetAudioContextsFromSourceMetadata( const source_metadata_v7& source_metadata) { AudioContexts track_contexts; Loading @@ -162,9 +174,14 @@ AudioContexts GetAudioContextsFromSourceMetadata( contentTypeToString(track.content_type).c_str(), track.content_type, track.gain, source_metadata.tracks[i].tags); if (isMetadataTagPresent(source_metadata.tracks[i].tags, "VX_AOSP_SAMPLESOUND")) { track_contexts.set(LeAudioContextType::SOUNDEFFECTS); } else { track_contexts.set( AudioContentToLeAudioContext(track.content_type, track.usage)); } } return track_contexts; } Loading