Add VTS for LE multi-codec

Bug: 308548462
Test: atest VtsHalBluetoothAudioTargetTest
Change-Id: Ia74da644eb8e62bdf0709ba7f375a7e35ccf0936
This commit is contained in:
Bao Do 2023-12-06 01:27:54 +00:00
parent c4adf243fe
commit c36897dbd8

View file

@ -46,6 +46,7 @@ using aidl::android::hardware::bluetooth::audio::AptxCapabilities;
using aidl::android::hardware::bluetooth::audio::AptxConfiguration;
using aidl::android::hardware::bluetooth::audio::AudioCapabilities;
using aidl::android::hardware::bluetooth::audio::AudioConfiguration;
using aidl::android::hardware::bluetooth::audio::AudioContext;
using aidl::android::hardware::bluetooth::audio::BnBluetoothAudioPort;
using aidl::android::hardware::bluetooth::audio::BroadcastCapability;
using aidl::android::hardware::bluetooth::audio::ChannelMode;
@ -54,6 +55,8 @@ using aidl::android::hardware::bluetooth::audio::CodecConfiguration;
using aidl::android::hardware::bluetooth::audio::CodecId;
using aidl::android::hardware::bluetooth::audio::CodecInfo;
using aidl::android::hardware::bluetooth::audio::CodecParameters;
using aidl::android::hardware::bluetooth::audio::CodecSpecificCapabilitiesLtv;
using aidl::android::hardware::bluetooth::audio::CodecSpecificConfigurationLtv;
using aidl::android::hardware::bluetooth::audio::CodecType;
using aidl::android::hardware::bluetooth::audio::HfpConfiguration;
using aidl::android::hardware::bluetooth::audio::IBluetoothAudioPort;
@ -64,11 +67,13 @@ using aidl::android::hardware::bluetooth::audio::Lc3Capabilities;
using aidl::android::hardware::bluetooth::audio::Lc3Configuration;
using aidl::android::hardware::bluetooth::audio::LdacCapabilities;
using aidl::android::hardware::bluetooth::audio::LdacConfiguration;
using aidl::android::hardware::bluetooth::audio::LeAudioAseConfiguration;
using aidl::android::hardware::bluetooth::audio::LeAudioBroadcastConfiguration;
using aidl::android::hardware::bluetooth::audio::
LeAudioCodecCapabilitiesSetting;
using aidl::android::hardware::bluetooth::audio::LeAudioCodecConfiguration;
using aidl::android::hardware::bluetooth::audio::LeAudioConfiguration;
using aidl::android::hardware::bluetooth::audio::MetadataLtv;
using aidl::android::hardware::bluetooth::audio::OpusCapabilities;
using aidl::android::hardware::bluetooth::audio::OpusConfiguration;
using aidl::android::hardware::bluetooth::audio::PcmConfiguration;
@ -92,6 +97,21 @@ using MqDataMode = SynchronizedReadWrite;
using DataMQ = AidlMessageQueue<MqDataType, MqDataMode>;
using DataMQDesc = MQDescriptor<MqDataType, MqDataMode>;
using LeAudioAseConfigurationSetting =
IBluetoothAudioProvider::LeAudioAseConfigurationSetting;
using AseDirectionRequirement = IBluetoothAudioProvider::
LeAudioConfigurationRequirement::AseDirectionRequirement;
using AseDirectionConfiguration = IBluetoothAudioProvider::
LeAudioAseConfigurationSetting::AseDirectionConfiguration;
using AseQosDirectionRequirement = IBluetoothAudioProvider::
LeAudioAseQosConfigurationRequirement::AseQosDirectionRequirement;
using LeAudioAseQosConfiguration =
IBluetoothAudioProvider::LeAudioAseQosConfiguration;
using LeAudioDeviceCapabilities =
IBluetoothAudioProvider::LeAudioDeviceCapabilities;
using LeAudioConfigurationRequirement =
IBluetoothAudioProvider::LeAudioConfigurationRequirement;
// Constants
static constexpr int32_t a2dp_sample_rates[] = {0, 44100, 48000, 88200, 96000};
@ -197,6 +217,13 @@ class BluetoothAudioProviderFactoryAidl
virtual void TearDown() override { provider_factory_ = nullptr; }
void GetProviderInfoHelper(const SessionType& session_type) {
temp_provider_info_ = std::nullopt;
auto aidl_reval =
provider_factory_->getProviderInfo(session_type, &temp_provider_info_);
ASSERT_TRUE(aidl_reval.isOk());
}
void GetProviderCapabilitiesHelper(const SessionType& session_type) {
temp_provider_capabilities_.clear();
auto aidl_retval = provider_factory_->getProviderCapabilities(
@ -576,6 +603,8 @@ class BluetoothAudioProviderFactoryAidl
std::shared_ptr<IBluetoothAudioProvider> audio_provider_;
std::shared_ptr<IBluetoothAudioPort> audio_port_;
std::vector<AudioCapabilities> temp_provider_capabilities_;
std::optional<IBluetoothAudioProviderFactory::ProviderInfo>
temp_provider_info_;
// temp storage saves the specified codec capability by
// GetOffloadCodecCapabilityHelper()
@ -2126,6 +2155,8 @@ class BluetoothAudioProviderLeAudioOutputHardwareAidl
BluetoothAudioProviderFactoryAidl::SetUp();
GetProviderCapabilitiesHelper(
SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
GetProviderInfoHelper(
SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
OpenProviderHelper(
SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
ASSERT_TRUE(temp_provider_capabilities_.empty() ||
@ -2152,6 +2183,99 @@ class BluetoothAudioProviderLeAudioOutputHardwareAidl
return false;
}
bool IsOffloadOutputProviderInfoSupported() {
if (!temp_provider_info_.has_value()) return false;
if (temp_provider_info_.value().codecInfos.empty()) return false;
// Check if all codec info is of LeAudio type
for (auto& codec_info : temp_provider_info_.value().codecInfos) {
if (codec_info.transport.getTag() != CodecInfo::Transport::leAudio)
return false;
}
return true;
}
std::vector<Lc3Configuration> GetUnicastLc3SupportedListFromProviderInfo() {
std::vector<Lc3Configuration> le_audio_codec_configs;
for (auto& codec_info : temp_provider_info_.value().codecInfos) {
// Only gets LC3 codec information
if (codec_info.id != CodecId::Core::LC3) continue;
// Combine those parameters into one list of Lc3Configuration
auto& transport =
codec_info.transport.get<CodecInfo::Transport::Tag::leAudio>();
for (int32_t samplingFrequencyHz : transport.samplingFrequencyHz) {
for (int32_t frameDurationUs : transport.frameDurationUs) {
for (int32_t octetsPerFrame : transport.bitdepth) {
Lc3Configuration lc3_config = {
.samplingFrequencyHz = samplingFrequencyHz,
.frameDurationUs = frameDurationUs,
.octetsPerFrame = octetsPerFrame,
};
le_audio_codec_configs.push_back(lc3_config);
}
}
}
}
return le_audio_codec_configs;
}
AudioContext GetAudioContext(int32_t bitmask) {
AudioContext media_audio_context;
media_audio_context.bitmask = bitmask;
return media_audio_context;
}
LeAudioDeviceCapabilities GetDefaultRemoteCapability() {
// Create a capability
LeAudioDeviceCapabilities capability;
capability.codecId = CodecId::Core::LC3;
auto pref_context_metadata = MetadataLtv::PreferredAudioContexts();
pref_context_metadata.values = GetAudioContext(AudioContext::MEDIA);
capability.metadata = {pref_context_metadata};
auto sampling_rate =
CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies();
sampling_rate.bitmask =
CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ8000;
auto frame_duration =
CodecSpecificCapabilitiesLtv::SupportedFrameDurations();
frame_duration.bitmask =
CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US7500;
auto octets = CodecSpecificCapabilitiesLtv::SupportedOctetsPerCodecFrame();
octets.minimum = 0;
octets.maximum = 60;
auto frames = CodecSpecificCapabilitiesLtv::SupportedMaxCodecFramesPerSDU();
frames.value = 2;
capability.codecSpecificCapabilities = {sampling_rate, frame_duration,
octets, frames};
return capability;
}
LeAudioConfigurationRequirement GetDefaultRequirement(
bool is_source_requriement) {
// Create a requirements
LeAudioConfigurationRequirement requirement;
requirement.audioContext = GetAudioContext(AudioContext::MEDIA);
auto direction_ase_requriement = AseDirectionRequirement();
direction_ase_requriement.aseConfiguration.codecId = CodecId::Core::LC3;
direction_ase_requriement.aseConfiguration.targetLatency =
LeAudioAseConfiguration::TargetLatency::BALANCED_LATENCY_RELIABILITY;
// Mismatch sampling frequency
direction_ase_requriement.aseConfiguration.codecConfiguration = {
CodecSpecificConfigurationLtv::SamplingFrequency::HZ11025,
CodecSpecificConfigurationLtv::FrameDuration::US7500,
};
if (is_source_requriement)
requirement.sourceAseRequirement = {direction_ase_requriement};
else
requirement.sinkAseRequirement = {direction_ase_requriement};
return requirement;
}
std::vector<Lc3Configuration> GetUnicastLc3SupportedList(bool decoding,
bool supported) {
std::vector<Lc3Configuration> le_audio_codec_configs;
@ -2269,6 +2393,14 @@ class BluetoothAudioProviderLeAudioOutputHardwareAidl
}
LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
std::vector<int32_t> all_context_bitmasks = {
AudioContext::UNSPECIFIED, AudioContext::CONVERSATIONAL,
AudioContext::MEDIA, AudioContext::GAME,
AudioContext::INSTRUCTIONAL, AudioContext::VOICE_ASSISTANTS,
AudioContext::LIVE_AUDIO, AudioContext::SOUND_EFFECTS,
AudioContext::NOTIFICATIONS, AudioContext::RINGTONE_ALERTS,
AudioContext::ALERTS, AudioContext::EMERGENCY_ALARM,
};
};
/**
@ -2279,6 +2411,101 @@ class BluetoothAudioProviderLeAudioOutputHardwareAidl
TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
OpenLeAudioOutputHardwareProvider) {}
/**
* Test whether each provider of type
* SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
* stopped with Unicast hardware encoding config taken from provider info
*/
TEST_P(
BluetoothAudioProviderLeAudioOutputHardwareAidl,
StartAndEndLeAudioOutputSessionWithPossibleUnicastConfigFromProviderInfo) {
if (!IsOffloadOutputProviderInfoSupported()) {
return;
}
auto lc3_codec_configs = GetUnicastLc3SupportedListFromProviderInfo();
LeAudioConfiguration le_audio_config = {
.codecType = CodecType::LC3,
.peerDelayUs = 0,
};
for (auto& lc3_config : lc3_codec_configs) {
le_audio_config.leAudioCodecConfig
.set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
DataMQDesc mq_desc;
auto aidl_retval = audio_provider_->startSession(
audio_port_, AudioConfiguration(le_audio_config), latency_modes,
&mq_desc);
ASSERT_TRUE(aidl_retval.isOk());
EXPECT_TRUE(audio_provider_->endSession().isOk());
}
}
TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
GetEmptyAseConfigurationEmptyCapability) {
std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
std::vector<LeAudioConfigurationRequirement> empty_requirement;
std::vector<LeAudioAseConfigurationSetting> configurations;
// Check empty capability for source direction
auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
std::nullopt, empty_capability, empty_requirement, &configurations);
ASSERT_TRUE(aidl_retval.isOk());
ASSERT_TRUE(configurations.empty());
// Check empty capability for sink direction
aidl_retval = audio_provider_->getLeAudioAseConfiguration(
empty_capability, std::nullopt, empty_requirement, &configurations);
ASSERT_TRUE(aidl_retval.isOk());
ASSERT_TRUE(configurations.empty());
}
TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
GetEmptyAseConfigurationMismatchedRequirement) {
std::vector<std::optional<LeAudioDeviceCapabilities>> capabilities = {
GetDefaultRemoteCapability()};
// Check empty capability for source direction
std::vector<LeAudioAseConfigurationSetting> configurations;
std::vector<LeAudioConfigurationRequirement> source_requirements = {
GetDefaultRequirement(true)};
auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
std::nullopt, capabilities, source_requirements, &configurations);
ASSERT_TRUE(aidl_retval.isOk());
ASSERT_TRUE(configurations.empty());
// Check empty capability for sink direction
std::vector<LeAudioConfigurationRequirement> sink_requirements = {
GetDefaultRequirement(false)};
aidl_retval = audio_provider_->getLeAudioAseConfiguration(
capabilities, std::nullopt, source_requirements, &configurations);
ASSERT_TRUE(aidl_retval.isOk());
ASSERT_TRUE(configurations.empty());
}
TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl, GetQoSConfiguration) {
IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement requirement;
std::vector<IBluetoothAudioProvider::LeAudioAseQosConfiguration>
QoSConfigurations;
for (auto bitmask : all_context_bitmasks) {
requirement.contextType = GetAudioContext(bitmask);
IBluetoothAudioProvider::LeAudioAseQosConfigurationPair result;
auto aidl_retval =
audio_provider_->getLeAudioAseQosConfiguration(requirement, &result);
ASSERT_TRUE(aidl_retval.isOk());
if (result.sinkQosConfiguration.has_value())
QoSConfigurations.push_back(result.sinkQosConfiguration.value());
if (result.sourceQosConfiguration.has_value())
QoSConfigurations.push_back(result.sourceQosConfiguration.value());
}
// QoS Configurations should not be empty, as we searched for all contexts
ASSERT_FALSE(QoSConfigurations.empty());
}
/**
* Test whether each provider of type
* SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
@ -2435,6 +2662,8 @@ class BluetoothAudioProviderLeAudioInputHardwareAidl
BluetoothAudioProviderFactoryAidl::SetUp();
GetProviderCapabilitiesHelper(
SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
GetProviderInfoHelper(
SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
OpenProviderHelper(
SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
ASSERT_TRUE(temp_provider_capabilities_.empty() ||
@ -2464,7 +2693,7 @@ class BluetoothAudioProviderLeAudioInputHardwareAidl
/**
* Test whether each provider of type
* SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
* SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
* stopped
*/
TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
@ -2472,7 +2701,38 @@ TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
/**
* Test whether each provider of type
* SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
* SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
* stopped with Unicast hardware encoding config taken from provider info
*/
TEST_P(
BluetoothAudioProviderLeAudioInputHardwareAidl,
StartAndEndLeAudioInputSessionWithPossibleUnicastConfigFromProviderInfo) {
if (!IsOffloadOutputProviderInfoSupported()) {
return;
}
auto lc3_codec_configs = GetUnicastLc3SupportedListFromProviderInfo();
LeAudioConfiguration le_audio_config = {
.codecType = CodecType::LC3,
.peerDelayUs = 0,
};
for (auto& lc3_config : lc3_codec_configs) {
le_audio_config.leAudioCodecConfig
.set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
DataMQDesc mq_desc;
auto aidl_retval = audio_provider_->startSession(
audio_port_, AudioConfiguration(le_audio_config), latency_modes,
&mq_desc);
ASSERT_TRUE(aidl_retval.isOk());
EXPECT_TRUE(audio_provider_->endSession().isOk());
}
}
/**
* Test whether each provider of type
* SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
* stopped with Unicast hardware encoding config
*/
TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
@ -2503,7 +2763,7 @@ TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
/**
* Test whether each provider of type
* SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
* SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
* stopped with Unicast hardware encoding config
*
* Disabled since offload codec checking is not ready
@ -2621,6 +2881,8 @@ class BluetoothAudioProviderLeAudioBroadcastHardwareAidl
BluetoothAudioProviderFactoryAidl::SetUp();
GetProviderCapabilitiesHelper(
SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
GetProviderInfoHelper(
SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
OpenProviderHelper(
SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
ASSERT_TRUE(temp_provider_capabilities_.empty() ||
@ -2647,6 +2909,42 @@ class BluetoothAudioProviderLeAudioBroadcastHardwareAidl
return false;
}
bool IsBroadcastOffloadProviderInfoSupported() {
if (!temp_provider_info_.has_value()) return false;
if (temp_provider_info_.value().codecInfos.empty()) return false;
// Check if all codec info is of LeAudio type
for (auto& codec_info : temp_provider_info_.value().codecInfos) {
if (codec_info.transport.getTag() != CodecInfo::Transport::leAudio)
return false;
}
return true;
}
std::vector<Lc3Configuration> GetBroadcastLc3SupportedListFromProviderInfo() {
std::vector<Lc3Configuration> le_audio_codec_configs;
for (auto& codec_info : temp_provider_info_.value().codecInfos) {
// Only gets LC3 codec information
if (codec_info.id != CodecId::Core::LC3) continue;
// Combine those parameters into one list of Lc3Configuration
auto& transport =
codec_info.transport.get<CodecInfo::Transport::Tag::leAudio>();
for (int32_t samplingFrequencyHz : transport.samplingFrequencyHz) {
for (int32_t frameDurationUs : transport.frameDurationUs) {
for (int32_t octetsPerFrame : transport.bitdepth) {
Lc3Configuration lc3_config = {
.samplingFrequencyHz = samplingFrequencyHz,
.frameDurationUs = frameDurationUs,
.octetsPerFrame = octetsPerFrame,
};
le_audio_codec_configs.push_back(lc3_config);
}
}
}
}
return le_audio_codec_configs;
}
std::vector<Lc3Configuration> GetBroadcastLc3SupportedList(bool supported) {
std::vector<Lc3Configuration> le_audio_codec_configs;
if (!supported) {
@ -2705,6 +3003,44 @@ class BluetoothAudioProviderLeAudioBroadcastHardwareAidl
TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
OpenLeAudioOutputHardwareProvider) {}
/**
* Test whether each provider of type
* SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
* started and stopped with broadcast hardware encoding config taken from
* provider info
*/
TEST_P(
BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
StartAndEndLeAudioBroadcastSessionWithPossibleUnicastConfigFromProviderInfo) {
if (!IsBroadcastOffloadProviderInfoSupported()) {
return;
}
auto lc3_codec_configs = GetBroadcastLc3SupportedListFromProviderInfo();
LeAudioBroadcastConfiguration le_audio_broadcast_config = {
.codecType = CodecType::LC3,
.streamMap = {},
};
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);
le_audio_broadcast_config.streamMap[0].streamHandle = 0x0;
le_audio_broadcast_config.streamMap[0].pcmStreamId = 0x0;
le_audio_broadcast_config.streamMap[0].audioChannelAllocation = 0x1 << 0;
DataMQDesc mq_desc;
auto aidl_retval = audio_provider_->startSession(
audio_port_, AudioConfiguration(le_audio_broadcast_config),
latency_modes, &mq_desc);
ASSERT_TRUE(aidl_retval.isOk());
EXPECT_TRUE(audio_provider_->endSession().isOk());
}
}
/**
* Test whether each provider of type
* SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be