From 6aeb5d7217abd27e0c59d916c9eec70f59207efe Mon Sep 17 00:00:00 2001 From: Bao Do Date: Mon, 11 Dec 2023 10:53:18 +0000 Subject: [PATCH] Add LE Audio getProviderInfo information Bug: 306225778 Test: mmm hardware/interfaces/bluetooth/audio/aidl/default Change-Id: Ieb03a1a3096dbeb6a4e2ac4774ece6d3ef3e33be --- .../aidl/default/BluetoothAudioProvider.h | 3 +- .../default/BluetoothAudioProviderFactory.cpp | 19 ++ .../aidl_session/BluetoothAudioCodecs.cpp | 27 +++ .../utils/aidl_session/BluetoothAudioCodecs.h | 3 + .../BluetoothLeAudioCodecsProvider.cpp | 195 +++++++++++++++--- .../BluetoothLeAudioCodecsProvider.h | 11 + 6 files changed, 225 insertions(+), 33 deletions(-) diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h index ca333941e3..5064869ca3 100644 --- a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h +++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h @@ -41,8 +41,7 @@ class BluetoothAudioProvider : public BnBluetoothAudioProvider { ndk::ScopedAStatus startSession( const std::shared_ptr& host_if, const AudioConfiguration& audio_config, - const std::vector& latency_modes, - DataMQDesc* _aidl_return); + const std::vector& latency_modes, DataMQDesc* _aidl_return); ndk::ScopedAStatus endSession(); ndk::ScopedAStatus streamStarted(BluetoothAudioStatus status); ndk::ScopedAStatus streamSuspended(BluetoothAudioStatus status); diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp index 3a64c4d046..275cfec35f 100644 --- a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp +++ b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp @@ -37,6 +37,9 @@ namespace hardware { namespace bluetooth { namespace audio { +static const std::string kLeAudioOffloadProviderName = + "LE_AUDIO_OFFLOAD_HARDWARE_OFFLOAD_PROVIDER"; + BluetoothAudioProviderFactory::BluetoothAudioProviderFactory() {} ndk::ScopedAStatus BluetoothAudioProviderFactory::openProvider( @@ -158,6 +161,22 @@ ndk::ScopedAStatus BluetoothAudioProviderFactory::getProviderInfo( provider_info.name = A2dpOffloadCodecFactory::GetInstance()->name; for (auto codec : A2dpOffloadCodecFactory::GetInstance()->codecs) provider_info.codecInfos.push_back(codec->info); + } else if (session_type == + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH || + session_type == + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH || + session_type == + SessionType:: + LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) { + std::vector db_codec_info = + BluetoothAudioCodecs::GetLeAudioOffloadCodecInfo(session_type); + if (!db_codec_info.empty()) { + auto& provider_info = _aidl_return->emplace(); + provider_info.name = kLeAudioOffloadProviderName; + provider_info.codecInfos = db_codec_info; + *_aidl_return = provider_info; + } + return ndk::ScopedAStatus::ok(); } return ndk::ScopedAStatus::ok(); diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp index 6e15b3b93c..1524f5e3ac 100644 --- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp +++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp @@ -97,6 +97,8 @@ const std::vector kDefaultOffloadA2dpCodecCapabilities = { {.codecType = CodecType::OPUS, .capabilities = {}}}; std::vector kDefaultOffloadLeAudioCapabilities; +std::unordered_map> + kDefaultOffloadLeAudioCodecInfoMap; template bool BluetoothAudioCodecs::ContainedInVector( @@ -411,6 +413,31 @@ BluetoothAudioCodecs::GetLeAudioOffloadCodecCapabilities( return kDefaultOffloadLeAudioCapabilities; } +std::vector BluetoothAudioCodecs::GetLeAudioOffloadCodecInfo( + const SessionType& session_type) { + if (session_type != + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH && + session_type != + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH && + session_type != + SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) { + return std::vector(); + } + + if (kDefaultOffloadLeAudioCodecInfoMap.empty()) { + auto le_audio_offload_setting = + BluetoothLeAudioCodecsProvider::ParseFromLeAudioOffloadSettingFile(); + auto kDefaultOffloadLeAudioCodecInfoMap = + BluetoothLeAudioCodecsProvider::GetLeAudioCodecInfo( + le_audio_offload_setting); + } + auto codec_info_map_iter = + kDefaultOffloadLeAudioCodecInfoMap.find(session_type); + if (codec_info_map_iter == kDefaultOffloadLeAudioCodecInfoMap.end()) + return std::vector(); + return codec_info_map_iter->second; +} + } // namespace audio } // namespace bluetooth } // namespace hardware diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h index e3d657b497..01afb7a30a 100644 --- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h +++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -46,6 +47,8 @@ class BluetoothAudioCodecs { static std::vector GetLeAudioOffloadCodecCapabilities(const SessionType& session_type); + static std::vector GetLeAudioOffloadCodecInfo( + const SessionType& session_type); private: template diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp index 26da5fbe81..8c7a740cc2 100644 --- a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp +++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp @@ -14,6 +14,11 @@ * limitations under the License. */ +#include + +#include "aidl/android/hardware/bluetooth/audio/ChannelMode.h" +#include "aidl/android/hardware/bluetooth/audio/CodecId.h" +#include "aidl_android_hardware_bluetooth_audio_setting_enums.h" #define LOG_TAG "BTAudioCodecsProviderAidl" #include "BluetoothLeAudioCodecsProvider.h" @@ -50,6 +55,123 @@ BluetoothLeAudioCodecsProvider::ParseFromLeAudioOffloadSettingFile() { return le_audio_offload_setting; } +std::unordered_map> +BluetoothLeAudioCodecsProvider::GetLeAudioCodecInfo( + const std::optional& + le_audio_offload_setting) { + // Load from previous storage if present + if (!session_codecs_map_.empty()) return session_codecs_map_; + + isInvalidFileContent = true; + if (!le_audio_offload_setting.has_value()) return {}; + + // Load scenario, configuration, codec configuration and strategy + LoadConfigurationToMap(le_audio_offload_setting); + if (supported_scenarios_.empty() || configuration_map_.empty() || + codec_configuration_map_.empty() || strategy_configuration_map_.empty()) + return {}; + + // Map each configuration into a CodecInfo + std::unordered_map config_codec_info_map_; + + for (auto& p : configuration_map_) { + // Initialize new CodecInfo for the config + auto config_name = p.first; + if (config_codec_info_map_.count(config_name) == 0) + config_codec_info_map_[config_name] = CodecInfo(); + + // Getting informations from codecConfig and strategyConfig + const auto codec_config_name = p.second.getCodecConfiguration(); + const auto strategy_config_name = p.second.getStrategyConfiguration(); + const auto codec_configuration_map_iter = + codec_configuration_map_.find(codec_config_name); + if (codec_configuration_map_iter == codec_configuration_map_.end()) + continue; + const auto strategy_configuration_map_iter = + strategy_configuration_map_.find(strategy_config_name); + if (strategy_configuration_map_iter == strategy_configuration_map_.end()) + continue; + + const auto& codec_config = codec_configuration_map_iter->second; + const auto codec = codec_config.getCodec(); + const auto& strategy_config = strategy_configuration_map_iter->second; + const auto strategy_config_channel_count = + strategy_config.getChannelCount(); + + // Initiate information + auto& codec_info = config_codec_info_map_[config_name]; + switch (codec) { + case setting::CodecType::LC3: + codec_info.name = "LC3"; + codec_info.id = CodecId::Core::LC3; + break; + default: + codec_info.name = "UNDEFINE"; + codec_info.id = CodecId::make(); + break; + } + codec_info.transport = + CodecInfo::Transport::make(); + + // Mapping codec configuration information + auto& transport = + codec_info.transport.get(); + transport.samplingFrequencyHz.push_back( + codec_config.getSamplingFrequency()); + // Mapping octetsPerCodecFrame to bitdepth for easier comparison. + transport.bitdepth.push_back(codec_config.getOctetsPerCodecFrame()); + transport.frameDurationUs.push_back(codec_config.getFrameDurationUs()); + switch (strategy_config.getAudioLocation()) { + case setting::AudioLocation::MONO: + if (strategy_config_channel_count == 1) + transport.channelMode.push_back(ChannelMode::MONO); + else + transport.channelMode.push_back(ChannelMode::DUALMONO); + break; + case setting::AudioLocation::STEREO: + transport.channelMode.push_back(ChannelMode::STEREO); + break; + default: + transport.channelMode.push_back(ChannelMode::UNKNOWN); + break; + } + } + + // Goes through every scenario, deduplicate configuration + std::set encoding_config, decoding_config, broadcast_config; + for (auto& s : supported_scenarios_) { + if (s.hasEncode()) encoding_config.insert(s.getEncode()); + if (s.hasDecode()) decoding_config.insert(s.getDecode()); + if (s.hasBroadcast()) broadcast_config.insert(s.getBroadcast()); + } + + // Split by session types and add results + const auto encoding_path = + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH; + const auto decoding_path = + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH; + const auto broadcast_path = + SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH; + session_codecs_map_ = + std::unordered_map>(); + session_codecs_map_[encoding_path] = std::vector(); + session_codecs_map_[decoding_path] = std::vector(); + session_codecs_map_[broadcast_path] = std::vector(); + session_codecs_map_[encoding_path].reserve(encoding_config.size()); + session_codecs_map_[decoding_path].reserve(decoding_config.size()); + session_codecs_map_[broadcast_path].reserve(broadcast_config.size()); + for (auto& c : encoding_config) + session_codecs_map_[encoding_path].push_back(config_codec_info_map_[c]); + for (auto& c : decoding_config) + session_codecs_map_[decoding_path].push_back(config_codec_info_map_[c]); + for (auto& c : broadcast_config) + session_codecs_map_[broadcast_path].push_back(config_codec_info_map_[c]); + + isInvalidFileContent = session_codecs_map_.empty(); + + return session_codecs_map_; +} + std::vector BluetoothLeAudioCodecsProvider::GetLeAudioCodecCapabilities( const std::optional& @@ -58,6 +180,8 @@ BluetoothLeAudioCodecsProvider::GetLeAudioCodecCapabilities( return leAudioCodecCapabilities; } + isInvalidFileContent = true; + if (!le_audio_offload_setting.has_value()) { LOG(ERROR) << __func__ @@ -65,40 +189,13 @@ BluetoothLeAudioCodecsProvider::GetLeAudioCodecCapabilities( return {}; } - ClearLeAudioCodecCapabilities(); - isInvalidFileContent = true; - - std::vector supported_scenarios = - GetScenarios(le_audio_offload_setting); - if (supported_scenarios.empty()) { - LOG(ERROR) << __func__ << ": No scenarios in " - << kLeAudioCodecCapabilitiesFile; + LoadConfigurationToMap(le_audio_offload_setting); + if (supported_scenarios_.empty() || configuration_map_.empty() || + codec_configuration_map_.empty() || strategy_configuration_map_.empty()) return {}; - } - - UpdateConfigurationsToMap(le_audio_offload_setting); - if (configuration_map_.empty()) { - LOG(ERROR) << __func__ << ": No configurations in " - << kLeAudioCodecCapabilitiesFile; - return {}; - } - - UpdateCodecConfigurationsToMap(le_audio_offload_setting); - if (codec_configuration_map_.empty()) { - LOG(ERROR) << __func__ << ": No codec configurations in " - << kLeAudioCodecCapabilitiesFile; - return {}; - } - - UpdateStrategyConfigurationsToMap(le_audio_offload_setting); - if (strategy_configuration_map_.empty()) { - LOG(ERROR) << __func__ << ": No strategy configurations in " - << kLeAudioCodecCapabilitiesFile; - return {}; - } leAudioCodecCapabilities = - ComposeLeAudioCodecCapabilities(supported_scenarios); + ComposeLeAudioCodecCapabilities(supported_scenarios_); isInvalidFileContent = leAudioCodecCapabilities.empty(); return leAudioCodecCapabilities; @@ -109,6 +206,8 @@ void BluetoothLeAudioCodecsProvider::ClearLeAudioCodecCapabilities() { configuration_map_.clear(); codec_configuration_map_.clear(); strategy_configuration_map_.clear(); + session_codecs_map_.clear(); + supported_scenarios_.clear(); } std::vector BluetoothLeAudioCodecsProvider::GetScenarios( @@ -191,6 +290,40 @@ void BluetoothLeAudioCodecsProvider::UpdateStrategyConfigurationsToMap( } } +void BluetoothLeAudioCodecsProvider::LoadConfigurationToMap( + const std::optional& + le_audio_offload_setting) { + ClearLeAudioCodecCapabilities(); + + supported_scenarios_ = GetScenarios(le_audio_offload_setting); + if (supported_scenarios_.empty()) { + LOG(ERROR) << __func__ << ": No scenarios in " + << kLeAudioCodecCapabilitiesFile; + return; + } + + UpdateConfigurationsToMap(le_audio_offload_setting); + if (configuration_map_.empty()) { + LOG(ERROR) << __func__ << ": No configurations in " + << kLeAudioCodecCapabilitiesFile; + return; + } + + UpdateCodecConfigurationsToMap(le_audio_offload_setting); + if (codec_configuration_map_.empty()) { + LOG(ERROR) << __func__ << ": No codec configurations in " + << kLeAudioCodecCapabilitiesFile; + return; + } + + UpdateStrategyConfigurationsToMap(le_audio_offload_setting); + if (strategy_configuration_map_.empty()) { + LOG(ERROR) << __func__ << ": No strategy configurations in " + << kLeAudioCodecCapabilitiesFile; + return; + } +} + std::vector BluetoothLeAudioCodecsProvider::ComposeLeAudioCodecCapabilities( const std::vector& supported_scenarios) { diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h index 654e70cccf..5bf67e2f95 100644 --- a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h +++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h @@ -22,6 +22,8 @@ #include #include +#include "aidl/android/hardware/bluetooth/audio/CodecInfo.h" +#include "aidl/android/hardware/bluetooth/audio/SessionType.h" #include "aidl_android_hardware_bluetooth_audio_setting.h" namespace aidl { @@ -39,14 +41,20 @@ class BluetoothLeAudioCodecsProvider { const std::optional& le_audio_offload_setting); static void ClearLeAudioCodecCapabilities(); + static std::unordered_map> + GetLeAudioCodecInfo(const std::optional& + le_audio_offload_setting); private: + static inline std::vector supported_scenarios_; static inline std::unordered_map configuration_map_; static inline std::unordered_map codec_configuration_map_; static inline std::unordered_map strategy_configuration_map_; + static inline std::unordered_map> + session_codecs_map_; static std::vector GetScenarios( const std::optional& @@ -60,6 +68,9 @@ class BluetoothLeAudioCodecsProvider { static void UpdateStrategyConfigurationsToMap( const std::optional& le_audio_offload_setting); + static void LoadConfigurationToMap( + const std::optional& + le_audio_offload_setting); static std::vector ComposeLeAudioCodecCapabilities(