Merge "Parse broadcast offload capabilities"

This commit is contained in:
Treehugger Robot 2023-02-07 08:41:05 +00:00 committed by Gerrit Code Review
commit 47c304ee1e
7 changed files with 101 additions and 14 deletions

View file

@ -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<LeAudioCodecConfiguration::lc3Config>(
lc3_config);

View file

@ -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<std::optional<Lc3Capabilities>> 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 <class T>
BroadcastCapability BluetoothLeAudioCodecsProvider::ComposeBroadcastCapability(
const CodecType& codec_type, const AudioLocation& audio_location,
const uint8_t& channel_count, const std::vector<T>& capability) {
return {.codecType = codec_type,
.supportedChannel = audio_location,
.channelCountPerStream = channel_count,
.leAudioCodecCapabilities = std::optional(capability)};
}
template <class T>
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) {

View file

@ -20,6 +20,7 @@
#include <android-base/logging.h>
#include <unordered_map>
#include <vector>
#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 <class T>
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 <class T>
static inline BroadcastCapability ComposeBroadcastCapability(
const CodecType& codec_type, const AudioLocation& audio_location,
const uint8_t& channel_count, const std::vector<T>& capability);
static inline Lc3Capabilities ComposeLc3Capability(
const setting::CodecConfiguration& codec_configuration);

View file

@ -46,7 +46,11 @@ typedef std::tuple<std::vector<ScenarioList>, std::vector<ConfigurationList>,
// 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<ScenarioList> kValidScenarioList = {
ScenarioList(std::vector<Scenario>{kValidScenario})};
static const std::vector<ScenarioList> kValidScenarioList = {ScenarioList(
std::vector<Scenario>{kValidScenario, kValidBroadcastScenario})};
static const std::vector<ConfigurationList> kValidConfigurationList = {
ConfigurationList(
std::vector<Configuration>{kValidConfigOneChanStereo_16_1})};
@ -84,7 +92,7 @@ static const std::vector<StrategyConfigurationList>
kValidStrategyConfigurationList = {
StrategyConfigurationList(std::vector<StrategyConfiguration>{
kValidStrategyStereoOneCis, kValidStrategyStereoTwoCis,
kValidStrategyMonoOneCis})};
kValidStrategyMonoOneCis, kValidStrategyBroadcastStereo})};
class BluetoothLeAudioCodecsProviderTest
: public ::testing::TestWithParam<OffloadSetting> {
@ -151,13 +159,15 @@ class GetScenariosTest : public BluetoothLeAudioCodecsProviderTest {
static std::vector<ScenarioList> CreateInvalidScenarios() {
std::vector<ScenarioList> invalid_scenario_test_cases;
invalid_scenario_test_cases.push_back(ScenarioList(std::vector<Scenario>{
Scenario(std::nullopt, std::make_optional("OneChanStereo_16_1"))}));
invalid_scenario_test_cases.push_back(ScenarioList(std::vector<Scenario>{
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>{Scenario(std::nullopt, std::nullopt)}));
std::vector<Scenario>{Scenario(std::make_optional("OneChanStereo_16_1"),
std::nullopt, std::nullopt)}));
invalid_scenario_test_cases.push_back(ScenarioList(std::vector<Scenario>{
Scenario(std::nullopt, std::nullopt, std::nullopt)}));
invalid_scenario_test_cases.push_back(
ScenarioList(std::vector<Scenario>{}));

View file

@ -40,6 +40,8 @@
<scenario encode="OneChanStereo_16_2" decode="OneChanMono_16_2"/>
<scenario encode="TwoChanStereo_16_2" decode="OneChanMono_16_2"/>
<scenario encode="OneChanMono_16_2" decode="OneChanMono_16_2"/>
<!-- broadcast -->
<scenario encode="invalid" decode="invalid" broadcast="BcastStereo_16_2"/>
</scenarioList>
<configurationList>
<configuration name="OneChanMono_16_1" codecConfiguration="LC3_16k_1" strategyConfiguration="MONO_ONE_CIS_PER_DEVICE"/>
@ -48,6 +50,7 @@
<configuration name="OneChanMono_16_2" codecConfiguration="LC3_16k_2" strategyConfiguration="MONO_ONE_CIS_PER_DEVICE"/>
<configuration name="TwoChanStereo_16_2" codecConfiguration="LC3_16k_2" strategyConfiguration="STEREO_TWO_CISES_PER_DEVICE"/>
<configuration name="OneChanStereo_16_2" codecConfiguration="LC3_16k_2" strategyConfiguration="STEREO_ONE_CIS_PER_DEVICE"/>
<configuration name="BcastStereo_16_2" codecConfiguration="LC3_16k_2" strategyConfiguration="BROADCAST_STEREO"/>
</configurationList>
<codecConfigurationList>
<codecConfiguration name="LC3_16k_1" codec="LC3" samplingFrequency="16000" frameDurationUs="7500" octetsPerCodecFrame="30"/>
@ -57,5 +60,6 @@
<strategyConfiguration name="STEREO_ONE_CIS_PER_DEVICE" audioLocation="STEREO" connectedDevice="2" channelCount="1"/>
<strategyConfiguration name="STEREO_TWO_CISES_PER_DEVICE" audioLocation="STEREO" connectedDevice="1" channelCount="2"/>
<strategyConfiguration name="MONO_ONE_CIS_PER_DEVICE" audioLocation="MONO" connectedDevice="1" channelCount="1"/>
<strategyConfiguration name="BROADCAST_STEREO" audioLocation="STEREO" connectedDevice="0" channelCount="2"/>
</strategyConfigurationList>
</leAudioOffloadSetting>

View file

@ -32,6 +32,7 @@
<xs:complexType>
<xs:attribute name="encode" type="xs:string"/>
<xs:attribute name="decode" type="xs:string"/>
<xs:attribute name="broadcast" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="configuration">

View file

@ -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);
}