Loading system/bta/le_audio/devices.cc +10 −0 Original line number Original line Diff line number Diff line Loading @@ -1235,6 +1235,8 @@ bool LeAudioDeviceGroup::IsConfigurationSupported( return false; return false; } } auto required_snk_strategy = GetGroupStrategy(); /* TODO For now: set ase if matching with first pac. /* TODO For now: set ase if matching with first pac. * 1) We assume as well that devices will match requirements in order * 1) We assume as well that devices will match requirements in order * e.g. 1 Device - 1 Requirement, 2 Device - 2 Requirement etc. * e.g. 1 Device - 1 Requirement, 2 Device - 2 Requirement etc. Loading @@ -1259,6 +1261,14 @@ bool LeAudioDeviceGroup::IsConfigurationSupported( +required_device_cnt, +ent.ase_cnt, +max_required_ase_per_dev, +required_device_cnt, +ent.ase_cnt, +max_required_ase_per_dev, static_cast<int>(strategy)); static_cast<int>(strategy)); if (ent.direction == types::kLeAudioDirectionSink && strategy != required_snk_strategy) { LOG_INFO(" Sink strategy mismatch (%d!=%d)", static_cast<int>(required_snk_strategy), static_cast<int>(strategy)); return false; } for (auto* device = GetFirstDeviceWithActiveContext(context_type); for (auto* device = GetFirstDeviceWithActiveContext(context_type); device != nullptr && required_device_cnt > 0; device != nullptr && required_device_cnt > 0; device = GetNextDeviceWithActiveContext(device, context_type)) { device = GetNextDeviceWithActiveContext(device, context_type)) { Loading system/bta/le_audio/devices_test.cc +234 −52 Original line number Original line Diff line number Diff line Loading @@ -218,7 +218,6 @@ bool IsLc3SettingSupported(LeAudioContextType context_type, Lc3SettingId id) { case LeAudioContextType::EMERGENCYALARM: case LeAudioContextType::EMERGENCYALARM: case LeAudioContextType::UNSPECIFIED: case LeAudioContextType::UNSPECIFIED: if (id == Lc3SettingId::LC3_16_1 || id == Lc3SettingId::LC3_16_2 || if (id == Lc3SettingId::LC3_16_1 || id == Lc3SettingId::LC3_16_2 || id == Lc3SettingId::LC3_32_1 || id == Lc3SettingId::LC3_32_2 || id == Lc3SettingId::LC3_48_4 || id == Lc3SettingId::LC3_48_2 || id == Lc3SettingId::LC3_48_4 || id == Lc3SettingId::LC3_48_2 || id == Lc3SettingId::LC3_VND_1 || id == Lc3SettingId::LC3_24_2) id == Lc3SettingId::LC3_VND_1 || id == Lc3SettingId::LC3_24_2) return true; return true; Loading Loading @@ -388,6 +387,7 @@ struct TestGroupAseConfigurationData { uint8_t audio_channel_counts_snk; uint8_t audio_channel_counts_snk; uint8_t audio_channel_counts_src; uint8_t audio_channel_counts_src; /* Note, do not confuse ASEs with channels num. */ uint8_t expected_active_channel_num_snk; uint8_t expected_active_channel_num_snk; uint8_t expected_active_channel_num_src; uint8_t expected_active_channel_num_src; }; }; Loading Loading @@ -418,22 +418,25 @@ class LeAudioAseConfigurationTest : public Test { devices_.push_back(device); devices_.push_back(device); group_->AddNode(device); group_->AddNode(device); int ase_id = 1; for (int i = 0; i < src_ase_num; i++) { for (int i = 0; i < src_ase_num; i++) { device->ases_.emplace_back(0x0000, 0x0000, kLeAudioDirectionSource); device->ases_.emplace_back(0x0000, 0x0000, kLeAudioDirectionSource, ase_id++); } } for (int i = 0; i < snk_ase_num; i++) { for (int i = 0; i < snk_ase_num; i++) { device->ases_.emplace_back(0x0000, 0x0000, kLeAudioDirectionSink); device->ases_.emplace_back(0x0000, 0x0000, kLeAudioDirectionSink, ase_id++); } } for (int i = 0; i < src_ase_num_cached; i++) { for (int i = 0; i < src_ase_num_cached; i++) { struct ase ase(0x0000, 0x0000, kLeAudioDirectionSource); struct ase ase(0x0000, 0x0000, kLeAudioDirectionSource, ase_id++); ase.state = AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED; ase.state = AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED; device->ases_.push_back(ase); device->ases_.push_back(ase); } } for (int i = 0; i < snk_ase_num_cached; i++) { for (int i = 0; i < snk_ase_num_cached; i++) { struct ase ase(0x0000, 0x0000, kLeAudioDirectionSink); struct ase ase(0x0000, 0x0000, kLeAudioDirectionSink, ase_id++); ase.state = AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED; ase.state = AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED; device->ases_.push_back(ase); device->ases_.push_back(ase); } } Loading @@ -451,17 +454,18 @@ class LeAudioAseConfigurationTest : public Test { device->conn_id_ = index; device->conn_id_ = index; device->SetConnectionState(DeviceConnectState::CONNECTED); device->SetConnectionState(DeviceConnectState::CONNECTED); group_->ReloadAudioDirections(); group_->ReloadAudioLocations(); return device.get(); return device.get(); } } void TestGroupAseConfigurationVerdict( bool TestGroupAseConfigurationVerdict( const TestGroupAseConfigurationData& data) { const TestGroupAseConfigurationData& data, uint8_t directions_to_verify) { uint8_t active_channel_num_snk = 0; uint8_t active_channel_num_snk = 0; uint8_t active_channel_num_src = 0; uint8_t active_channel_num_src = 0; bool expected_active_ase = data.expected_active_channel_num_snk + if (directions_to_verify == 0) return false; data.expected_active_channel_num_src; if (data.device->HaveActiveAse() == 0) return false; ASSERT_EQ(expected_active_ase, data.device->HaveActiveAse()); for (ase* ase = data.device->GetFirstActiveAse(); ase; for (ase* ase = data.device->GetFirstActiveAse(); ase; ase = data.device->GetNextActiveAse(ase)) { ase = data.device->GetNextActiveAse(ase)) { Loading @@ -473,8 +477,17 @@ class LeAudioAseConfigurationTest : public Test { GetAudioChannelCounts(*ase->codec_config.audio_channel_allocation); GetAudioChannelCounts(*ase->codec_config.audio_channel_allocation); } } ASSERT_EQ(data.expected_active_channel_num_snk, active_channel_num_snk); bool result = true; ASSERT_EQ(data.expected_active_channel_num_src, active_channel_num_src); if (directions_to_verify & kLeAudioDirectionSink) { result &= (data.expected_active_channel_num_snk == active_channel_num_snk); } if (directions_to_verify & kLeAudioDirectionSource) { result &= (data.expected_active_channel_num_src == active_channel_num_src); } return result; } } void SetCisInformationToActiveAse(void) { void SetCisInformationToActiveAse(void) { Loading @@ -494,9 +507,12 @@ class LeAudioAseConfigurationTest : public Test { void TestSingleAseConfiguration(LeAudioContextType context_type, void TestSingleAseConfiguration(LeAudioContextType context_type, TestGroupAseConfigurationData* data, TestGroupAseConfigurationData* data, uint8_t data_size, uint8_t data_size, const AudioSetConfiguration* audio_set_conf) { const AudioSetConfiguration* audio_set_conf, uint8_t directions_to_verify) { // the configuration should fail if there are no active ases expected // the configuration should fail if there are no active ases expected bool success_expected = data_size > 0; bool success_expected = data_size > 0; uint8_t configuration_directions = 0; for (int i = 0; i < data_size; i++) { for (int i = 0; i < data_size; i++) { success_expected &= (data[i].expected_active_channel_num_snk + success_expected &= (data[i].expected_active_channel_num_snk + data[i].expected_active_channel_num_src) > 0; data[i].expected_active_channel_num_src) > 0; Loading @@ -505,8 +521,10 @@ class LeAudioAseConfigurationTest : public Test { PublishedAudioCapabilitiesBuilder snk_pac_builder, src_pac_builder; PublishedAudioCapabilitiesBuilder snk_pac_builder, src_pac_builder; for (const auto& entry : (*audio_set_conf).confs) { for (const auto& entry : (*audio_set_conf).confs) { if (entry.direction == kLeAudioDirectionSink) { if (entry.direction == kLeAudioDirectionSink) { configuration_directions |= kLeAudioDirectionSink; snk_pac_builder.Add(entry.codec, data[i].audio_channel_counts_snk); snk_pac_builder.Add(entry.codec, data[i].audio_channel_counts_snk); } else { } else { configuration_directions |= kLeAudioDirectionSource; src_pac_builder.Add(entry.codec, data[i].audio_channel_counts_src); src_pac_builder.Add(entry.codec, data[i].audio_channel_counts_src); } } } } Loading @@ -520,9 +538,12 @@ class LeAudioAseConfigurationTest : public Test { ASSERT_EQ(success_expected, ASSERT_EQ(success_expected, group_->Configure(context_type, AudioContexts(context_type))); group_->Configure(context_type, AudioContexts(context_type))); bool result = true; for (int i = 0; i < data_size; i++) { for (int i = 0; i < data_size; i++) { TestGroupAseConfigurationVerdict(data[i]); result &= TestGroupAseConfigurationVerdict( data[i], directions_to_verify & configuration_directions); } } ASSERT_TRUE(result); } } int getNumOfAses(LeAudioDevice* device, uint8_t direction) { int getNumOfAses(LeAudioDevice* device, uint8_t direction) { Loading @@ -531,17 +552,21 @@ class LeAudioAseConfigurationTest : public Test { [direction](auto& a) { return a.direction == direction; }); [direction](auto& a) { return a.direction == direction; }); } } void TestGroupAseConfiguration(LeAudioContextType context_type, void TestGroupAseConfiguration( TestGroupAseConfigurationData* data, LeAudioContextType context_type, TestGroupAseConfigurationData* data, uint8_t data_size) { uint8_t data_size, uint8_t directions_to_verify = kLeAudioDirectionSink | kLeAudioDirectionSource) { const auto* configurations = const auto* configurations = ::le_audio::AudioSetConfigurationProvider::Get()->GetConfigurations( ::le_audio::AudioSetConfigurationProvider::Get()->GetConfigurations( context_type); context_type); bool success_expected = directions_to_verify != 0; int num_of_matching_configurations = 0; int num_of_matching_configurations = 0; bool success_expected = data_size > 0; for (const auto& audio_set_conf : *configurations) { for (const auto& audio_set_conf : *configurations) { bool interesting_configuration = true; bool interesting_configuration = true; uint8_t configuration_directions = 0; // the configuration should fail if there are no active ases expected // the configuration should fail if there are no active ases expected PublishedAudioCapabilitiesBuilder snk_pac_builder, src_pac_builder; PublishedAudioCapabilitiesBuilder snk_pac_builder, src_pac_builder; snk_pac_builder.Reset(); snk_pac_builder.Reset(); Loading @@ -549,8 +574,6 @@ class LeAudioAseConfigurationTest : public Test { /* Let's go thru devices in the group and configure them*/ /* Let's go thru devices in the group and configure them*/ for (int i = 0; i < data_size; i++) { for (int i = 0; i < data_size; i++) { success_expected &= (data[i].expected_active_channel_num_snk + data[i].expected_active_channel_num_src) > 0; int num_of_ase_snk_per_dev = 0; int num_of_ase_snk_per_dev = 0; int num_of_ase_src_per_dev = 0; int num_of_ase_src_per_dev = 0; Loading @@ -565,10 +588,18 @@ class LeAudioAseConfigurationTest : public Test { interesting_configuration = false; interesting_configuration = false; } } /* Make sure the strategy is the expected one */ if (entry.direction == kLeAudioDirectionSink && group_->GetGroupStrategy() != entry.strategy) { interesting_configuration = false; } if (entry.direction == kLeAudioDirectionSink) { if (entry.direction == kLeAudioDirectionSink) { configuration_directions |= kLeAudioDirectionSink; num_of_ase_snk_per_dev = entry.ase_cnt / data_size; num_of_ase_snk_per_dev = entry.ase_cnt / data_size; snk_pac_builder.Add(entry.codec, data[i].audio_channel_counts_snk); snk_pac_builder.Add(entry.codec, data[i].audio_channel_counts_snk); } else { } else { configuration_directions |= kLeAudioDirectionSource; num_of_ase_src_per_dev = entry.ase_cnt / data_size; num_of_ase_src_per_dev = entry.ase_cnt / data_size; src_pac_builder.Add(entry.codec, data[i].audio_channel_counts_src); src_pac_builder.Add(entry.codec, data[i].audio_channel_counts_src); } } Loading @@ -578,11 +609,13 @@ class LeAudioAseConfigurationTest : public Test { } } /* Make sure configuration can satisfy number of expected active ASEs*/ /* Make sure configuration can satisfy number of expected active ASEs*/ if (num_of_ase_snk_per_dev != data[i].expected_active_channel_num_snk) { if (num_of_ase_snk_per_dev > data[i].device->GetAseCount(kLeAudioDirectionSink)) { interesting_configuration = false; interesting_configuration = false; } } if (num_of_ase_src_per_dev != data[i].expected_active_channel_num_src) { if (num_of_ase_src_per_dev > data[i].device->GetAseCount(kLeAudioDirectionSource)) { interesting_configuration = false; interesting_configuration = false; } } } } Loading @@ -593,13 +626,18 @@ class LeAudioAseConfigurationTest : public Test { /* In case of configuration #ase is same as the one we expected to be /* In case of configuration #ase is same as the one we expected to be * activated verify, ASEs are actually active */ * activated verify, ASEs are actually active */ if (interesting_configuration) { if (interesting_configuration && (directions_to_verify == configuration_directions)) { ASSERT_TRUE(configuration_result); ASSERT_TRUE(configuration_result); num_of_matching_configurations++; bool matching_conf = true; /* Check if each of the devices has activated ASEs as expected */ /* Check if each of the devices has activated ASEs as expected */ for (int i = 0; i < data_size; i++) { for (int i = 0; i < data_size; i++) { TestGroupAseConfigurationVerdict(data[i]); matching_conf &= TestGroupAseConfigurationVerdict( data[i], configuration_directions); } } if (matching_conf) num_of_matching_configurations++; } } group_->Deactivate(); group_->Deactivate(); TestAsesInactive(); TestAsesInactive(); Loading Loading @@ -681,9 +719,11 @@ class LeAudioAseConfigurationTest : public Test { uint16_t octets_per_frame = GetOctetsPerCodecFrame(opcf_variant); uint16_t octets_per_frame = GetOctetsPerCodecFrame(opcf_variant); PublishedAudioCapabilitiesBuilder pac_builder; PublishedAudioCapabilitiesBuilder pac_builder; pac_builder.Add( pac_builder.Add(LeAudioCodecIdLc3, sampling_frequency, LeAudioCodecIdLc3, sampling_frequency, frame_duration, frame_duration, kLeAudioCodecLC3ChannelCountSingleChannel, octets_per_frame); kLeAudioCodecLC3ChannelCountSingleChannel | kLeAudioCodecLC3ChannelCountTwoChannel, octets_per_frame); for (auto& device : devices_) { for (auto& device : devices_) { /* For simplicity configure both PACs with the same /* For simplicity configure both PACs with the same parameters*/ parameters*/ Loading Loading @@ -731,16 +771,31 @@ TEST_F(LeAudioAseConfigurationTest, test_mono_speaker_ringtone) { {mono_speaker, kLeAudioCodecLC3ChannelCountSingleChannel, {mono_speaker, kLeAudioCodecLC3ChannelCountSingleChannel, kLeAudioCodecLC3ChannelCountSingleChannel, 1, 0}); kLeAudioCodecLC3ChannelCountSingleChannel, 1, 0}); TestGroupAseConfiguration(LeAudioContextType::RINGTONE, &data, 1); /* mono, change location as by default it is stereo */ mono_speaker->snk_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; group_->ReloadAudioLocations(); uint8_t direction_to_verify = kLeAudioDirectionSink; TestGroupAseConfiguration(LeAudioContextType::RINGTONE, &data, 1, direction_to_verify); } } TEST_F(LeAudioAseConfigurationTest, test_mono_speaker_conversational) { TEST_F(LeAudioAseConfigurationTest, test_mono_speaker_conversational) { LeAudioDevice* mono_speaker = AddTestDevice(1, 0); LeAudioDevice* mono_speaker = AddTestDevice(1, 0); TestGroupAseConfigurationData data({mono_speaker, TestGroupAseConfigurationData data({mono_speaker, kLeAudioCodecLC3ChannelCountSingleChannel, kLeAudioCodecLC3ChannelCountSingleChannel, kLeAudioCodecLC3ChannelCountNone, 0, 0}); kLeAudioCodecLC3ChannelCountNone, 1, 0}); TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, &data, 1); /* mono, change location as by default it is stereo */ mono_speaker->snk_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; group_->ReloadAudioLocations(); /* Microphone should be used on the phone */ uint8_t direction_to_verify = kLeAudioDirectionSink; TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, &data, 1, direction_to_verify); } } TEST_F(LeAudioAseConfigurationTest, test_mono_speaker_media) { TEST_F(LeAudioAseConfigurationTest, test_mono_speaker_media) { Loading @@ -749,7 +804,14 @@ TEST_F(LeAudioAseConfigurationTest, test_mono_speaker_media) { kLeAudioCodecLC3ChannelCountSingleChannel, kLeAudioCodecLC3ChannelCountSingleChannel, kLeAudioCodecLC3ChannelCountNone, 1, 0}); kLeAudioCodecLC3ChannelCountNone, 1, 0}); TestGroupAseConfiguration(LeAudioContextType::MEDIA, &data, 1); /* mono, change location as by default it is stereo */ mono_speaker->snk_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; group_->ReloadAudioLocations(); uint8_t direction_to_verify = kLeAudioDirectionSink; TestGroupAseConfiguration(LeAudioContextType::MEDIA, &data, 1, direction_to_verify); } } TEST_F(LeAudioAseConfigurationTest, test_bounded_headphones_ringtone) { TEST_F(LeAudioAseConfigurationTest, test_bounded_headphones_ringtone) { Loading @@ -758,16 +820,20 @@ TEST_F(LeAudioAseConfigurationTest, test_bounded_headphones_ringtone) { {bounded_headphones, kLeAudioCodecLC3ChannelCountTwoChannel, {bounded_headphones, kLeAudioCodecLC3ChannelCountTwoChannel, kLeAudioCodecLC3ChannelCountSingleChannel, 2, 0}); kLeAudioCodecLC3ChannelCountSingleChannel, 2, 0}); TestGroupAseConfiguration(LeAudioContextType::RINGTONE, &data, 1); uint8_t direction_to_verify = kLeAudioDirectionSink; TestGroupAseConfiguration(LeAudioContextType::RINGTONE, &data, 1, direction_to_verify); } } TEST_F(LeAudioAseConfigurationTest, test_bounded_headphones_conversional) { TEST_F(LeAudioAseConfigurationTest, test_bounded_headphones_conversional) { LeAudioDevice* bounded_headphones = AddTestDevice(2, 0); LeAudioDevice* bounded_headphones = AddTestDevice(2, 0); TestGroupAseConfigurationData data({bounded_headphones, TestGroupAseConfigurationData data({bounded_headphones, kLeAudioCodecLC3ChannelCountTwoChannel, kLeAudioCodecLC3ChannelCountTwoChannel, kLeAudioCodecLC3ChannelCountNone, 0, 0}); kLeAudioCodecLC3ChannelCountNone, 2, 0}); TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, &data, 1); uint8_t direction_to_verify = kLeAudioDirectionSink; TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, &data, 1, direction_to_verify); } } TEST_F(LeAudioAseConfigurationTest, test_bounded_headphones_media) { TEST_F(LeAudioAseConfigurationTest, test_bounded_headphones_media) { Loading @@ -776,15 +842,37 @@ TEST_F(LeAudioAseConfigurationTest, test_bounded_headphones_media) { kLeAudioCodecLC3ChannelCountTwoChannel, kLeAudioCodecLC3ChannelCountTwoChannel, kLeAudioCodecLC3ChannelCountNone, 2, 0}); kLeAudioCodecLC3ChannelCountNone, 2, 0}); TestGroupAseConfiguration(LeAudioContextType::MEDIA, &data, 1); uint8_t direction_to_verify = kLeAudioDirectionSink; TestGroupAseConfiguration(LeAudioContextType::MEDIA, &data, 1, direction_to_verify); } } TEST_F(LeAudioAseConfigurationTest, test_bounded_headset_ringtone) { TEST_F(LeAudioAseConfigurationTest, test_bounded_headset_ringtone_mono_microphone) { LeAudioDevice* bounded_headset = AddTestDevice(2, 1); LeAudioDevice* bounded_headset = AddTestDevice(2, 1); TestGroupAseConfigurationData data( TestGroupAseConfigurationData data( {bounded_headset, kLeAudioCodecLC3ChannelCountTwoChannel, {bounded_headset, kLeAudioCodecLC3ChannelCountTwoChannel, kLeAudioCodecLC3ChannelCountSingleChannel, 2, 1}); kLeAudioCodecLC3ChannelCountSingleChannel, 2, 1}); /* mono, change location as by default it is stereo */ bounded_headset->src_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; group_->ReloadAudioLocations(); TestGroupAseConfiguration(LeAudioContextType::RINGTONE, &data, 1); } TEST_F(LeAudioAseConfigurationTest, test_bounded_headset_ringtone_stereo_microphone) { LeAudioDevice* bounded_headset = AddTestDevice(2, 2); TestGroupAseConfigurationData data( {bounded_headset, kLeAudioCodecLC3ChannelCountSingleChannel | kLeAudioCodecLC3ChannelCountTwoChannel, kLeAudioCodecLC3ChannelCountSingleChannel | kLeAudioCodecLC3ChannelCountTwoChannel, 2, 2}); TestGroupAseConfiguration(LeAudioContextType::RINGTONE, &data, 1); TestGroupAseConfiguration(LeAudioContextType::RINGTONE, &data, 1); } } Loading @@ -803,7 +891,9 @@ TEST_F(LeAudioAseConfigurationTest, test_bounded_headset_media) { {bounded_headset, kLeAudioCodecLC3ChannelCountTwoChannel, {bounded_headset, kLeAudioCodecLC3ChannelCountTwoChannel, kLeAudioCodecLC3ChannelCountSingleChannel, 2, 0}); kLeAudioCodecLC3ChannelCountSingleChannel, 2, 0}); TestGroupAseConfiguration(LeAudioContextType::MEDIA, &data, 1); uint8_t directions_to_verify = kLeAudioDirectionSink; TestGroupAseConfiguration(LeAudioContextType::MEDIA, &data, 1, directions_to_verify); } } TEST_F(LeAudioAseConfigurationTest, test_earbuds_ringtone) { TEST_F(LeAudioAseConfigurationTest, test_earbuds_ringtone) { Loading @@ -815,6 +905,17 @@ TEST_F(LeAudioAseConfigurationTest, test_earbuds_ringtone) { {right, kLeAudioCodecLC3ChannelCountSingleChannel, {right, kLeAudioCodecLC3ChannelCountSingleChannel, kLeAudioCodecLC3ChannelCountSingleChannel, 1, 1}}; kLeAudioCodecLC3ChannelCountSingleChannel, 1, 1}}; /* Change location as by default it is stereo */ left->snk_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; left->src_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; right->snk_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight; right->src_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight; group_->ReloadAudioLocations(); TestGroupAseConfiguration(LeAudioContextType::RINGTONE, data, 2); TestGroupAseConfiguration(LeAudioContextType::RINGTONE, data, 2); } } Loading @@ -827,6 +928,17 @@ TEST_F(LeAudioAseConfigurationTest, test_earbuds_conversional) { {right, kLeAudioCodecLC3ChannelCountSingleChannel, {right, kLeAudioCodecLC3ChannelCountSingleChannel, kLeAudioCodecLC3ChannelCountSingleChannel, 1, 1}}; kLeAudioCodecLC3ChannelCountSingleChannel, 1, 1}}; /* Change location as by default it is stereo */ left->snk_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; left->src_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; right->snk_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight; right->src_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight; group_->ReloadAudioLocations(); TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, data, 2); TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, data, 2); } } Loading @@ -839,32 +951,81 @@ TEST_F(LeAudioAseConfigurationTest, test_earbuds_media) { {right, kLeAudioCodecLC3ChannelCountSingleChannel, {right, kLeAudioCodecLC3ChannelCountSingleChannel, kLeAudioCodecLC3ChannelCountSingleChannel, 1, 0}}; kLeAudioCodecLC3ChannelCountSingleChannel, 1, 0}}; TestGroupAseConfiguration(LeAudioContextType::MEDIA, data, 2); /* Change location as by default it is stereo */ left->snk_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; left->src_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; right->snk_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight; right->src_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight; group_->ReloadAudioLocations(); uint8_t directions_to_verify = kLeAudioDirectionSink; TestGroupAseConfiguration(LeAudioContextType::MEDIA, data, 2, directions_to_verify); } } TEST_F(LeAudioAseConfigurationTest, test_handsfree_ringtone) { TEST_F(LeAudioAseConfigurationTest, test_handsfree_mono_ringtone) { LeAudioDevice* handsfree = AddTestDevice(1, 1); LeAudioDevice* handsfree = AddTestDevice(1, 1); TestGroupAseConfigurationData data( TestGroupAseConfigurationData data( {handsfree, kLeAudioCodecLC3ChannelCountSingleChannel, {handsfree, kLeAudioCodecLC3ChannelCountSingleChannel, kLeAudioCodecLC3ChannelCountSingleChannel, 1, 1}); kLeAudioCodecLC3ChannelCountSingleChannel, 1, 1}); handsfree->snk_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; handsfree->src_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; group_->ReloadAudioLocations(); TestGroupAseConfiguration(LeAudioContextType::RINGTONE, &data, 1); } TEST_F(LeAudioAseConfigurationTest, test_handsfree_stereo_ringtone) { LeAudioDevice* handsfree = AddTestDevice(1, 1); TestGroupAseConfigurationData data( {handsfree, kLeAudioCodecLC3ChannelCountSingleChannel | kLeAudioCodecLC3ChannelCountTwoChannel, kLeAudioCodecLC3ChannelCountSingleChannel, 2, 1}); TestGroupAseConfiguration(LeAudioContextType::RINGTONE, &data, 1); TestGroupAseConfiguration(LeAudioContextType::RINGTONE, &data, 1); } } TEST_F(LeAudioAseConfigurationTest, test_handsfree_conversional) { TEST_F(LeAudioAseConfigurationTest, test_handsfree_mono_conversional) { LeAudioDevice* handsfree = AddTestDevice(1, 1); LeAudioDevice* handsfree = AddTestDevice(1, 1); TestGroupAseConfigurationData data( TestGroupAseConfigurationData data( {handsfree, kLeAudioCodecLC3ChannelCountSingleChannel, {handsfree, kLeAudioCodecLC3ChannelCountSingleChannel, kLeAudioCodecLC3ChannelCountSingleChannel, 1, 1}); kLeAudioCodecLC3ChannelCountSingleChannel, 1, 1}); handsfree->snk_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; handsfree->src_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; group_->ReloadAudioLocations(); TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, &data, 1); } TEST_F(LeAudioAseConfigurationTest, test_handsfree_stereo_conversional) { LeAudioDevice* handsfree = AddTestDevice(1, 1); TestGroupAseConfigurationData data( {handsfree, kLeAudioCodecLC3ChannelCountSingleChannel | kLeAudioCodecLC3ChannelCountTwoChannel, kLeAudioCodecLC3ChannelCountSingleChannel, 2, 1}); TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, &data, 1); TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, &data, 1); } } TEST_F(LeAudioAseConfigurationTest, test_handsfree_full_cached_conversional) { TEST_F(LeAudioAseConfigurationTest, test_handsfree_full_cached_conversional) { LeAudioDevice* handsfree = AddTestDevice(0, 0, 1, 1); LeAudioDevice* handsfree = AddTestDevice(0, 0, 1, 1); TestGroupAseConfigurationData data( TestGroupAseConfigurationData data( {handsfree, kLeAudioCodecLC3ChannelCountSingleChannel, {handsfree, kLeAudioCodecLC3ChannelCountSingleChannel, 1, 1}); kLeAudioCodecLC3ChannelCountSingleChannel | kLeAudioCodecLC3ChannelCountTwoChannel, kLeAudioCodecLC3ChannelCountSingleChannel, 2, 1}); TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, &data, 1); TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, &data, 1); } } Loading @@ -873,19 +1034,26 @@ TEST_F(LeAudioAseConfigurationTest, test_handsfree_partial_cached_conversional) { test_handsfree_partial_cached_conversional) { LeAudioDevice* handsfree = AddTestDevice(1, 0, 0, 1); LeAudioDevice* handsfree = AddTestDevice(1, 0, 0, 1); TestGroupAseConfigurationData data( TestGroupAseConfigurationData data( {handsfree, kLeAudioCodecLC3ChannelCountSingleChannel, {handsfree, kLeAudioCodecLC3ChannelCountSingleChannel, 1, 1}); kLeAudioCodecLC3ChannelCountSingleChannel | kLeAudioCodecLC3ChannelCountTwoChannel, kLeAudioCodecLC3ChannelCountSingleChannel, 2, 1}); TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, &data, 1); TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, &data, 1); } } TEST_F(LeAudioAseConfigurationTest, test_handsfree_media) { TEST_F(LeAudioAseConfigurationTest, test_handsfree_media_two_channels_allocation_stereo) { LeAudioDevice* handsfree = AddTestDevice(1, 1); LeAudioDevice* handsfree = AddTestDevice(1, 1); TestGroupAseConfigurationData data( TestGroupAseConfigurationData data( {handsfree, kLeAudioCodecLC3ChannelCountSingleChannel, {handsfree, kLeAudioCodecLC3ChannelCountSingleChannel, 1, 0}); kLeAudioCodecLC3ChannelCountSingleChannel | kLeAudioCodecLC3ChannelCountTwoChannel, kLeAudioCodecLC3ChannelCountSingleChannel, 2, 0}); TestGroupAseConfiguration(LeAudioContextType::MEDIA, &data, 1); uint8_t directions_to_verify = kLeAudioDirectionSink; TestGroupAseConfiguration(LeAudioContextType::MEDIA, &data, 1, directions_to_verify); } } TEST_F(LeAudioAseConfigurationTest, test_lc3_config_ringtone) { TEST_F(LeAudioAseConfigurationTest, test_lc3_config_ringtone) { Loading @@ -901,7 +1069,7 @@ TEST_F(LeAudioAseConfigurationTest, test_lc3_config_conversional) { } } TEST_F(LeAudioAseConfigurationTest, test_lc3_config_media) { TEST_F(LeAudioAseConfigurationTest, test_lc3_config_media) { AddTestDevice(1, 0); AddTestDevice(1, 1); TestLc3CodecConfig(LeAudioContextType::MEDIA); TestLc3CodecConfig(LeAudioContextType::MEDIA); } } Loading Loading @@ -934,6 +1102,17 @@ TEST_F(LeAudioAseConfigurationTest, test_reconnection_media) { LeAudioDevice* left = AddTestDevice(2, 1); LeAudioDevice* left = AddTestDevice(2, 1); LeAudioDevice* right = AddTestDevice(2, 1); LeAudioDevice* right = AddTestDevice(2, 1); /* Change location as by default it is stereo */ left->snk_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; left->src_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; right->snk_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight; right->src_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight; group_->ReloadAudioLocations(); TestGroupAseConfigurationData data[] = { TestGroupAseConfigurationData data[] = { {left, kLeAudioCodecLC3ChannelCountSingleChannel, {left, kLeAudioCodecLC3ChannelCountSingleChannel, kLeAudioCodecLC3ChannelCountSingleChannel, 1, 0}, kLeAudioCodecLC3ChannelCountSingleChannel, 1, 0}, Loading @@ -947,7 +1126,9 @@ TEST_F(LeAudioAseConfigurationTest, test_reconnection_media) { ASSERT_NE(all_configurations->end(), all_configurations->begin()); ASSERT_NE(all_configurations->end(), all_configurations->begin()); auto configuration = *all_configurations->begin(); auto configuration = *all_configurations->begin(); TestSingleAseConfiguration(LeAudioContextType::MEDIA, data, 2, configuration); uint8_t direction_to_verify = kLeAudioDirectionSink; TestSingleAseConfiguration(LeAudioContextType::MEDIA, data, 2, configuration, direction_to_verify); /* Generate CISes, symulate CIG creation and assign cis handles to ASEs.*/ /* Generate CISes, symulate CIG creation and assign cis handles to ASEs.*/ group_->CigGenerateCisIds(LeAudioContextType::MEDIA); group_->CigGenerateCisIds(LeAudioContextType::MEDIA); Loading Loading @@ -987,8 +1168,9 @@ TEST_F(LeAudioAseConfigurationTest, test_reconnection_media) { ASSERT_TRUE(number_of_active_ases == 2); ASSERT_TRUE(number_of_active_ases == 2); ASSERT_TRUE(group_snk_audio_location == kChannelAllocationStereo); ASSERT_TRUE(group_snk_audio_location == kChannelAllocationStereo); uint8_t directions_to_verify = ::le_audio::types::kLeAudioDirectionSink; for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) { TestGroupAseConfigurationVerdict(data[i]); TestGroupAseConfigurationVerdict(data[i], directions_to_verify); } } /* Before device is rejoining, and group already exist, cis handles are /* Before device is rejoining, and group already exist, cis handles are Loading Loading
system/bta/le_audio/devices.cc +10 −0 Original line number Original line Diff line number Diff line Loading @@ -1235,6 +1235,8 @@ bool LeAudioDeviceGroup::IsConfigurationSupported( return false; return false; } } auto required_snk_strategy = GetGroupStrategy(); /* TODO For now: set ase if matching with first pac. /* TODO For now: set ase if matching with first pac. * 1) We assume as well that devices will match requirements in order * 1) We assume as well that devices will match requirements in order * e.g. 1 Device - 1 Requirement, 2 Device - 2 Requirement etc. * e.g. 1 Device - 1 Requirement, 2 Device - 2 Requirement etc. Loading @@ -1259,6 +1261,14 @@ bool LeAudioDeviceGroup::IsConfigurationSupported( +required_device_cnt, +ent.ase_cnt, +max_required_ase_per_dev, +required_device_cnt, +ent.ase_cnt, +max_required_ase_per_dev, static_cast<int>(strategy)); static_cast<int>(strategy)); if (ent.direction == types::kLeAudioDirectionSink && strategy != required_snk_strategy) { LOG_INFO(" Sink strategy mismatch (%d!=%d)", static_cast<int>(required_snk_strategy), static_cast<int>(strategy)); return false; } for (auto* device = GetFirstDeviceWithActiveContext(context_type); for (auto* device = GetFirstDeviceWithActiveContext(context_type); device != nullptr && required_device_cnt > 0; device != nullptr && required_device_cnt > 0; device = GetNextDeviceWithActiveContext(device, context_type)) { device = GetNextDeviceWithActiveContext(device, context_type)) { Loading
system/bta/le_audio/devices_test.cc +234 −52 Original line number Original line Diff line number Diff line Loading @@ -218,7 +218,6 @@ bool IsLc3SettingSupported(LeAudioContextType context_type, Lc3SettingId id) { case LeAudioContextType::EMERGENCYALARM: case LeAudioContextType::EMERGENCYALARM: case LeAudioContextType::UNSPECIFIED: case LeAudioContextType::UNSPECIFIED: if (id == Lc3SettingId::LC3_16_1 || id == Lc3SettingId::LC3_16_2 || if (id == Lc3SettingId::LC3_16_1 || id == Lc3SettingId::LC3_16_2 || id == Lc3SettingId::LC3_32_1 || id == Lc3SettingId::LC3_32_2 || id == Lc3SettingId::LC3_48_4 || id == Lc3SettingId::LC3_48_2 || id == Lc3SettingId::LC3_48_4 || id == Lc3SettingId::LC3_48_2 || id == Lc3SettingId::LC3_VND_1 || id == Lc3SettingId::LC3_24_2) id == Lc3SettingId::LC3_VND_1 || id == Lc3SettingId::LC3_24_2) return true; return true; Loading Loading @@ -388,6 +387,7 @@ struct TestGroupAseConfigurationData { uint8_t audio_channel_counts_snk; uint8_t audio_channel_counts_snk; uint8_t audio_channel_counts_src; uint8_t audio_channel_counts_src; /* Note, do not confuse ASEs with channels num. */ uint8_t expected_active_channel_num_snk; uint8_t expected_active_channel_num_snk; uint8_t expected_active_channel_num_src; uint8_t expected_active_channel_num_src; }; }; Loading Loading @@ -418,22 +418,25 @@ class LeAudioAseConfigurationTest : public Test { devices_.push_back(device); devices_.push_back(device); group_->AddNode(device); group_->AddNode(device); int ase_id = 1; for (int i = 0; i < src_ase_num; i++) { for (int i = 0; i < src_ase_num; i++) { device->ases_.emplace_back(0x0000, 0x0000, kLeAudioDirectionSource); device->ases_.emplace_back(0x0000, 0x0000, kLeAudioDirectionSource, ase_id++); } } for (int i = 0; i < snk_ase_num; i++) { for (int i = 0; i < snk_ase_num; i++) { device->ases_.emplace_back(0x0000, 0x0000, kLeAudioDirectionSink); device->ases_.emplace_back(0x0000, 0x0000, kLeAudioDirectionSink, ase_id++); } } for (int i = 0; i < src_ase_num_cached; i++) { for (int i = 0; i < src_ase_num_cached; i++) { struct ase ase(0x0000, 0x0000, kLeAudioDirectionSource); struct ase ase(0x0000, 0x0000, kLeAudioDirectionSource, ase_id++); ase.state = AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED; ase.state = AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED; device->ases_.push_back(ase); device->ases_.push_back(ase); } } for (int i = 0; i < snk_ase_num_cached; i++) { for (int i = 0; i < snk_ase_num_cached; i++) { struct ase ase(0x0000, 0x0000, kLeAudioDirectionSink); struct ase ase(0x0000, 0x0000, kLeAudioDirectionSink, ase_id++); ase.state = AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED; ase.state = AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED; device->ases_.push_back(ase); device->ases_.push_back(ase); } } Loading @@ -451,17 +454,18 @@ class LeAudioAseConfigurationTest : public Test { device->conn_id_ = index; device->conn_id_ = index; device->SetConnectionState(DeviceConnectState::CONNECTED); device->SetConnectionState(DeviceConnectState::CONNECTED); group_->ReloadAudioDirections(); group_->ReloadAudioLocations(); return device.get(); return device.get(); } } void TestGroupAseConfigurationVerdict( bool TestGroupAseConfigurationVerdict( const TestGroupAseConfigurationData& data) { const TestGroupAseConfigurationData& data, uint8_t directions_to_verify) { uint8_t active_channel_num_snk = 0; uint8_t active_channel_num_snk = 0; uint8_t active_channel_num_src = 0; uint8_t active_channel_num_src = 0; bool expected_active_ase = data.expected_active_channel_num_snk + if (directions_to_verify == 0) return false; data.expected_active_channel_num_src; if (data.device->HaveActiveAse() == 0) return false; ASSERT_EQ(expected_active_ase, data.device->HaveActiveAse()); for (ase* ase = data.device->GetFirstActiveAse(); ase; for (ase* ase = data.device->GetFirstActiveAse(); ase; ase = data.device->GetNextActiveAse(ase)) { ase = data.device->GetNextActiveAse(ase)) { Loading @@ -473,8 +477,17 @@ class LeAudioAseConfigurationTest : public Test { GetAudioChannelCounts(*ase->codec_config.audio_channel_allocation); GetAudioChannelCounts(*ase->codec_config.audio_channel_allocation); } } ASSERT_EQ(data.expected_active_channel_num_snk, active_channel_num_snk); bool result = true; ASSERT_EQ(data.expected_active_channel_num_src, active_channel_num_src); if (directions_to_verify & kLeAudioDirectionSink) { result &= (data.expected_active_channel_num_snk == active_channel_num_snk); } if (directions_to_verify & kLeAudioDirectionSource) { result &= (data.expected_active_channel_num_src == active_channel_num_src); } return result; } } void SetCisInformationToActiveAse(void) { void SetCisInformationToActiveAse(void) { Loading @@ -494,9 +507,12 @@ class LeAudioAseConfigurationTest : public Test { void TestSingleAseConfiguration(LeAudioContextType context_type, void TestSingleAseConfiguration(LeAudioContextType context_type, TestGroupAseConfigurationData* data, TestGroupAseConfigurationData* data, uint8_t data_size, uint8_t data_size, const AudioSetConfiguration* audio_set_conf) { const AudioSetConfiguration* audio_set_conf, uint8_t directions_to_verify) { // the configuration should fail if there are no active ases expected // the configuration should fail if there are no active ases expected bool success_expected = data_size > 0; bool success_expected = data_size > 0; uint8_t configuration_directions = 0; for (int i = 0; i < data_size; i++) { for (int i = 0; i < data_size; i++) { success_expected &= (data[i].expected_active_channel_num_snk + success_expected &= (data[i].expected_active_channel_num_snk + data[i].expected_active_channel_num_src) > 0; data[i].expected_active_channel_num_src) > 0; Loading @@ -505,8 +521,10 @@ class LeAudioAseConfigurationTest : public Test { PublishedAudioCapabilitiesBuilder snk_pac_builder, src_pac_builder; PublishedAudioCapabilitiesBuilder snk_pac_builder, src_pac_builder; for (const auto& entry : (*audio_set_conf).confs) { for (const auto& entry : (*audio_set_conf).confs) { if (entry.direction == kLeAudioDirectionSink) { if (entry.direction == kLeAudioDirectionSink) { configuration_directions |= kLeAudioDirectionSink; snk_pac_builder.Add(entry.codec, data[i].audio_channel_counts_snk); snk_pac_builder.Add(entry.codec, data[i].audio_channel_counts_snk); } else { } else { configuration_directions |= kLeAudioDirectionSource; src_pac_builder.Add(entry.codec, data[i].audio_channel_counts_src); src_pac_builder.Add(entry.codec, data[i].audio_channel_counts_src); } } } } Loading @@ -520,9 +538,12 @@ class LeAudioAseConfigurationTest : public Test { ASSERT_EQ(success_expected, ASSERT_EQ(success_expected, group_->Configure(context_type, AudioContexts(context_type))); group_->Configure(context_type, AudioContexts(context_type))); bool result = true; for (int i = 0; i < data_size; i++) { for (int i = 0; i < data_size; i++) { TestGroupAseConfigurationVerdict(data[i]); result &= TestGroupAseConfigurationVerdict( data[i], directions_to_verify & configuration_directions); } } ASSERT_TRUE(result); } } int getNumOfAses(LeAudioDevice* device, uint8_t direction) { int getNumOfAses(LeAudioDevice* device, uint8_t direction) { Loading @@ -531,17 +552,21 @@ class LeAudioAseConfigurationTest : public Test { [direction](auto& a) { return a.direction == direction; }); [direction](auto& a) { return a.direction == direction; }); } } void TestGroupAseConfiguration(LeAudioContextType context_type, void TestGroupAseConfiguration( TestGroupAseConfigurationData* data, LeAudioContextType context_type, TestGroupAseConfigurationData* data, uint8_t data_size) { uint8_t data_size, uint8_t directions_to_verify = kLeAudioDirectionSink | kLeAudioDirectionSource) { const auto* configurations = const auto* configurations = ::le_audio::AudioSetConfigurationProvider::Get()->GetConfigurations( ::le_audio::AudioSetConfigurationProvider::Get()->GetConfigurations( context_type); context_type); bool success_expected = directions_to_verify != 0; int num_of_matching_configurations = 0; int num_of_matching_configurations = 0; bool success_expected = data_size > 0; for (const auto& audio_set_conf : *configurations) { for (const auto& audio_set_conf : *configurations) { bool interesting_configuration = true; bool interesting_configuration = true; uint8_t configuration_directions = 0; // the configuration should fail if there are no active ases expected // the configuration should fail if there are no active ases expected PublishedAudioCapabilitiesBuilder snk_pac_builder, src_pac_builder; PublishedAudioCapabilitiesBuilder snk_pac_builder, src_pac_builder; snk_pac_builder.Reset(); snk_pac_builder.Reset(); Loading @@ -549,8 +574,6 @@ class LeAudioAseConfigurationTest : public Test { /* Let's go thru devices in the group and configure them*/ /* Let's go thru devices in the group and configure them*/ for (int i = 0; i < data_size; i++) { for (int i = 0; i < data_size; i++) { success_expected &= (data[i].expected_active_channel_num_snk + data[i].expected_active_channel_num_src) > 0; int num_of_ase_snk_per_dev = 0; int num_of_ase_snk_per_dev = 0; int num_of_ase_src_per_dev = 0; int num_of_ase_src_per_dev = 0; Loading @@ -565,10 +588,18 @@ class LeAudioAseConfigurationTest : public Test { interesting_configuration = false; interesting_configuration = false; } } /* Make sure the strategy is the expected one */ if (entry.direction == kLeAudioDirectionSink && group_->GetGroupStrategy() != entry.strategy) { interesting_configuration = false; } if (entry.direction == kLeAudioDirectionSink) { if (entry.direction == kLeAudioDirectionSink) { configuration_directions |= kLeAudioDirectionSink; num_of_ase_snk_per_dev = entry.ase_cnt / data_size; num_of_ase_snk_per_dev = entry.ase_cnt / data_size; snk_pac_builder.Add(entry.codec, data[i].audio_channel_counts_snk); snk_pac_builder.Add(entry.codec, data[i].audio_channel_counts_snk); } else { } else { configuration_directions |= kLeAudioDirectionSource; num_of_ase_src_per_dev = entry.ase_cnt / data_size; num_of_ase_src_per_dev = entry.ase_cnt / data_size; src_pac_builder.Add(entry.codec, data[i].audio_channel_counts_src); src_pac_builder.Add(entry.codec, data[i].audio_channel_counts_src); } } Loading @@ -578,11 +609,13 @@ class LeAudioAseConfigurationTest : public Test { } } /* Make sure configuration can satisfy number of expected active ASEs*/ /* Make sure configuration can satisfy number of expected active ASEs*/ if (num_of_ase_snk_per_dev != data[i].expected_active_channel_num_snk) { if (num_of_ase_snk_per_dev > data[i].device->GetAseCount(kLeAudioDirectionSink)) { interesting_configuration = false; interesting_configuration = false; } } if (num_of_ase_src_per_dev != data[i].expected_active_channel_num_src) { if (num_of_ase_src_per_dev > data[i].device->GetAseCount(kLeAudioDirectionSource)) { interesting_configuration = false; interesting_configuration = false; } } } } Loading @@ -593,13 +626,18 @@ class LeAudioAseConfigurationTest : public Test { /* In case of configuration #ase is same as the one we expected to be /* In case of configuration #ase is same as the one we expected to be * activated verify, ASEs are actually active */ * activated verify, ASEs are actually active */ if (interesting_configuration) { if (interesting_configuration && (directions_to_verify == configuration_directions)) { ASSERT_TRUE(configuration_result); ASSERT_TRUE(configuration_result); num_of_matching_configurations++; bool matching_conf = true; /* Check if each of the devices has activated ASEs as expected */ /* Check if each of the devices has activated ASEs as expected */ for (int i = 0; i < data_size; i++) { for (int i = 0; i < data_size; i++) { TestGroupAseConfigurationVerdict(data[i]); matching_conf &= TestGroupAseConfigurationVerdict( data[i], configuration_directions); } } if (matching_conf) num_of_matching_configurations++; } } group_->Deactivate(); group_->Deactivate(); TestAsesInactive(); TestAsesInactive(); Loading Loading @@ -681,9 +719,11 @@ class LeAudioAseConfigurationTest : public Test { uint16_t octets_per_frame = GetOctetsPerCodecFrame(opcf_variant); uint16_t octets_per_frame = GetOctetsPerCodecFrame(opcf_variant); PublishedAudioCapabilitiesBuilder pac_builder; PublishedAudioCapabilitiesBuilder pac_builder; pac_builder.Add( pac_builder.Add(LeAudioCodecIdLc3, sampling_frequency, LeAudioCodecIdLc3, sampling_frequency, frame_duration, frame_duration, kLeAudioCodecLC3ChannelCountSingleChannel, octets_per_frame); kLeAudioCodecLC3ChannelCountSingleChannel | kLeAudioCodecLC3ChannelCountTwoChannel, octets_per_frame); for (auto& device : devices_) { for (auto& device : devices_) { /* For simplicity configure both PACs with the same /* For simplicity configure both PACs with the same parameters*/ parameters*/ Loading Loading @@ -731,16 +771,31 @@ TEST_F(LeAudioAseConfigurationTest, test_mono_speaker_ringtone) { {mono_speaker, kLeAudioCodecLC3ChannelCountSingleChannel, {mono_speaker, kLeAudioCodecLC3ChannelCountSingleChannel, kLeAudioCodecLC3ChannelCountSingleChannel, 1, 0}); kLeAudioCodecLC3ChannelCountSingleChannel, 1, 0}); TestGroupAseConfiguration(LeAudioContextType::RINGTONE, &data, 1); /* mono, change location as by default it is stereo */ mono_speaker->snk_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; group_->ReloadAudioLocations(); uint8_t direction_to_verify = kLeAudioDirectionSink; TestGroupAseConfiguration(LeAudioContextType::RINGTONE, &data, 1, direction_to_verify); } } TEST_F(LeAudioAseConfigurationTest, test_mono_speaker_conversational) { TEST_F(LeAudioAseConfigurationTest, test_mono_speaker_conversational) { LeAudioDevice* mono_speaker = AddTestDevice(1, 0); LeAudioDevice* mono_speaker = AddTestDevice(1, 0); TestGroupAseConfigurationData data({mono_speaker, TestGroupAseConfigurationData data({mono_speaker, kLeAudioCodecLC3ChannelCountSingleChannel, kLeAudioCodecLC3ChannelCountSingleChannel, kLeAudioCodecLC3ChannelCountNone, 0, 0}); kLeAudioCodecLC3ChannelCountNone, 1, 0}); TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, &data, 1); /* mono, change location as by default it is stereo */ mono_speaker->snk_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; group_->ReloadAudioLocations(); /* Microphone should be used on the phone */ uint8_t direction_to_verify = kLeAudioDirectionSink; TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, &data, 1, direction_to_verify); } } TEST_F(LeAudioAseConfigurationTest, test_mono_speaker_media) { TEST_F(LeAudioAseConfigurationTest, test_mono_speaker_media) { Loading @@ -749,7 +804,14 @@ TEST_F(LeAudioAseConfigurationTest, test_mono_speaker_media) { kLeAudioCodecLC3ChannelCountSingleChannel, kLeAudioCodecLC3ChannelCountSingleChannel, kLeAudioCodecLC3ChannelCountNone, 1, 0}); kLeAudioCodecLC3ChannelCountNone, 1, 0}); TestGroupAseConfiguration(LeAudioContextType::MEDIA, &data, 1); /* mono, change location as by default it is stereo */ mono_speaker->snk_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; group_->ReloadAudioLocations(); uint8_t direction_to_verify = kLeAudioDirectionSink; TestGroupAseConfiguration(LeAudioContextType::MEDIA, &data, 1, direction_to_verify); } } TEST_F(LeAudioAseConfigurationTest, test_bounded_headphones_ringtone) { TEST_F(LeAudioAseConfigurationTest, test_bounded_headphones_ringtone) { Loading @@ -758,16 +820,20 @@ TEST_F(LeAudioAseConfigurationTest, test_bounded_headphones_ringtone) { {bounded_headphones, kLeAudioCodecLC3ChannelCountTwoChannel, {bounded_headphones, kLeAudioCodecLC3ChannelCountTwoChannel, kLeAudioCodecLC3ChannelCountSingleChannel, 2, 0}); kLeAudioCodecLC3ChannelCountSingleChannel, 2, 0}); TestGroupAseConfiguration(LeAudioContextType::RINGTONE, &data, 1); uint8_t direction_to_verify = kLeAudioDirectionSink; TestGroupAseConfiguration(LeAudioContextType::RINGTONE, &data, 1, direction_to_verify); } } TEST_F(LeAudioAseConfigurationTest, test_bounded_headphones_conversional) { TEST_F(LeAudioAseConfigurationTest, test_bounded_headphones_conversional) { LeAudioDevice* bounded_headphones = AddTestDevice(2, 0); LeAudioDevice* bounded_headphones = AddTestDevice(2, 0); TestGroupAseConfigurationData data({bounded_headphones, TestGroupAseConfigurationData data({bounded_headphones, kLeAudioCodecLC3ChannelCountTwoChannel, kLeAudioCodecLC3ChannelCountTwoChannel, kLeAudioCodecLC3ChannelCountNone, 0, 0}); kLeAudioCodecLC3ChannelCountNone, 2, 0}); TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, &data, 1); uint8_t direction_to_verify = kLeAudioDirectionSink; TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, &data, 1, direction_to_verify); } } TEST_F(LeAudioAseConfigurationTest, test_bounded_headphones_media) { TEST_F(LeAudioAseConfigurationTest, test_bounded_headphones_media) { Loading @@ -776,15 +842,37 @@ TEST_F(LeAudioAseConfigurationTest, test_bounded_headphones_media) { kLeAudioCodecLC3ChannelCountTwoChannel, kLeAudioCodecLC3ChannelCountTwoChannel, kLeAudioCodecLC3ChannelCountNone, 2, 0}); kLeAudioCodecLC3ChannelCountNone, 2, 0}); TestGroupAseConfiguration(LeAudioContextType::MEDIA, &data, 1); uint8_t direction_to_verify = kLeAudioDirectionSink; TestGroupAseConfiguration(LeAudioContextType::MEDIA, &data, 1, direction_to_verify); } } TEST_F(LeAudioAseConfigurationTest, test_bounded_headset_ringtone) { TEST_F(LeAudioAseConfigurationTest, test_bounded_headset_ringtone_mono_microphone) { LeAudioDevice* bounded_headset = AddTestDevice(2, 1); LeAudioDevice* bounded_headset = AddTestDevice(2, 1); TestGroupAseConfigurationData data( TestGroupAseConfigurationData data( {bounded_headset, kLeAudioCodecLC3ChannelCountTwoChannel, {bounded_headset, kLeAudioCodecLC3ChannelCountTwoChannel, kLeAudioCodecLC3ChannelCountSingleChannel, 2, 1}); kLeAudioCodecLC3ChannelCountSingleChannel, 2, 1}); /* mono, change location as by default it is stereo */ bounded_headset->src_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; group_->ReloadAudioLocations(); TestGroupAseConfiguration(LeAudioContextType::RINGTONE, &data, 1); } TEST_F(LeAudioAseConfigurationTest, test_bounded_headset_ringtone_stereo_microphone) { LeAudioDevice* bounded_headset = AddTestDevice(2, 2); TestGroupAseConfigurationData data( {bounded_headset, kLeAudioCodecLC3ChannelCountSingleChannel | kLeAudioCodecLC3ChannelCountTwoChannel, kLeAudioCodecLC3ChannelCountSingleChannel | kLeAudioCodecLC3ChannelCountTwoChannel, 2, 2}); TestGroupAseConfiguration(LeAudioContextType::RINGTONE, &data, 1); TestGroupAseConfiguration(LeAudioContextType::RINGTONE, &data, 1); } } Loading @@ -803,7 +891,9 @@ TEST_F(LeAudioAseConfigurationTest, test_bounded_headset_media) { {bounded_headset, kLeAudioCodecLC3ChannelCountTwoChannel, {bounded_headset, kLeAudioCodecLC3ChannelCountTwoChannel, kLeAudioCodecLC3ChannelCountSingleChannel, 2, 0}); kLeAudioCodecLC3ChannelCountSingleChannel, 2, 0}); TestGroupAseConfiguration(LeAudioContextType::MEDIA, &data, 1); uint8_t directions_to_verify = kLeAudioDirectionSink; TestGroupAseConfiguration(LeAudioContextType::MEDIA, &data, 1, directions_to_verify); } } TEST_F(LeAudioAseConfigurationTest, test_earbuds_ringtone) { TEST_F(LeAudioAseConfigurationTest, test_earbuds_ringtone) { Loading @@ -815,6 +905,17 @@ TEST_F(LeAudioAseConfigurationTest, test_earbuds_ringtone) { {right, kLeAudioCodecLC3ChannelCountSingleChannel, {right, kLeAudioCodecLC3ChannelCountSingleChannel, kLeAudioCodecLC3ChannelCountSingleChannel, 1, 1}}; kLeAudioCodecLC3ChannelCountSingleChannel, 1, 1}}; /* Change location as by default it is stereo */ left->snk_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; left->src_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; right->snk_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight; right->src_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight; group_->ReloadAudioLocations(); TestGroupAseConfiguration(LeAudioContextType::RINGTONE, data, 2); TestGroupAseConfiguration(LeAudioContextType::RINGTONE, data, 2); } } Loading @@ -827,6 +928,17 @@ TEST_F(LeAudioAseConfigurationTest, test_earbuds_conversional) { {right, kLeAudioCodecLC3ChannelCountSingleChannel, {right, kLeAudioCodecLC3ChannelCountSingleChannel, kLeAudioCodecLC3ChannelCountSingleChannel, 1, 1}}; kLeAudioCodecLC3ChannelCountSingleChannel, 1, 1}}; /* Change location as by default it is stereo */ left->snk_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; left->src_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; right->snk_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight; right->src_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight; group_->ReloadAudioLocations(); TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, data, 2); TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, data, 2); } } Loading @@ -839,32 +951,81 @@ TEST_F(LeAudioAseConfigurationTest, test_earbuds_media) { {right, kLeAudioCodecLC3ChannelCountSingleChannel, {right, kLeAudioCodecLC3ChannelCountSingleChannel, kLeAudioCodecLC3ChannelCountSingleChannel, 1, 0}}; kLeAudioCodecLC3ChannelCountSingleChannel, 1, 0}}; TestGroupAseConfiguration(LeAudioContextType::MEDIA, data, 2); /* Change location as by default it is stereo */ left->snk_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; left->src_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; right->snk_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight; right->src_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight; group_->ReloadAudioLocations(); uint8_t directions_to_verify = kLeAudioDirectionSink; TestGroupAseConfiguration(LeAudioContextType::MEDIA, data, 2, directions_to_verify); } } TEST_F(LeAudioAseConfigurationTest, test_handsfree_ringtone) { TEST_F(LeAudioAseConfigurationTest, test_handsfree_mono_ringtone) { LeAudioDevice* handsfree = AddTestDevice(1, 1); LeAudioDevice* handsfree = AddTestDevice(1, 1); TestGroupAseConfigurationData data( TestGroupAseConfigurationData data( {handsfree, kLeAudioCodecLC3ChannelCountSingleChannel, {handsfree, kLeAudioCodecLC3ChannelCountSingleChannel, kLeAudioCodecLC3ChannelCountSingleChannel, 1, 1}); kLeAudioCodecLC3ChannelCountSingleChannel, 1, 1}); handsfree->snk_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; handsfree->src_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; group_->ReloadAudioLocations(); TestGroupAseConfiguration(LeAudioContextType::RINGTONE, &data, 1); } TEST_F(LeAudioAseConfigurationTest, test_handsfree_stereo_ringtone) { LeAudioDevice* handsfree = AddTestDevice(1, 1); TestGroupAseConfigurationData data( {handsfree, kLeAudioCodecLC3ChannelCountSingleChannel | kLeAudioCodecLC3ChannelCountTwoChannel, kLeAudioCodecLC3ChannelCountSingleChannel, 2, 1}); TestGroupAseConfiguration(LeAudioContextType::RINGTONE, &data, 1); TestGroupAseConfiguration(LeAudioContextType::RINGTONE, &data, 1); } } TEST_F(LeAudioAseConfigurationTest, test_handsfree_conversional) { TEST_F(LeAudioAseConfigurationTest, test_handsfree_mono_conversional) { LeAudioDevice* handsfree = AddTestDevice(1, 1); LeAudioDevice* handsfree = AddTestDevice(1, 1); TestGroupAseConfigurationData data( TestGroupAseConfigurationData data( {handsfree, kLeAudioCodecLC3ChannelCountSingleChannel, {handsfree, kLeAudioCodecLC3ChannelCountSingleChannel, kLeAudioCodecLC3ChannelCountSingleChannel, 1, 1}); kLeAudioCodecLC3ChannelCountSingleChannel, 1, 1}); handsfree->snk_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; handsfree->src_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; group_->ReloadAudioLocations(); TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, &data, 1); } TEST_F(LeAudioAseConfigurationTest, test_handsfree_stereo_conversional) { LeAudioDevice* handsfree = AddTestDevice(1, 1); TestGroupAseConfigurationData data( {handsfree, kLeAudioCodecLC3ChannelCountSingleChannel | kLeAudioCodecLC3ChannelCountTwoChannel, kLeAudioCodecLC3ChannelCountSingleChannel, 2, 1}); TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, &data, 1); TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, &data, 1); } } TEST_F(LeAudioAseConfigurationTest, test_handsfree_full_cached_conversional) { TEST_F(LeAudioAseConfigurationTest, test_handsfree_full_cached_conversional) { LeAudioDevice* handsfree = AddTestDevice(0, 0, 1, 1); LeAudioDevice* handsfree = AddTestDevice(0, 0, 1, 1); TestGroupAseConfigurationData data( TestGroupAseConfigurationData data( {handsfree, kLeAudioCodecLC3ChannelCountSingleChannel, {handsfree, kLeAudioCodecLC3ChannelCountSingleChannel, 1, 1}); kLeAudioCodecLC3ChannelCountSingleChannel | kLeAudioCodecLC3ChannelCountTwoChannel, kLeAudioCodecLC3ChannelCountSingleChannel, 2, 1}); TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, &data, 1); TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, &data, 1); } } Loading @@ -873,19 +1034,26 @@ TEST_F(LeAudioAseConfigurationTest, test_handsfree_partial_cached_conversional) { test_handsfree_partial_cached_conversional) { LeAudioDevice* handsfree = AddTestDevice(1, 0, 0, 1); LeAudioDevice* handsfree = AddTestDevice(1, 0, 0, 1); TestGroupAseConfigurationData data( TestGroupAseConfigurationData data( {handsfree, kLeAudioCodecLC3ChannelCountSingleChannel, {handsfree, kLeAudioCodecLC3ChannelCountSingleChannel, 1, 1}); kLeAudioCodecLC3ChannelCountSingleChannel | kLeAudioCodecLC3ChannelCountTwoChannel, kLeAudioCodecLC3ChannelCountSingleChannel, 2, 1}); TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, &data, 1); TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, &data, 1); } } TEST_F(LeAudioAseConfigurationTest, test_handsfree_media) { TEST_F(LeAudioAseConfigurationTest, test_handsfree_media_two_channels_allocation_stereo) { LeAudioDevice* handsfree = AddTestDevice(1, 1); LeAudioDevice* handsfree = AddTestDevice(1, 1); TestGroupAseConfigurationData data( TestGroupAseConfigurationData data( {handsfree, kLeAudioCodecLC3ChannelCountSingleChannel, {handsfree, kLeAudioCodecLC3ChannelCountSingleChannel, 1, 0}); kLeAudioCodecLC3ChannelCountSingleChannel | kLeAudioCodecLC3ChannelCountTwoChannel, kLeAudioCodecLC3ChannelCountSingleChannel, 2, 0}); TestGroupAseConfiguration(LeAudioContextType::MEDIA, &data, 1); uint8_t directions_to_verify = kLeAudioDirectionSink; TestGroupAseConfiguration(LeAudioContextType::MEDIA, &data, 1, directions_to_verify); } } TEST_F(LeAudioAseConfigurationTest, test_lc3_config_ringtone) { TEST_F(LeAudioAseConfigurationTest, test_lc3_config_ringtone) { Loading @@ -901,7 +1069,7 @@ TEST_F(LeAudioAseConfigurationTest, test_lc3_config_conversional) { } } TEST_F(LeAudioAseConfigurationTest, test_lc3_config_media) { TEST_F(LeAudioAseConfigurationTest, test_lc3_config_media) { AddTestDevice(1, 0); AddTestDevice(1, 1); TestLc3CodecConfig(LeAudioContextType::MEDIA); TestLc3CodecConfig(LeAudioContextType::MEDIA); } } Loading Loading @@ -934,6 +1102,17 @@ TEST_F(LeAudioAseConfigurationTest, test_reconnection_media) { LeAudioDevice* left = AddTestDevice(2, 1); LeAudioDevice* left = AddTestDevice(2, 1); LeAudioDevice* right = AddTestDevice(2, 1); LeAudioDevice* right = AddTestDevice(2, 1); /* Change location as by default it is stereo */ left->snk_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; left->src_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft; right->snk_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight; right->src_audio_locations_ = ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight; group_->ReloadAudioLocations(); TestGroupAseConfigurationData data[] = { TestGroupAseConfigurationData data[] = { {left, kLeAudioCodecLC3ChannelCountSingleChannel, {left, kLeAudioCodecLC3ChannelCountSingleChannel, kLeAudioCodecLC3ChannelCountSingleChannel, 1, 0}, kLeAudioCodecLC3ChannelCountSingleChannel, 1, 0}, Loading @@ -947,7 +1126,9 @@ TEST_F(LeAudioAseConfigurationTest, test_reconnection_media) { ASSERT_NE(all_configurations->end(), all_configurations->begin()); ASSERT_NE(all_configurations->end(), all_configurations->begin()); auto configuration = *all_configurations->begin(); auto configuration = *all_configurations->begin(); TestSingleAseConfiguration(LeAudioContextType::MEDIA, data, 2, configuration); uint8_t direction_to_verify = kLeAudioDirectionSink; TestSingleAseConfiguration(LeAudioContextType::MEDIA, data, 2, configuration, direction_to_verify); /* Generate CISes, symulate CIG creation and assign cis handles to ASEs.*/ /* Generate CISes, symulate CIG creation and assign cis handles to ASEs.*/ group_->CigGenerateCisIds(LeAudioContextType::MEDIA); group_->CigGenerateCisIds(LeAudioContextType::MEDIA); Loading Loading @@ -987,8 +1168,9 @@ TEST_F(LeAudioAseConfigurationTest, test_reconnection_media) { ASSERT_TRUE(number_of_active_ases == 2); ASSERT_TRUE(number_of_active_ases == 2); ASSERT_TRUE(group_snk_audio_location == kChannelAllocationStereo); ASSERT_TRUE(group_snk_audio_location == kChannelAllocationStereo); uint8_t directions_to_verify = ::le_audio::types::kLeAudioDirectionSink; for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) { TestGroupAseConfigurationVerdict(data[i]); TestGroupAseConfigurationVerdict(data[i], directions_to_verify); } } /* Before device is rejoining, and group already exist, cis handles are /* Before device is rejoining, and group already exist, cis handles are Loading