From ac077efa165ea9d6b065941d96b2359cc712b87d Mon Sep 17 00:00:00 2001 From: Patty Huang Date: Wed, 23 Nov 2022 14:45:15 +0800 Subject: [PATCH] Parse broadcast offload capabilities 1. Parse the broadcast capability from capability file 2. Convert broadcast HAL format to stack format 3. Update test to validate broadcast capability parsing 4. Correct the map size before accessing in VTS test Tag: #feature Bug: 242472419 Test: atest BluetoothLeAudioCodecsProviderTest Test: atest VtsHalBluetoothAudioTargetTest Change-Id: I8ac88c1e9024ca03757620bf48eacdd60ada7eb4 --- .../vts/VtsHalBluetoothAudioTargetTest.cpp | 1 + .../BluetoothLeAudioCodecsProvider.cpp | 70 +++++++++++++++++-- .../BluetoothLeAudioCodecsProvider.h | 9 +++ .../BluetoothLeAudioCodecsProviderTest.cpp | 28 +++++--- .../le_audio_codec_capabilities.xml | 4 ++ .../le_audio_codec_capabilities.xsd | 1 + .../schema/current.txt | 2 + 7 files changed, 101 insertions(+), 14 deletions(-) diff --git a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp index e9b74b771c..128ef61403 100644 --- a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp +++ b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp @@ -1566,6 +1566,7 @@ TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl, }; for (auto& lc3_config : lc3_codec_configs) { + le_audio_broadcast_config.streamMap.resize(1); le_audio_broadcast_config.streamMap[0] .leAudioCodecConfig.set( lc3_config); diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp index 1dec900aed..0a804bbb41 100644 --- a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp +++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp @@ -200,13 +200,21 @@ BluetoothLeAudioCodecsProvider::ComposeLeAudioCodecCapabilities( GetUnicastCapability(scenario.getEncode()); UnicastCapability unicast_decode_capability = GetUnicastCapability(scenario.getDecode()); - // encode and decode cannot be unknown at the same time - if (unicast_encode_capability.codecType == CodecType::UNKNOWN && - unicast_decode_capability.codecType == CodecType::UNKNOWN) { - continue; - } BroadcastCapability broadcast_capability = {.codecType = CodecType::UNKNOWN}; + + if (scenario.hasBroadcast()) { + broadcast_capability = GetBroadcastCapability(scenario.getBroadcast()); + } + + // At least one capability should be valid + if (unicast_encode_capability.codecType == CodecType::UNKNOWN && + unicast_decode_capability.codecType == CodecType::UNKNOWN && + broadcast_capability.codecType == CodecType::UNKNOWN) { + LOG(ERROR) << __func__ << ": None of the capability is valid."; + continue; + } + le_audio_codec_capabilities.push_back( {.unicastEncodeCapability = unicast_encode_capability, .unicastDecodeCapability = unicast_decode_capability, @@ -252,6 +260,54 @@ UnicastCapability BluetoothLeAudioCodecsProvider::GetUnicastCapability( return {.codecType = CodecType::UNKNOWN}; } +BroadcastCapability BluetoothLeAudioCodecsProvider::GetBroadcastCapability( + const std::string& coding_direction) { + if (coding_direction == "invalid") { + return {.codecType = CodecType::UNKNOWN}; + } + + auto configuration_iter = configuration_map_.find(coding_direction); + if (configuration_iter == configuration_map_.end()) { + return {.codecType = CodecType::UNKNOWN}; + } + + auto codec_configuration_iter = codec_configuration_map_.find( + configuration_iter->second.getCodecConfiguration()); + if (codec_configuration_iter == codec_configuration_map_.end()) { + return {.codecType = CodecType::UNKNOWN}; + } + + auto strategy_configuration_iter = strategy_configuration_map_.find( + configuration_iter->second.getStrategyConfiguration()); + if (strategy_configuration_iter == strategy_configuration_map_.end()) { + return {.codecType = CodecType::UNKNOWN}; + } + + CodecType codec_type = + GetCodecType(codec_configuration_iter->second.getCodec()); + std::vector> bcastLc3Cap( + 1, std::optional(ComposeLc3Capability(codec_configuration_iter->second))); + + if (codec_type == CodecType::LC3) { + return ComposeBroadcastCapability( + codec_type, + GetAudioLocation( + strategy_configuration_iter->second.getAudioLocation()), + strategy_configuration_iter->second.getChannelCount(), bcastLc3Cap); + } + return {.codecType = CodecType::UNKNOWN}; +} + +template +BroadcastCapability BluetoothLeAudioCodecsProvider::ComposeBroadcastCapability( + const CodecType& codec_type, const AudioLocation& audio_location, + const uint8_t& channel_count, const std::vector& capability) { + return {.codecType = codec_type, + .supportedChannel = audio_location, + .channelCountPerStream = channel_count, + .leAudioCodecCapabilities = std::optional(capability)}; +} + template UnicastCapability BluetoothLeAudioCodecsProvider::ComposeUnicastCapability( const CodecType& codec_type, const AudioLocation& audio_location, @@ -322,6 +378,10 @@ bool BluetoothLeAudioCodecsProvider::IsValidStrategyConfiguration( // 1. two connected device, one for L one for R // 2. one connected device for both L and R return true; + } else if (strategy_configuration.getConnectedDevice() == 0 && + strategy_configuration.getChannelCount() == 2) { + // Broadcast + return true; } } else if (strategy_configuration.getAudioLocation() == setting::AudioLocation::MONO) { diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h index e8799843ef..06e4595a4f 100644 --- a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h +++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h @@ -20,6 +20,7 @@ #include #include +#include #include "aidl_android_hardware_bluetooth_audio_setting.h" @@ -66,12 +67,20 @@ class BluetoothLeAudioCodecsProvider { static UnicastCapability GetUnicastCapability( const std::string& coding_direction); + static BroadcastCapability GetBroadcastCapability( + const std::string& coding_direction); + template static inline UnicastCapability ComposeUnicastCapability( const CodecType& codec_type, const AudioLocation& audio_location, const uint8_t& device_cnt, const uint8_t& channel_count, const T& capability); + template + static inline BroadcastCapability ComposeBroadcastCapability( + const CodecType& codec_type, const AudioLocation& audio_location, + const uint8_t& channel_count, const std::vector& capability); + static inline Lc3Capabilities ComposeLc3Capability( const setting::CodecConfiguration& codec_configuration); diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProviderTest.cpp b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProviderTest.cpp index 5393cd70e8..dba2749fde 100644 --- a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProviderTest.cpp +++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProviderTest.cpp @@ -46,7 +46,11 @@ typedef std::tuple, std::vector, // Define valid components for each list // Scenario static const Scenario kValidScenario(std::make_optional("OneChanStereo_16_1"), - std::make_optional("OneChanStereo_16_1")); + std::make_optional("OneChanStereo_16_1"), + std::nullopt); +static const Scenario kValidBroadcastScenario( + std::nullopt, std::nullopt, std::make_optional("BcastStereo_16_2")); + // Configuration static const Configuration kValidConfigOneChanStereo_16_1( std::make_optional("OneChanStereo_16_1"), std::make_optional("LC3_16k_1"), @@ -69,11 +73,15 @@ static const StrategyConfiguration kValidStrategyMonoOneCis( std::make_optional("MONO_ONE_CIS_PER_DEVICE"), std::make_optional(AudioLocation::MONO), std::make_optional(1), std::make_optional(1)); +static const StrategyConfiguration kValidStrategyBroadcastStereo( + std::make_optional("BROADCAST_STEREO"), + std::make_optional(AudioLocation::STEREO), std::make_optional(0), + std::make_optional(2)); // Define valid test list built from above valid components // Scenario, Configuration, CodecConfiguration, StrategyConfiguration -static const std::vector kValidScenarioList = { - ScenarioList(std::vector{kValidScenario})}; +static const std::vector kValidScenarioList = {ScenarioList( + std::vector{kValidScenario, kValidBroadcastScenario})}; static const std::vector kValidConfigurationList = { ConfigurationList( std::vector{kValidConfigOneChanStereo_16_1})}; @@ -84,7 +92,7 @@ static const std::vector kValidStrategyConfigurationList = { StrategyConfigurationList(std::vector{ kValidStrategyStereoOneCis, kValidStrategyStereoTwoCis, - kValidStrategyMonoOneCis})}; + kValidStrategyMonoOneCis, kValidStrategyBroadcastStereo})}; class BluetoothLeAudioCodecsProviderTest : public ::testing::TestWithParam { @@ -151,13 +159,15 @@ class GetScenariosTest : public BluetoothLeAudioCodecsProviderTest { static std::vector CreateInvalidScenarios() { std::vector invalid_scenario_test_cases; invalid_scenario_test_cases.push_back(ScenarioList(std::vector{ - Scenario(std::nullopt, std::make_optional("OneChanStereo_16_1"))})); - - invalid_scenario_test_cases.push_back(ScenarioList(std::vector{ - Scenario(std::make_optional("OneChanStereo_16_1"), std::nullopt)})); + Scenario(std::nullopt, std::make_optional("OneChanStereo_16_1"), + std::nullopt)})); invalid_scenario_test_cases.push_back(ScenarioList( - std::vector{Scenario(std::nullopt, std::nullopt)})); + std::vector{Scenario(std::make_optional("OneChanStereo_16_1"), + std::nullopt, std::nullopt)})); + + invalid_scenario_test_cases.push_back(ScenarioList(std::vector{ + Scenario(std::nullopt, std::nullopt, std::nullopt)})); invalid_scenario_test_cases.push_back( ScenarioList(std::vector{})); diff --git a/bluetooth/audio/utils/le_audio_codec_capabilities/le_audio_codec_capabilities.xml b/bluetooth/audio/utils/le_audio_codec_capabilities/le_audio_codec_capabilities.xml index c7904b338c..c8d1af097d 100644 --- a/bluetooth/audio/utils/le_audio_codec_capabilities/le_audio_codec_capabilities.xml +++ b/bluetooth/audio/utils/le_audio_codec_capabilities/le_audio_codec_capabilities.xml @@ -40,6 +40,8 @@ + + @@ -48,6 +50,7 @@ + @@ -57,5 +60,6 @@ + diff --git a/bluetooth/audio/utils/le_audio_codec_capabilities/le_audio_codec_capabilities.xsd b/bluetooth/audio/utils/le_audio_codec_capabilities/le_audio_codec_capabilities.xsd index 213e5974da..8c2d6a11eb 100644 --- a/bluetooth/audio/utils/le_audio_codec_capabilities/le_audio_codec_capabilities.xsd +++ b/bluetooth/audio/utils/le_audio_codec_capabilities/le_audio_codec_capabilities.xsd @@ -32,6 +32,7 @@ + diff --git a/bluetooth/audio/utils/le_audio_codec_capabilities/schema/current.txt b/bluetooth/audio/utils/le_audio_codec_capabilities/schema/current.txt index 06aa21a7b3..886350e37d 100644 --- a/bluetooth/audio/utils/le_audio_codec_capabilities/schema/current.txt +++ b/bluetooth/audio/utils/le_audio_codec_capabilities/schema/current.txt @@ -64,8 +64,10 @@ package aidl.android.hardware.bluetooth.audio.setting { public class Scenario { ctor public Scenario(); + method public String getBroadcast(); method public String getDecode(); method public String getEncode(); + method public void setBroadcast(String); method public void setDecode(String); method public void setEncode(String); }