mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 22:04:26 +00:00
Add LE Audio getProviderInfo information
Bug: 306225778 Test: mmm hardware/interfaces/bluetooth/audio/aidl/default Change-Id: Ieb03a1a3096dbeb6a4e2ac4774ece6d3ef3e33be
This commit is contained in:
@@ -41,8 +41,7 @@ class BluetoothAudioProvider : public BnBluetoothAudioProvider {
|
||||
ndk::ScopedAStatus startSession(
|
||||
const std::shared_ptr<IBluetoothAudioPort>& host_if,
|
||||
const AudioConfiguration& audio_config,
|
||||
const std::vector<LatencyMode>& latency_modes,
|
||||
DataMQDesc* _aidl_return);
|
||||
const std::vector<LatencyMode>& latency_modes, DataMQDesc* _aidl_return);
|
||||
ndk::ScopedAStatus endSession();
|
||||
ndk::ScopedAStatus streamStarted(BluetoothAudioStatus status);
|
||||
ndk::ScopedAStatus streamSuspended(BluetoothAudioStatus status);
|
||||
|
||||
@@ -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<CodecInfo> 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();
|
||||
|
||||
@@ -97,6 +97,8 @@ const std::vector<CodecCapabilities> kDefaultOffloadA2dpCodecCapabilities = {
|
||||
{.codecType = CodecType::OPUS, .capabilities = {}}};
|
||||
|
||||
std::vector<LeAudioCodecCapabilitiesSetting> kDefaultOffloadLeAudioCapabilities;
|
||||
std::unordered_map<SessionType, std::vector<CodecInfo>>
|
||||
kDefaultOffloadLeAudioCodecInfoMap;
|
||||
|
||||
template <class T>
|
||||
bool BluetoothAudioCodecs::ContainedInVector(
|
||||
@@ -411,6 +413,31 @@ BluetoothAudioCodecs::GetLeAudioOffloadCodecCapabilities(
|
||||
return kDefaultOffloadLeAudioCapabilities;
|
||||
}
|
||||
|
||||
std::vector<CodecInfo> 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<CodecInfo>();
|
||||
}
|
||||
|
||||
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<CodecInfo>();
|
||||
return codec_info_map_iter->second;
|
||||
}
|
||||
|
||||
} // namespace audio
|
||||
} // namespace bluetooth
|
||||
} // namespace hardware
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include <aidl/android/hardware/bluetooth/audio/CodecCapabilities.h>
|
||||
#include <aidl/android/hardware/bluetooth/audio/CodecConfiguration.h>
|
||||
#include <aidl/android/hardware/bluetooth/audio/CodecInfo.h>
|
||||
#include <aidl/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.h>
|
||||
#include <aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.h>
|
||||
#include <aidl/android/hardware/bluetooth/audio/OpusConfiguration.h>
|
||||
@@ -46,6 +47,8 @@ class BluetoothAudioCodecs {
|
||||
|
||||
static std::vector<LeAudioCodecCapabilitiesSetting>
|
||||
GetLeAudioOffloadCodecCapabilities(const SessionType& session_type);
|
||||
static std::vector<CodecInfo> GetLeAudioOffloadCodecInfo(
|
||||
const SessionType& session_type);
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
|
||||
@@ -14,6 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <set>
|
||||
|
||||
#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<SessionType, std::vector<CodecInfo>>
|
||||
BluetoothLeAudioCodecsProvider::GetLeAudioCodecInfo(
|
||||
const std::optional<setting::LeAudioOffloadSetting>&
|
||||
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<std::string, CodecInfo> 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<CodecId::Tag::undef>();
|
||||
break;
|
||||
}
|
||||
codec_info.transport =
|
||||
CodecInfo::Transport::make<CodecInfo::Transport::Tag::leAudio>();
|
||||
|
||||
// Mapping codec configuration information
|
||||
auto& transport =
|
||||
codec_info.transport.get<CodecInfo::Transport::Tag::leAudio>();
|
||||
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<std::string> 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<SessionType, std::vector<CodecInfo>>();
|
||||
session_codecs_map_[encoding_path] = std::vector<CodecInfo>();
|
||||
session_codecs_map_[decoding_path] = std::vector<CodecInfo>();
|
||||
session_codecs_map_[broadcast_path] = std::vector<CodecInfo>();
|
||||
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<LeAudioCodecCapabilitiesSetting>
|
||||
BluetoothLeAudioCodecsProvider::GetLeAudioCodecCapabilities(
|
||||
const std::optional<setting::LeAudioOffloadSetting>&
|
||||
@@ -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<setting::Scenario> 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<setting::Scenario> BluetoothLeAudioCodecsProvider::GetScenarios(
|
||||
@@ -191,6 +290,40 @@ void BluetoothLeAudioCodecsProvider::UpdateStrategyConfigurationsToMap(
|
||||
}
|
||||
}
|
||||
|
||||
void BluetoothLeAudioCodecsProvider::LoadConfigurationToMap(
|
||||
const std::optional<setting::LeAudioOffloadSetting>&
|
||||
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<LeAudioCodecCapabilitiesSetting>
|
||||
BluetoothLeAudioCodecsProvider::ComposeLeAudioCodecCapabilities(
|
||||
const std::vector<setting::Scenario>& supported_scenarios) {
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#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<setting::LeAudioOffloadSetting>&
|
||||
le_audio_offload_setting);
|
||||
static void ClearLeAudioCodecCapabilities();
|
||||
static std::unordered_map<SessionType, std::vector<CodecInfo>>
|
||||
GetLeAudioCodecInfo(const std::optional<setting::LeAudioOffloadSetting>&
|
||||
le_audio_offload_setting);
|
||||
|
||||
private:
|
||||
static inline std::vector<setting::Scenario> supported_scenarios_;
|
||||
static inline std::unordered_map<std::string, setting::Configuration>
|
||||
configuration_map_;
|
||||
static inline std::unordered_map<std::string, setting::CodecConfiguration>
|
||||
codec_configuration_map_;
|
||||
static inline std::unordered_map<std::string, setting::StrategyConfiguration>
|
||||
strategy_configuration_map_;
|
||||
static inline std::unordered_map<SessionType, std::vector<CodecInfo>>
|
||||
session_codecs_map_;
|
||||
|
||||
static std::vector<setting::Scenario> GetScenarios(
|
||||
const std::optional<setting::LeAudioOffloadSetting>&
|
||||
@@ -60,6 +68,9 @@ class BluetoothLeAudioCodecsProvider {
|
||||
static void UpdateStrategyConfigurationsToMap(
|
||||
const std::optional<setting::LeAudioOffloadSetting>&
|
||||
le_audio_offload_setting);
|
||||
static void LoadConfigurationToMap(
|
||||
const std::optional<setting::LeAudioOffloadSetting>&
|
||||
le_audio_offload_setting);
|
||||
|
||||
static std::vector<LeAudioCodecCapabilitiesSetting>
|
||||
ComposeLeAudioCodecCapabilities(
|
||||
|
||||
Reference in New Issue
Block a user