123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473 |
- /*
- * Copyright 2019 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.
- */
- #include <gtest/gtest.h>
- #include "client_interface.h"
- namespace {
- using ::android::hardware::bluetooth::audio::V2_0::AacObjectType;
- using ::android::hardware::bluetooth::audio::V2_0::AacParameters;
- using ::android::hardware::bluetooth::audio::V2_0::AacVariableBitRate;
- using ::android::hardware::bluetooth::audio::V2_0::AptxParameters;
- using ::android::hardware::bluetooth::audio::V2_0::CodecCapabilities;
- using ::android::hardware::bluetooth::audio::V2_0::CodecConfiguration;
- using ::android::hardware::bluetooth::audio::V2_0::CodecType;
- using ::android::hardware::bluetooth::audio::V2_0::LdacChannelMode;
- using ::android::hardware::bluetooth::audio::V2_0::LdacParameters;
- using ::android::hardware::bluetooth::audio::V2_0::LdacQualityIndex;
- using ::android::hardware::bluetooth::audio::V2_0::SbcAllocMethod;
- using ::android::hardware::bluetooth::audio::V2_0::SbcBlockLength;
- using ::android::hardware::bluetooth::audio::V2_0::SbcChannelMode;
- using ::android::hardware::bluetooth::audio::V2_0::SbcNumSubbands;
- using ::android::hardware::bluetooth::audio::V2_0::SbcParameters;
- using ::bluetooth::audio::AudioCapabilities;
- using ::bluetooth::audio::AudioConfiguration;
- using ::bluetooth::audio::BitsPerSample;
- using ::bluetooth::audio::BluetoothAudioClientInterface;
- using ::bluetooth::audio::BluetoothAudioStatus;
- using ::bluetooth::audio::ChannelMode;
- using ::bluetooth::audio::PcmParameters;
- using ::bluetooth::audio::SampleRate;
- using ::bluetooth::audio::SessionType;
- using ::testing::Test;
- constexpr SampleRate kSampleRates[9] = {
- SampleRate::RATE_UNKNOWN, SampleRate::RATE_44100, SampleRate::RATE_48000,
- SampleRate::RATE_88200, SampleRate::RATE_96000, SampleRate::RATE_176400,
- SampleRate::RATE_192000, SampleRate::RATE_16000, SampleRate::RATE_24000};
- constexpr BitsPerSample kBitsPerSamples[4] = {
- BitsPerSample::BITS_UNKNOWN, BitsPerSample::BITS_16, BitsPerSample::BITS_24,
- BitsPerSample::BITS_32};
- constexpr ChannelMode kChannelModes[3] = {
- ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
- constexpr uint16_t kPeerMtus[5] = {660, 663, 883, 1005, 1500};
- class TestTransport : public bluetooth::audio::IBluetoothTransportInstance {
- private:
- static constexpr uint64_t kRemoteDelayReportMs = 200;
- public:
- TestTransport(SessionType session_type)
- : bluetooth::audio::IBluetoothTransportInstance(session_type, {}){};
- bluetooth::audio::BluetoothAudioCtrlAck StartRequest() {
- return bluetooth::audio::BluetoothAudioCtrlAck::SUCCESS_FINISHED;
- }
- bluetooth::audio::BluetoothAudioCtrlAck SuspendRequest() {
- return bluetooth::audio::BluetoothAudioCtrlAck::SUCCESS_FINISHED;
- }
- void StopRequest() {}
- bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
- uint64_t* total_bytes_readed,
- timespec* data_position) {
- if (remote_delay_report_ns) {
- *remote_delay_report_ns = kRemoteDelayReportMs * 1000000;
- }
- if (total_bytes_readed) {
- *total_bytes_readed = 0;
- }
- if (data_position) {
- clock_gettime(CLOCK_MONOTONIC, data_position);
- }
- return true;
- }
- void MetadataChanged(const source_metadata_t& source_metadata __unused) {}
- void ResetPresentationPosition(){};
- void LogBytesRead(size_t bytes_readed __unused){};
- };
- class BluetoothAudioClientInterfaceTest : public Test {
- protected:
- TestTransport* test_transport_;
- BluetoothAudioClientInterface* clientif_;
- static constexpr int kClientIfReturnSuccess = 0;
- virtual void SetUp() override {}
- virtual void TearDown() override {
- clientif_ = nullptr;
- test_transport_ = nullptr;
- }
- bool IsSoftwarePcmParametersSupported(const PcmParameters& pcm_config) {
- const std::vector<AudioCapabilities>& capabilities =
- clientif_->GetAudioCapabilities();
- PcmParameters pcm_capabilities = capabilities[0].pcmCapabilities();
- bool is_pcm_config_valid =
- (pcm_config.sampleRate != SampleRate::RATE_UNKNOWN &&
- pcm_config.bitsPerSample != BitsPerSample::BITS_UNKNOWN &&
- pcm_config.channelMode != ChannelMode::UNKNOWN);
- bool is_pcm_config_supported =
- (pcm_config.sampleRate & pcm_capabilities.sampleRate &&
- pcm_config.bitsPerSample & pcm_capabilities.bitsPerSample &&
- pcm_config.channelMode & pcm_capabilities.channelMode);
- return (is_pcm_config_valid && is_pcm_config_supported);
- }
- bool IsOffloadCodecConfigurationSupported(
- const CodecConfiguration& codec_config) {
- CodecCapabilities codec_capability = {};
- for (auto audio_capability : clientif_->GetAudioCapabilities()) {
- if (audio_capability.codecCapabilities().codecType ==
- codec_config.codecType) {
- codec_capability = audio_capability.codecCapabilities();
- }
- }
- if (codec_capability.codecType != codec_config.codecType) {
- // codec is unsupported
- return false;
- }
- bool is_codec_config_supported = false;
- switch (codec_config.codecType) {
- case CodecType::SBC: {
- SbcParameters sbc_config = codec_config.config.sbcConfig();
- SbcParameters sbc_capability =
- codec_capability.capabilities.sbcCapabilities();
- is_codec_config_supported =
- (sbc_config.sampleRate & sbc_capability.sampleRate &&
- sbc_config.channelMode & sbc_capability.channelMode &&
- sbc_config.blockLength & sbc_capability.blockLength &&
- sbc_config.numSubbands & sbc_capability.numSubbands &&
- sbc_config.allocMethod & sbc_capability.allocMethod &&
- sbc_config.bitsPerSample & sbc_capability.bitsPerSample &&
- (sbc_capability.minBitpool <= sbc_config.minBitpool &&
- sbc_config.minBitpool <= sbc_config.maxBitpool &&
- sbc_config.maxBitpool <= sbc_capability.maxBitpool));
- return is_codec_config_supported;
- }
- case CodecType::AAC: {
- AacParameters aac_config = codec_config.config.aacConfig();
- AacParameters aac_capability =
- codec_capability.capabilities.aacCapabilities();
- is_codec_config_supported =
- (aac_config.objectType & aac_capability.objectType &&
- aac_config.sampleRate & aac_capability.sampleRate &&
- aac_config.channelMode & aac_capability.channelMode &&
- (aac_config.variableBitRateEnabled ==
- AacVariableBitRate::DISABLED ||
- aac_capability.variableBitRateEnabled ==
- AacVariableBitRate::ENABLED) &&
- aac_config.bitsPerSample & aac_capability.bitsPerSample);
- return is_codec_config_supported;
- }
- case CodecType::LDAC: {
- LdacParameters ldac_config = codec_config.config.ldacConfig();
- LdacParameters ldac_capability =
- codec_capability.capabilities.ldacCapabilities();
- is_codec_config_supported =
- (ldac_config.sampleRate & ldac_capability.sampleRate &&
- ldac_config.channelMode & ldac_capability.channelMode &&
- ldac_config.bitsPerSample & ldac_capability.bitsPerSample);
- return is_codec_config_supported;
- }
- case CodecType::APTX:
- [[fallthrough]];
- case CodecType::APTX_HD: {
- AptxParameters aptx_config = codec_config.config.aptxConfig();
- AptxParameters aptx_capability =
- codec_capability.capabilities.aptxCapabilities();
- is_codec_config_supported =
- (aptx_config.sampleRate & aptx_capability.sampleRate &&
- aptx_config.channelMode & aptx_capability.channelMode &&
- aptx_config.bitsPerSample & aptx_capability.bitsPerSample);
- return is_codec_config_supported;
- }
- case CodecType::UNKNOWN:
- return false;
- }
- }
- };
- } // namespace
- TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpSoftwareSession) {
- test_transport_ =
- new TestTransport(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
- clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr);
- AudioConfiguration audio_config = {};
- PcmParameters pcm_config = {};
- for (auto sample_rate : kSampleRates) {
- pcm_config.sampleRate = sample_rate;
- for (auto bits_per_sample : kBitsPerSamples) {
- pcm_config.bitsPerSample = bits_per_sample;
- for (auto channel_mode : kChannelModes) {
- pcm_config.channelMode = channel_mode;
- audio_config.pcmConfig(pcm_config);
- clientif_->UpdateAudioConfig(audio_config);
- if (IsSoftwarePcmParametersSupported(pcm_config)) {
- EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess);
- } else {
- EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess);
- }
- EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess);
- } // ChannelMode
- } // BitsPerSampple
- } // SampleRate
- }
- TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpOffloadSbcSession) {
- test_transport_ =
- new TestTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr);
- AudioConfiguration audio_config = {};
- CodecConfiguration codec_config = {};
- SbcBlockLength block_lengths[4] = {
- SbcBlockLength::BLOCKS_4, SbcBlockLength::BLOCKS_8,
- SbcBlockLength::BLOCKS_12, SbcBlockLength::BLOCKS_16};
- SbcNumSubbands num_subbands[2] = {SbcNumSubbands::SUBBAND_4,
- SbcNumSubbands::SUBBAND_8};
- SbcAllocMethod alloc_methods[2] = {SbcAllocMethod::ALLOC_MD_S,
- SbcAllocMethod::ALLOC_MD_L};
- for (auto sample_rate : kSampleRates) {
- for (auto bits_per_sample : kBitsPerSamples) {
- for (auto channel_mode : kChannelModes) {
- for (auto peer_mtu : kPeerMtus) {
- for (auto block_length : block_lengths) {
- for (auto num_subband : num_subbands) {
- for (auto alloc_method : alloc_methods) {
- codec_config.codecType = CodecType::SBC;
- codec_config.peerMtu = peer_mtu;
- codec_config.isScmstEnabled = false;
- // A2DP_SBC_DEFAULT_BITRATE
- codec_config.encodedAudioBitrate = 328000;
- SbcParameters sbc = {
- .sampleRate = sample_rate,
- .channelMode = (channel_mode == ChannelMode::MONO
- ? SbcChannelMode::MONO
- : SbcChannelMode::JOINT_STEREO),
- .blockLength = block_length,
- .numSubbands = num_subband,
- .allocMethod = alloc_method,
- .bitsPerSample = bits_per_sample,
- .minBitpool = 2,
- .maxBitpool = 53};
- codec_config.config.sbcConfig(sbc);
- audio_config.codecConfig(codec_config);
- clientif_->UpdateAudioConfig(audio_config);
- if (IsOffloadCodecConfigurationSupported(codec_config)) {
- EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess);
- } else {
- EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess);
- }
- EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess);
- } // SbcAllocMethod
- } // SbcNumSubbands
- } // SbcBlockLength
- } // peerMtu
- } // ChannelMode
- } // BitsPerSampple
- } // SampleRate
- }
- TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpOffloadAacSession) {
- test_transport_ =
- new TestTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr);
- AudioConfiguration audio_config = {};
- CodecConfiguration codec_config = {};
- AacObjectType object_types[4] = {
- AacObjectType::MPEG2_LC, AacObjectType::MPEG4_LC,
- AacObjectType::MPEG4_LTP, AacObjectType::MPEG4_SCALABLE};
- AacVariableBitRate variable_bitrates[2] = {AacVariableBitRate::DISABLED,
- AacVariableBitRate::ENABLED};
- for (auto sample_rate : kSampleRates) {
- for (auto bits_per_sample : kBitsPerSamples) {
- for (auto channel_mode : kChannelModes) {
- for (auto peer_mtu : kPeerMtus) {
- for (auto object_type : object_types) {
- for (auto variable_bitrate : variable_bitrates) {
- codec_config.codecType = CodecType::AAC;
- codec_config.peerMtu = peer_mtu;
- codec_config.isScmstEnabled = false;
- // A2DP_AAC_DEFAULT_BITRATE
- codec_config.encodedAudioBitrate = 320000;
- AacParameters aac = {.objectType = object_type,
- .sampleRate = sample_rate,
- .channelMode = channel_mode,
- .variableBitRateEnabled = variable_bitrate,
- .bitsPerSample = bits_per_sample};
- codec_config.config.aacConfig(aac);
- audio_config.codecConfig(codec_config);
- clientif_->UpdateAudioConfig(audio_config);
- if (IsOffloadCodecConfigurationSupported(codec_config)) {
- EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess);
- } else {
- EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess);
- }
- EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess);
- } // AacVariableBitRate
- } // AacObjectType
- } // peerMtu
- } // ChannelMode
- } // BitsPerSampple
- } // SampleRate
- }
- TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpOffloadLdacSession) {
- test_transport_ =
- new TestTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr);
- AudioConfiguration audio_config = {};
- CodecConfiguration codec_config = {};
- LdacQualityIndex quality_indexes[4] = {
- LdacQualityIndex::QUALITY_HIGH, LdacQualityIndex::QUALITY_MID,
- LdacQualityIndex::QUALITY_LOW, LdacQualityIndex::QUALITY_ABR};
- for (auto sample_rate : kSampleRates) {
- for (auto bits_per_sample : kBitsPerSamples) {
- for (auto channel_mode : kChannelModes) {
- for (auto peer_mtu : kPeerMtus) {
- for (auto quality_index : quality_indexes) {
- codec_config.codecType = CodecType::LDAC;
- codec_config.peerMtu = peer_mtu;
- codec_config.isScmstEnabled = false;
- codec_config.encodedAudioBitrate = 990000;
- LdacParameters ldac = {
- .sampleRate = sample_rate,
- .channelMode = (channel_mode == ChannelMode::MONO
- ? LdacChannelMode::MONO
- : LdacChannelMode::STEREO),
- .qualityIndex = quality_index,
- .bitsPerSample = bits_per_sample};
- codec_config.config.ldacConfig(ldac);
- audio_config.codecConfig(codec_config);
- clientif_->UpdateAudioConfig(audio_config);
- if (IsOffloadCodecConfigurationSupported(codec_config)) {
- EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess);
- } else {
- EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess);
- }
- EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess);
- } // LdacQualityIndex
- } // peerMtu
- } // ChannelMode
- } // BitsPerSampple
- } // SampleRate
- }
- TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpOffloadAptxSession) {
- test_transport_ =
- new TestTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr);
- AudioConfiguration audio_config = {};
- CodecConfiguration codec_config = {};
- for (auto sample_rate : kSampleRates) {
- for (auto bits_per_sample : kBitsPerSamples) {
- for (auto channel_mode : kChannelModes) {
- for (auto peer_mtu : kPeerMtus) {
- codec_config.codecType = CodecType::APTX;
- codec_config.peerMtu = peer_mtu;
- codec_config.isScmstEnabled = false;
- codec_config.encodedAudioBitrate = 352000;
- AptxParameters aptx = {.sampleRate = sample_rate,
- .channelMode = channel_mode,
- .bitsPerSample = bits_per_sample};
- codec_config.config.aptxConfig(aptx);
- audio_config.codecConfig(codec_config);
- clientif_->UpdateAudioConfig(audio_config);
- if (IsOffloadCodecConfigurationSupported(codec_config)) {
- EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess);
- } else {
- EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess);
- }
- EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess);
- } // peerMtu
- } // ChannelMode
- } // BitsPerSampple
- } // SampleRate
- }
- TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpOffloadAptxHdSession) {
- test_transport_ =
- new TestTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr);
- AudioConfiguration audio_config = {};
- CodecConfiguration codec_config = {};
- for (auto sample_rate : kSampleRates) {
- for (auto bits_per_sample : kBitsPerSamples) {
- for (auto channel_mode : kChannelModes) {
- for (auto peer_mtu : kPeerMtus) {
- codec_config.codecType = CodecType::APTX_HD;
- codec_config.peerMtu = peer_mtu;
- codec_config.isScmstEnabled = false;
- codec_config.encodedAudioBitrate = 576000;
- AptxParameters aptx = {.sampleRate = sample_rate,
- .channelMode = channel_mode,
- .bitsPerSample = bits_per_sample};
- codec_config.config.aptxConfig(aptx);
- audio_config.codecConfig(codec_config);
- clientif_->UpdateAudioConfig(audio_config);
- if (IsOffloadCodecConfigurationSupported(codec_config)) {
- EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess);
- } else {
- EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess);
- }
- EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess);
- } // peerMtu
- } // ChannelMode
- } // BitsPerSampple
- } // SampleRate
- }
- TEST_F(BluetoothAudioClientInterfaceTest,
- StartAndEndA2dpOffloadUnknownSession) {
- test_transport_ =
- new TestTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr);
- AudioConfiguration audio_config = {};
- CodecConfiguration codec_config = {};
- codec_config.codecType = CodecType::UNKNOWN;
- codec_config.peerMtu = 1005;
- codec_config.isScmstEnabled = false;
- codec_config.encodedAudioBitrate = 328000;
- codec_config.config = {};
- audio_config.codecConfig(codec_config);
- clientif_->UpdateAudioConfig(audio_config);
- if (IsOffloadCodecConfigurationSupported(codec_config)) {
- EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess);
- } else {
- EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess);
- }
- EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess);
- }
- TEST_F(BluetoothAudioClientInterfaceTest,
- StartAndEndHearingAidSoftwareSession) {
- test_transport_ =
- new TestTransport(SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
- clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr);
- AudioConfiguration audio_config = {};
- PcmParameters pcm_config = {};
- for (auto sample_rate : kSampleRates) {
- pcm_config.sampleRate = sample_rate;
- for (auto bits_per_sample : kBitsPerSamples) {
- pcm_config.bitsPerSample = bits_per_sample;
- for (auto channel_mode : kChannelModes) {
- pcm_config.channelMode = channel_mode;
- audio_config.pcmConfig(pcm_config);
- clientif_->UpdateAudioConfig(audio_config);
- if (IsSoftwarePcmParametersSupported(pcm_config)) {
- EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess);
- } else {
- EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess);
- }
- EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess);
- } // ChannelMode
- } // BitsPerSampple
- } // SampleRate
- }
|