Merge "Expose different offload audio capabilities by project" am: 449d7b0f67 am: 464cbaa8f2 am: 67aed07877

Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/2207308

Change-Id: I362fc71e3631fd3296850c319799bf072769e7a6
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Treehugger Robot 2022-09-14 04:03:52 +00:00 committed by Automerger Merge Worker
commit f14b884e6b
10 changed files with 665 additions and 110 deletions

View file

@ -40,9 +40,13 @@ cc_library_shared {
"aidl_session/BluetoothAudioCodecs.cpp",
"aidl_session/BluetoothAudioSession.cpp",
"aidl_session/HidlToAidlMiddleware.cpp",
"aidl_session/BluetoothLeAudioCodecsProvider.cpp",
],
export_include_dirs: ["aidl_session/"],
header_libs: ["libhardware_headers"],
header_libs: [
"libhardware_headers",
"libxsdc-utils",
],
shared_libs: [
"android.hardware.bluetooth.audio@2.0",
"android.hardware.bluetooth.audio@2.1",
@ -53,5 +57,15 @@ cc_library_shared {
"liblog",
"android.hardware.bluetooth.audio-V2-ndk",
"libhidlbase",
"libxml2",
],
generated_sources: ["le_audio_codec_capabilities"],
generated_headers: ["le_audio_codec_capabilities"],
}
xsd_config {
name: "le_audio_codec_capabilities",
srcs: ["le_audio_codec_capabilities/le_audio_codec_capabilities.xsd"],
package_name: "aidl.android.hardware.bluetooth.audio.setting",
api_dir: "le_audio_codec_capabilities/schema",
}

View file

@ -32,6 +32,8 @@
#include <aidl/android/hardware/bluetooth/audio/SbcChannelMode.h>
#include <android-base/logging.h>
#include "BluetoothLeAudioCodecsProvider.h"
namespace aidl {
namespace android {
namespace hardware {
@ -96,67 +98,6 @@ const std::vector<CodecCapabilities> kDefaultOffloadA2dpCodecCapabilities = {
std::vector<LeAudioCodecCapabilitiesSetting> kDefaultOffloadLeAudioCapabilities;
static const UnicastCapability kInvalidUnicastCapability = {
.codecType = CodecType::UNKNOWN};
static const BroadcastCapability kInvalidBroadcastCapability = {
.codecType = CodecType::UNKNOWN};
// Default Supported Codecs
// LC3 16_1: sample rate: 16 kHz, frame duration: 7.5 ms, octets per frame: 30
static const Lc3Capabilities kLc3Capability_16_1 = {
.samplingFrequencyHz = {16000},
.frameDurationUs = {7500},
.octetsPerFrame = {30}};
// Default Supported Codecs
// LC3 16_2: sample rate: 16 kHz, frame duration: 10 ms, octets per frame: 40
static const Lc3Capabilities kLc3Capability_16_2 = {
.samplingFrequencyHz = {16000},
.frameDurationUs = {10000},
.octetsPerFrame = {40}};
// Default Supported Codecs
// LC3 24_2: sample rate: 24 kHz, frame duration: 10 ms, octets per frame: 60
static const Lc3Capabilities kLc3Capability_24_2 = {
.samplingFrequencyHz = {24000},
.frameDurationUs = {10000},
.octetsPerFrame = {60}};
// Default Supported Codecs
// LC3 32_2: sample rate: 32 kHz, frame duration: 10 ms, octets per frame: 80
static const Lc3Capabilities kLc3Capability_32_2 = {
.samplingFrequencyHz = {32000},
.frameDurationUs = {10000},
.octetsPerFrame = {80}};
// Default Supported Codecs
// LC3 48_4: sample rate: 48 kHz, frame duration: 10 ms, octets per frame: 120
static const Lc3Capabilities kLc3Capability_48_4 = {
.samplingFrequencyHz = {48000},
.frameDurationUs = {10000},
.octetsPerFrame = {120}};
static const std::vector<Lc3Capabilities> supportedLc3CapabilityList = {
kLc3Capability_48_4, kLc3Capability_32_2, kLc3Capability_24_2,
kLc3Capability_16_2, kLc3Capability_16_1};
static AudioLocation stereoAudio = static_cast<AudioLocation>(
static_cast<uint8_t>(AudioLocation::FRONT_LEFT) |
static_cast<uint8_t>(AudioLocation::FRONT_RIGHT));
static AudioLocation monoAudio = AudioLocation::UNKNOWN;
// Stores the supported setting of audio location, connected device, and the
// channel count for each device
std::vector<std::tuple<AudioLocation, uint8_t, uint8_t>>
supportedDeviceSetting = {
// Stereo, two connected device, one for L one for R
std::make_tuple(stereoAudio, 2, 1),
// Stereo, one connected device for both L and R
std::make_tuple(stereoAudio, 1, 2),
// Mono
std::make_tuple(monoAudio, 1, 1)};
template <class T>
bool BluetoothAudioCodecs::ContainedInVector(
const std::vector<T>& vector, const typename identity<T>::type& target) {
@ -444,19 +385,6 @@ bool BluetoothAudioCodecs::IsOffloadCodecConfigurationValid(
return false;
}
UnicastCapability composeUnicastLc3Capability(
AudioLocation audioLocation, uint8_t deviceCnt, uint8_t channelCount,
const Lc3Capabilities& capability) {
return {
.codecType = CodecType::LC3,
.supportedChannel = audioLocation,
.deviceCount = deviceCnt,
.channelCountPerDevice = channelCount,
.leAudioCodecCapabilities =
UnicastCapability::LeAudioCodecCapabilities(capability),
};
}
std::vector<LeAudioCodecCapabilitiesSetting>
BluetoothAudioCodecs::GetLeAudioOffloadCodecCapabilities(
const SessionType& session_type) {
@ -470,41 +398,8 @@ BluetoothAudioCodecs::GetLeAudioOffloadCodecCapabilities(
}
if (kDefaultOffloadLeAudioCapabilities.empty()) {
for (auto [audioLocation, deviceCnt, channelCount] :
supportedDeviceSetting) {
for (auto capability : supportedLc3CapabilityList) {
UnicastCapability lc3Capability = composeUnicastLc3Capability(
audioLocation, deviceCnt, channelCount, capability);
UnicastCapability lc3MonoDecodeCapability =
composeUnicastLc3Capability(monoAudio, 1, 1, capability);
// Adds the capability for encode only
kDefaultOffloadLeAudioCapabilities.push_back(
{.unicastEncodeCapability = lc3Capability,
.unicastDecodeCapability = kInvalidUnicastCapability,
.broadcastCapability = kInvalidBroadcastCapability});
// Adds the capability for decode only
kDefaultOffloadLeAudioCapabilities.push_back(
{.unicastEncodeCapability = kInvalidUnicastCapability,
.unicastDecodeCapability = lc3Capability,
.broadcastCapability = kInvalidBroadcastCapability});
// Adds the capability for the case that encode and decode exist at the
// same time(force one active device for decode)
kDefaultOffloadLeAudioCapabilities.push_back(
{.unicastEncodeCapability = lc3Capability,
.unicastDecodeCapability = lc3MonoDecodeCapability,
.broadcastCapability = kInvalidBroadcastCapability});
// Adds the capability for the case that encode and decode exist at the
// same time
kDefaultOffloadLeAudioCapabilities.push_back(
{.unicastEncodeCapability = lc3Capability,
.unicastDecodeCapability = lc3Capability,
.broadcastCapability = kInvalidBroadcastCapability});
}
}
kDefaultOffloadLeAudioCapabilities =
BluetoothLeAudioCodecsProvider::GetLeAudioCodecCapabilities();
}
return kDefaultOffloadLeAudioCapabilities;

View file

@ -0,0 +1,312 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "BTAudioCodecsProviderAidl"
#include "BluetoothLeAudioCodecsProvider.h"
namespace aidl {
namespace android {
namespace hardware {
namespace bluetooth {
namespace audio {
static const char* kLeAudioCodecCapabilitiesFile =
"/vendor/etc/le_audio_codec_capabilities.xml";
static const AudioLocation kStereoAudio = static_cast<AudioLocation>(
static_cast<uint8_t>(AudioLocation::FRONT_LEFT) |
static_cast<uint8_t>(AudioLocation::FRONT_RIGHT));
static const AudioLocation kMonoAudio = AudioLocation::UNKNOWN;
static std::vector<LeAudioCodecCapabilitiesSetting> leAudioCodecCapabilities;
std::vector<LeAudioCodecCapabilitiesSetting>
BluetoothLeAudioCodecsProvider::GetLeAudioCodecCapabilities() {
if (!leAudioCodecCapabilities.empty()) {
return leAudioCodecCapabilities;
}
const auto le_audio_offload_setting =
setting::readLeAudioOffloadSetting(kLeAudioCodecCapabilitiesFile);
if (!le_audio_offload_setting.has_value()) {
LOG(ERROR) << __func__ << ": Failed to read "
<< kLeAudioCodecCapabilitiesFile;
return {};
}
std::vector<setting::Scenario> 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 {};
}
leAudioCodecCapabilities =
ComposeLeAudioCodecCapabilities(supported_scenarios);
return leAudioCodecCapabilities;
}
std::vector<setting::Scenario> BluetoothLeAudioCodecsProvider::GetScenarios(
const std::optional<setting::LeAudioOffloadSetting>&
le_audio_offload_setting) {
std::vector<setting::Scenario> supported_scenarios;
if (le_audio_offload_setting->hasScenarioList()) {
for (const auto& scenario_list :
le_audio_offload_setting->getScenarioList()) {
if (!scenario_list.hasScenario()) {
continue;
}
for (const auto& scenario : scenario_list.getScenario()) {
if (scenario.hasEncode() && scenario.hasDecode()) {
supported_scenarios.push_back(scenario);
}
}
}
}
return supported_scenarios;
}
void BluetoothLeAudioCodecsProvider::UpdateConfigurationsToMap(
const std::optional<setting::LeAudioOffloadSetting>&
le_audio_offload_setting) {
if (le_audio_offload_setting->hasConfigurationList()) {
for (const auto& configuration_list :
le_audio_offload_setting->getConfigurationList()) {
if (!configuration_list.hasConfiguration()) {
continue;
}
for (const auto& configuration : configuration_list.getConfiguration()) {
if (configuration.hasName() && configuration.hasCodecConfiguration() &&
configuration.hasStrategyConfiguration()) {
configuration_map_.insert(
make_pair(configuration.getName(), configuration));
}
}
}
}
}
void BluetoothLeAudioCodecsProvider::UpdateCodecConfigurationsToMap(
const std::optional<setting::LeAudioOffloadSetting>&
le_audio_offload_setting) {
if (le_audio_offload_setting->hasCodecConfigurationList()) {
for (const auto& codec_configuration_list :
le_audio_offload_setting->getCodecConfigurationList()) {
if (!codec_configuration_list.hasCodecConfiguration()) {
continue;
}
for (const auto& codec_configuration :
codec_configuration_list.getCodecConfiguration()) {
if (IsValidCodecConfiguration(codec_configuration)) {
codec_configuration_map_.insert(
make_pair(codec_configuration.getName(), codec_configuration));
}
}
}
}
}
void BluetoothLeAudioCodecsProvider::UpdateStrategyConfigurationsToMap(
const std::optional<setting::LeAudioOffloadSetting>&
le_audio_offload_setting) {
if (le_audio_offload_setting->hasStrategyConfigurationList()) {
for (const auto& strategy_configuration_list :
le_audio_offload_setting->getStrategyConfigurationList()) {
if (!strategy_configuration_list.hasStrategyConfiguration()) {
continue;
}
for (const auto& strategy_configuration :
strategy_configuration_list.getStrategyConfiguration()) {
if (IsValidStrategyConfiguration(strategy_configuration)) {
strategy_configuration_map_.insert(make_pair(
strategy_configuration.getName(), strategy_configuration));
}
}
}
}
}
std::vector<LeAudioCodecCapabilitiesSetting>
BluetoothLeAudioCodecsProvider::ComposeLeAudioCodecCapabilities(
const std::vector<setting::Scenario>& supported_scenarios) {
std::vector<LeAudioCodecCapabilitiesSetting> le_audio_codec_capabilities;
for (const auto& scenario : supported_scenarios) {
UnicastCapability unicast_encode_capability =
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};
le_audio_codec_capabilities.push_back(
{.unicastEncodeCapability = unicast_encode_capability,
.unicastDecodeCapability = unicast_decode_capability,
.broadcastCapability = broadcast_capability});
}
return le_audio_codec_capabilities;
}
UnicastCapability BluetoothLeAudioCodecsProvider::GetUnicastCapability(
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());
if (codec_type == CodecType::LC3) {
return ComposeUnicastCapability(
codec_type,
GetAudioLocation(
strategy_configuration_iter->second.getAudioLocation()),
strategy_configuration_iter->second.getConnectedDevice(),
strategy_configuration_iter->second.getChannelCount(),
ComposeLc3Capability(codec_configuration_iter->second));
}
return {.codecType = CodecType::UNKNOWN};
}
template <class T>
UnicastCapability BluetoothLeAudioCodecsProvider::ComposeUnicastCapability(
const CodecType& codec_type, const AudioLocation& audio_location,
const uint8_t& device_cnt, const uint8_t& channel_count,
const T& capability) {
return {
.codecType = codec_type,
.supportedChannel = audio_location,
.deviceCount = device_cnt,
.channelCountPerDevice = channel_count,
.leAudioCodecCapabilities =
UnicastCapability::LeAudioCodecCapabilities(capability),
};
}
Lc3Capabilities BluetoothLeAudioCodecsProvider::ComposeLc3Capability(
const setting::CodecConfiguration& codec_configuration) {
return {.samplingFrequencyHz = {codec_configuration.getSamplingFrequency()},
.frameDurationUs = {codec_configuration.getFrameDurationUs()},
.octetsPerFrame = {codec_configuration.getOctetsPerCodecFrame()}};
}
AudioLocation BluetoothLeAudioCodecsProvider::GetAudioLocation(
const setting::AudioLocation& audio_location) {
switch (audio_location) {
case setting::AudioLocation::MONO:
return kMonoAudio;
case setting::AudioLocation::STEREO:
return kStereoAudio;
default:
return AudioLocation::UNKNOWN;
}
}
CodecType BluetoothLeAudioCodecsProvider::GetCodecType(
const setting::CodecType& codec_type) {
switch (codec_type) {
case setting::CodecType::LC3:
return CodecType::LC3;
default:
return CodecType::UNKNOWN;
}
}
bool BluetoothLeAudioCodecsProvider::IsValidCodecConfiguration(
const setting::CodecConfiguration& codec_configuration) {
return codec_configuration.hasName() && codec_configuration.hasCodec() &&
codec_configuration.hasSamplingFrequency() &&
codec_configuration.hasFrameDurationUs() &&
codec_configuration.hasOctetsPerCodecFrame();
}
bool BluetoothLeAudioCodecsProvider::IsValidStrategyConfiguration(
const setting::StrategyConfiguration& strategy_configuration) {
if (!strategy_configuration.hasName() ||
!strategy_configuration.hasAudioLocation() ||
!strategy_configuration.hasConnectedDevice() ||
!strategy_configuration.hasChannelCount()) {
return false;
}
if (strategy_configuration.getAudioLocation() ==
setting::AudioLocation::STEREO) {
if ((strategy_configuration.getConnectedDevice() == 2 &&
strategy_configuration.getChannelCount() == 1) ||
(strategy_configuration.getConnectedDevice() == 1 &&
strategy_configuration.getChannelCount() == 2)) {
// Stereo
// 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.getAudioLocation() ==
setting::AudioLocation::MONO) {
if (strategy_configuration.getConnectedDevice() == 1 &&
strategy_configuration.getChannelCount() == 1) {
// Mono
return true;
}
}
return false;
}
} // namespace audio
} // namespace bluetooth
} // namespace hardware
} // namespace android
} // namespace aidl

View file

@ -0,0 +1,87 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <aidl/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.h>
#include <android-base/logging.h>
#include <unordered_map>
#include "aidl_android_hardware_bluetooth_audio_setting.h"
namespace aidl {
namespace android {
namespace hardware {
namespace bluetooth {
namespace audio {
class BluetoothLeAudioCodecsProvider {
public:
static std::vector<LeAudioCodecCapabilitiesSetting>
GetLeAudioCodecCapabilities();
private:
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 std::vector<setting::Scenario> GetScenarios(
const std::optional<setting::LeAudioOffloadSetting>&
le_audio_offload_setting);
static void UpdateConfigurationsToMap(
const std::optional<setting::LeAudioOffloadSetting>&
le_audio_offload_setting);
static void UpdateCodecConfigurationsToMap(
const std::optional<setting::LeAudioOffloadSetting>&
le_audio_offload_setting);
static void UpdateStrategyConfigurationsToMap(
const std::optional<setting::LeAudioOffloadSetting>&
le_audio_offload_setting);
static std::vector<LeAudioCodecCapabilitiesSetting>
ComposeLeAudioCodecCapabilities(
const std::vector<setting::Scenario>& supported_scenarios);
static UnicastCapability GetUnicastCapability(
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);
static inline Lc3Capabilities ComposeLc3Capability(
const setting::CodecConfiguration& codec_configuration);
static inline AudioLocation GetAudioLocation(
const setting::AudioLocation& audio_location);
static inline CodecType GetCodecType(const setting::CodecType& codec_type);
static inline bool IsValidCodecConfiguration(
const setting::CodecConfiguration& codec_configuration);
static inline bool IsValidStrategyConfiguration(
const setting::StrategyConfiguration& strategy_configuration);
};
} // namespace audio
} // namespace bluetooth
} // namespace hardware
} // namespace android
} // namespace aidl

View file

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---
This is an example to configure LE Audio hardware offload supported capability settings
In the follow list, there would be only one list in this file. Add element into each list as needed.
codecConfigurationList:
Supported codec capability along with its parameter setting
strategyConfigurationList:
ASE Configuration strategies
configurationList:
For each configuration , there are two attributes
- codecConfiguration
- strategyConfiguration
scenarioList:
There would be only one `scenarios` group
For each scenario, the are two attributes
- encode
- decode
If a scenario is unidirectional, mark another direction as `invalid`
The configuration should be chosen from `configurationList`
-->
<leAudioOffloadSetting>
<scenarioList>
<!-- encode only -->
<scenario encode="OneChanMono_16_1" decode="invalid"/>
<scenario encode="TwoChanStereo_16_1" decode="invalid"/>
<scenario encode="OneChanStereo_16_1" decode="invalid"/>
<scenario encode="OneChanMono_16_2" decode="invalid"/>
<scenario encode="TwoChanStereo_16_2" decode="invalid"/>
<scenario encode="OneChanStereo_16_2" decode="invalid"/>
<!-- encode and decode -->
<scenario encode="OneChanStereo_16_1" decode="OneChanStereo_16_1"/>
<scenario encode="OneChanStereo_16_1" decode="OneChanMono_16_1"/>
<scenario encode="TwoChanStereo_16_1" decode="OneChanMono_16_1"/>
<scenario encode="OneChanMono_16_1" decode="OneChanMono_16_1"/>
<scenario encode="OneChanStereo_16_2" decode="OneChanStereo_16_2"/>
<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"/>
</scenarioList>
<configurationList>
<configuration name="OneChanMono_16_1" codecConfiguration="LC3_16k_1" strategyConfiguration="MONO_ONE_CIS_PER_DEVICE"/>
<configuration name="TwoChanStereo_16_1" codecConfiguration="LC3_16k_1" strategyConfiguration="STEREO_TWO_CISES_PER_DEVICE"/>
<configuration name="OneChanStereo_16_1" codecConfiguration="LC3_16k_1" strategyConfiguration="STEREO_ONE_CIS_PER_DEVICE"/>
<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"/>
</configurationList>
<codecConfigurationList>
<codecConfiguration name="LC3_16k_1" codec="LC3" samplingFrequency="16000" frameDurationUs="7500" octetsPerCodecFrame="30"/>
<codecConfiguration name="LC3_16k_2" codec="LC3" samplingFrequency="16000" frameDurationUs="10000" octetsPerCodecFrame="40"/>
</codecConfigurationList>
<strategyConfigurationList>
<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"/>
</strategyConfigurationList>
</leAudioOffloadSetting>

View file

@ -0,0 +1,74 @@
<!-- LE Audio Offload Codec Capability Schema -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="leAudioOffloadSetting">
<xs:complexType>
<xs:element ref="scenarioList" minOccurs="1" maxOccurs="1"/>
<xs:element ref="configurationList" minOccurs="1" maxOccurs="1"/>
<xs:element ref="codecConfigurationList" minOccurs="1" maxOccurs="1"/>
<xs:element ref="strategyConfigurationList" minOccurs="1" maxOccurs="1"/>
</xs:complexType>
</xs:element>
<xs:element name="scenarioList">
<xs:complexType>
<xs:element ref="scenario" minOccurs="1" maxOccurs="unbounded"/>
</xs:complexType>
</xs:element>
<xs:element name="configurationList">
<xs:complexType>
<xs:element ref="configuration" minOccurs="1" maxOccurs="unbounded"/>
</xs:complexType>
</xs:element>
<xs:element name="codecConfigurationList">
<xs:complexType>
<xs:element ref="codecConfiguration" minOccurs="1" maxOccurs="unbounded"/>
</xs:complexType>
</xs:element>
<xs:element name="strategyConfigurationList">
<xs:complexType>
<xs:element ref="strategyConfiguration" minOccurs="1" maxOccurs="unbounded"/>
</xs:complexType>
</xs:element>
<xs:element name="scenario">
<xs:complexType>
<xs:attribute name="encode" type="xs:string"/>
<xs:attribute name="decode" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="configuration">
<xs:complexType>
<xs:attribute name="name" type="xs:string"/>
<xs:attribute name="codecConfiguration" type="xs:string"/>
<xs:attribute name="strategyConfiguration" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="codecConfiguration">
<xs:complexType>
<xs:attribute name="name" type="xs:string"/>
<xs:attribute name="codec" type="codecType"/>
<xs:attribute name="pcmBitDepth" type="xs:unsignedByte"/>
<xs:attribute name="samplingFrequency" type="xs:int"/>
<xs:attribute name="frameDurationUs" type="xs:int"/>
<xs:attribute name="octetsPerCodecFrame" type="xs:int"/>
<xs:attribute name="codecFrameBlocksPerSdu" type="xs:unsignedByte"/>
</xs:complexType>
</xs:element>
<xs:element name="strategyConfiguration">
<xs:complexType>
<xs:attribute name="name" type="xs:string"/>
<xs:attribute name="audioLocation" type="audioLocation"/>
<xs:attribute name="connectedDevice" type="xs:unsignedByte"/>
<xs:attribute name="channelCount" type="xs:unsignedByte"/>
</xs:complexType>
</xs:element>
<xs:simpleType name="audioLocation">
<xs:restriction base="xs:string">
<xs:enumeration value="MONO"/>
<xs:enumeration value="STEREO"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="codecType">
<xs:restriction base="xs:string">
<xs:enumeration value="LC3"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>

View file

@ -0,0 +1,111 @@
// Signature format: 2.0
package aidl.android.hardware.bluetooth.audio.setting {
public enum AudioLocation {
method public String getRawName();
enum_constant public static final aidl.android.hardware.bluetooth.audio.setting.AudioLocation MONO;
enum_constant public static final aidl.android.hardware.bluetooth.audio.setting.AudioLocation STEREO;
}
public class CodecConfiguration {
ctor public CodecConfiguration();
method public aidl.android.hardware.bluetooth.audio.setting.CodecType getCodec();
method public short getCodecFrameBlocksPerSdu();
method public int getFrameDurationUs();
method public String getName();
method public int getOctetsPerCodecFrame();
method public short getPcmBitDepth();
method public int getSamplingFrequency();
method public void setCodec(aidl.android.hardware.bluetooth.audio.setting.CodecType);
method public void setCodecFrameBlocksPerSdu(short);
method public void setFrameDurationUs(int);
method public void setName(String);
method public void setOctetsPerCodecFrame(int);
method public void setPcmBitDepth(short);
method public void setSamplingFrequency(int);
}
public class CodecConfigurationList {
ctor public CodecConfigurationList();
method public java.util.List<aidl.android.hardware.bluetooth.audio.setting.CodecConfiguration> getCodecConfiguration();
}
public enum CodecType {
method public String getRawName();
enum_constant public static final aidl.android.hardware.bluetooth.audio.setting.CodecType LC3;
}
public class Configuration {
ctor public Configuration();
method public String getCodecConfiguration();
method public String getName();
method public String getStrategyConfiguration();
method public void setCodecConfiguration(String);
method public void setName(String);
method public void setStrategyConfiguration(String);
}
public class ConfigurationList {
ctor public ConfigurationList();
method public java.util.List<aidl.android.hardware.bluetooth.audio.setting.Configuration> getConfiguration();
}
public class LeAudioOffloadSetting {
ctor public LeAudioOffloadSetting();
method public aidl.android.hardware.bluetooth.audio.setting.CodecConfigurationList getCodecConfigurationList();
method public aidl.android.hardware.bluetooth.audio.setting.ConfigurationList getConfigurationList();
method public aidl.android.hardware.bluetooth.audio.setting.ScenarioList getScenarioList();
method public aidl.android.hardware.bluetooth.audio.setting.StrategyConfigurationList getStrategyConfigurationList();
method public void setCodecConfigurationList(aidl.android.hardware.bluetooth.audio.setting.CodecConfigurationList);
method public void setConfigurationList(aidl.android.hardware.bluetooth.audio.setting.ConfigurationList);
method public void setScenarioList(aidl.android.hardware.bluetooth.audio.setting.ScenarioList);
method public void setStrategyConfigurationList(aidl.android.hardware.bluetooth.audio.setting.StrategyConfigurationList);
}
public class Scenario {
ctor public Scenario();
method public String getDecode();
method public String getEncode();
method public void setDecode(String);
method public void setEncode(String);
}
public class ScenarioList {
ctor public ScenarioList();
method public java.util.List<aidl.android.hardware.bluetooth.audio.setting.Scenario> getScenario();
}
public class StrategyConfiguration {
ctor public StrategyConfiguration();
method public aidl.android.hardware.bluetooth.audio.setting.AudioLocation getAudioLocation();
method public short getChannelCount();
method public short getConnectedDevice();
method public String getName();
method public void setAudioLocation(aidl.android.hardware.bluetooth.audio.setting.AudioLocation);
method public void setChannelCount(short);
method public void setConnectedDevice(short);
method public void setName(String);
}
public class StrategyConfigurationList {
ctor public StrategyConfigurationList();
method public java.util.List<aidl.android.hardware.bluetooth.audio.setting.StrategyConfiguration> getStrategyConfiguration();
}
public class XmlParser {
ctor public XmlParser();
method public static aidl.android.hardware.bluetooth.audio.setting.CodecConfiguration readCodecConfiguration(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method public static aidl.android.hardware.bluetooth.audio.setting.CodecConfigurationList readCodecConfigurationList(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method public static aidl.android.hardware.bluetooth.audio.setting.Configuration readConfiguration(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method public static aidl.android.hardware.bluetooth.audio.setting.ConfigurationList readConfigurationList(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method public static aidl.android.hardware.bluetooth.audio.setting.LeAudioOffloadSetting readLeAudioOffloadSetting(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method public static aidl.android.hardware.bluetooth.audio.setting.Scenario readScenario(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method public static aidl.android.hardware.bluetooth.audio.setting.ScenarioList readScenarioList(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method public static aidl.android.hardware.bluetooth.audio.setting.StrategyConfiguration readStrategyConfiguration(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method public static aidl.android.hardware.bluetooth.audio.setting.StrategyConfigurationList readStrategyConfigurationList(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
}
}

View file

@ -0,0 +1 @@
// Signature format: 2.0