Cheney Ni | ad05f3e | 2018-11-08 16:41:02 +0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2019 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | #include <gtest/gtest.h> |
| 18 | |
| 19 | #include "client_interface.h" |
| 20 | |
| 21 | namespace { |
| 22 | |
| 23 | using ::android::hardware::bluetooth::audio::V2_0::AacObjectType; |
| 24 | using ::android::hardware::bluetooth::audio::V2_0::AacParameters; |
| 25 | using ::android::hardware::bluetooth::audio::V2_0::AacVariableBitRate; |
| 26 | using ::android::hardware::bluetooth::audio::V2_0::AptxParameters; |
| 27 | using ::android::hardware::bluetooth::audio::V2_0::CodecCapabilities; |
| 28 | using ::android::hardware::bluetooth::audio::V2_0::CodecConfiguration; |
| 29 | using ::android::hardware::bluetooth::audio::V2_0::CodecType; |
| 30 | using ::android::hardware::bluetooth::audio::V2_0::LdacChannelMode; |
| 31 | using ::android::hardware::bluetooth::audio::V2_0::LdacParameters; |
| 32 | using ::android::hardware::bluetooth::audio::V2_0::LdacQualityIndex; |
| 33 | using ::android::hardware::bluetooth::audio::V2_0::SbcAllocMethod; |
| 34 | using ::android::hardware::bluetooth::audio::V2_0::SbcBlockLength; |
| 35 | using ::android::hardware::bluetooth::audio::V2_0::SbcChannelMode; |
| 36 | using ::android::hardware::bluetooth::audio::V2_0::SbcNumSubbands; |
| 37 | using ::android::hardware::bluetooth::audio::V2_0::SbcParameters; |
| 38 | |
| 39 | using ::bluetooth::audio::AudioCapabilities; |
| 40 | using ::bluetooth::audio::AudioConfiguration; |
| 41 | using ::bluetooth::audio::BitsPerSample; |
| 42 | using ::bluetooth::audio::BluetoothAudioClientInterface; |
| 43 | using ::bluetooth::audio::BluetoothAudioStatus; |
| 44 | using ::bluetooth::audio::ChannelMode; |
| 45 | using ::bluetooth::audio::PcmParameters; |
| 46 | using ::bluetooth::audio::SampleRate; |
| 47 | using ::bluetooth::audio::SessionType; |
| 48 | using ::testing::Test; |
| 49 | |
| 50 | constexpr SampleRate kSampleRates[9] = { |
| 51 | SampleRate::RATE_UNKNOWN, SampleRate::RATE_44100, SampleRate::RATE_48000, |
| 52 | SampleRate::RATE_88200, SampleRate::RATE_96000, SampleRate::RATE_176400, |
| 53 | SampleRate::RATE_192000, SampleRate::RATE_16000, SampleRate::RATE_24000}; |
| 54 | constexpr BitsPerSample kBitsPerSamples[4] = { |
| 55 | BitsPerSample::BITS_UNKNOWN, BitsPerSample::BITS_16, BitsPerSample::BITS_24, |
| 56 | BitsPerSample::BITS_32}; |
| 57 | constexpr ChannelMode kChannelModes[3] = { |
| 58 | ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO}; |
| 59 | constexpr uint16_t kPeerMtus[5] = {660, 663, 883, 1005, 1500}; |
| 60 | |
| 61 | class TestTransport : public bluetooth::audio::IBluetoothTransportInstance { |
| 62 | private: |
| 63 | static constexpr uint64_t kRemoteDelayReportMs = 200; |
| 64 | |
| 65 | public: |
| 66 | TestTransport(SessionType session_type) |
| 67 | : bluetooth::audio::IBluetoothTransportInstance(session_type, {}){}; |
Yi Kong | 183eace | 2019-03-29 15:42:58 -0700 | [diff] [blame] | 68 | bluetooth::audio::BluetoothAudioCtrlAck StartRequest() override { |
Cheney Ni | ad05f3e | 2018-11-08 16:41:02 +0800 | [diff] [blame] | 69 | return bluetooth::audio::BluetoothAudioCtrlAck::SUCCESS_FINISHED; |
| 70 | } |
Yi Kong | 183eace | 2019-03-29 15:42:58 -0700 | [diff] [blame] | 71 | bluetooth::audio::BluetoothAudioCtrlAck SuspendRequest() override { |
Cheney Ni | ad05f3e | 2018-11-08 16:41:02 +0800 | [diff] [blame] | 72 | return bluetooth::audio::BluetoothAudioCtrlAck::SUCCESS_FINISHED; |
| 73 | } |
Yi Kong | 183eace | 2019-03-29 15:42:58 -0700 | [diff] [blame] | 74 | void StopRequest() override {} |
Cheney Ni | ad05f3e | 2018-11-08 16:41:02 +0800 | [diff] [blame] | 75 | bool GetPresentationPosition(uint64_t* remote_delay_report_ns, |
| 76 | uint64_t* total_bytes_readed, |
Yi Kong | 183eace | 2019-03-29 15:42:58 -0700 | [diff] [blame] | 77 | timespec* data_position) override { |
Cheney Ni | ad05f3e | 2018-11-08 16:41:02 +0800 | [diff] [blame] | 78 | if (remote_delay_report_ns) { |
| 79 | *remote_delay_report_ns = kRemoteDelayReportMs * 1000000; |
| 80 | } |
| 81 | if (total_bytes_readed) { |
| 82 | *total_bytes_readed = 0; |
| 83 | } |
| 84 | if (data_position) { |
| 85 | clock_gettime(CLOCK_MONOTONIC, data_position); |
| 86 | } |
| 87 | return true; |
| 88 | } |
Yi Kong | 183eace | 2019-03-29 15:42:58 -0700 | [diff] [blame] | 89 | void MetadataChanged( |
| 90 | const source_metadata_t& source_metadata __unused) override {} |
| 91 | void ResetPresentationPosition() override{}; |
| 92 | void LogBytesRead(size_t bytes_readed __unused) override{}; |
Cheney Ni | ad05f3e | 2018-11-08 16:41:02 +0800 | [diff] [blame] | 93 | }; |
| 94 | |
| 95 | class BluetoothAudioClientInterfaceTest : public Test { |
| 96 | protected: |
| 97 | TestTransport* test_transport_; |
| 98 | BluetoothAudioClientInterface* clientif_; |
| 99 | |
| 100 | static constexpr int kClientIfReturnSuccess = 0; |
| 101 | |
Yi Kong | 183eace | 2019-03-29 15:42:58 -0700 | [diff] [blame] | 102 | void SetUp() override {} |
Cheney Ni | ad05f3e | 2018-11-08 16:41:02 +0800 | [diff] [blame] | 103 | |
Yi Kong | 183eace | 2019-03-29 15:42:58 -0700 | [diff] [blame] | 104 | void TearDown() override { |
Cheney Ni | ad05f3e | 2018-11-08 16:41:02 +0800 | [diff] [blame] | 105 | clientif_ = nullptr; |
| 106 | test_transport_ = nullptr; |
| 107 | } |
| 108 | |
| 109 | bool IsSoftwarePcmParametersSupported(const PcmParameters& pcm_config) { |
| 110 | const std::vector<AudioCapabilities>& capabilities = |
| 111 | clientif_->GetAudioCapabilities(); |
| 112 | PcmParameters pcm_capabilities = capabilities[0].pcmCapabilities(); |
| 113 | bool is_pcm_config_valid = |
| 114 | (pcm_config.sampleRate != SampleRate::RATE_UNKNOWN && |
| 115 | pcm_config.bitsPerSample != BitsPerSample::BITS_UNKNOWN && |
| 116 | pcm_config.channelMode != ChannelMode::UNKNOWN); |
| 117 | bool is_pcm_config_supported = |
| 118 | (pcm_config.sampleRate & pcm_capabilities.sampleRate && |
| 119 | pcm_config.bitsPerSample & pcm_capabilities.bitsPerSample && |
| 120 | pcm_config.channelMode & pcm_capabilities.channelMode); |
| 121 | return (is_pcm_config_valid && is_pcm_config_supported); |
| 122 | } |
| 123 | |
| 124 | bool IsOffloadCodecConfigurationSupported( |
| 125 | const CodecConfiguration& codec_config) { |
| 126 | CodecCapabilities codec_capability = {}; |
| 127 | for (auto audio_capability : clientif_->GetAudioCapabilities()) { |
| 128 | if (audio_capability.codecCapabilities().codecType == |
| 129 | codec_config.codecType) { |
| 130 | codec_capability = audio_capability.codecCapabilities(); |
| 131 | } |
| 132 | } |
| 133 | if (codec_capability.codecType != codec_config.codecType) { |
| 134 | // codec is unsupported |
| 135 | return false; |
| 136 | } |
| 137 | bool is_codec_config_supported = false; |
| 138 | switch (codec_config.codecType) { |
| 139 | case CodecType::SBC: { |
| 140 | SbcParameters sbc_config = codec_config.config.sbcConfig(); |
| 141 | SbcParameters sbc_capability = |
| 142 | codec_capability.capabilities.sbcCapabilities(); |
| 143 | is_codec_config_supported = |
| 144 | (sbc_config.sampleRate & sbc_capability.sampleRate && |
| 145 | sbc_config.channelMode & sbc_capability.channelMode && |
| 146 | sbc_config.blockLength & sbc_capability.blockLength && |
| 147 | sbc_config.numSubbands & sbc_capability.numSubbands && |
| 148 | sbc_config.allocMethod & sbc_capability.allocMethod && |
| 149 | sbc_config.bitsPerSample & sbc_capability.bitsPerSample && |
| 150 | (sbc_capability.minBitpool <= sbc_config.minBitpool && |
| 151 | sbc_config.minBitpool <= sbc_config.maxBitpool && |
| 152 | sbc_config.maxBitpool <= sbc_capability.maxBitpool)); |
| 153 | return is_codec_config_supported; |
| 154 | } |
| 155 | case CodecType::AAC: { |
| 156 | AacParameters aac_config = codec_config.config.aacConfig(); |
| 157 | AacParameters aac_capability = |
| 158 | codec_capability.capabilities.aacCapabilities(); |
| 159 | is_codec_config_supported = |
| 160 | (aac_config.objectType & aac_capability.objectType && |
| 161 | aac_config.sampleRate & aac_capability.sampleRate && |
| 162 | aac_config.channelMode & aac_capability.channelMode && |
| 163 | (aac_config.variableBitRateEnabled == |
| 164 | AacVariableBitRate::DISABLED || |
| 165 | aac_capability.variableBitRateEnabled == |
| 166 | AacVariableBitRate::ENABLED) && |
| 167 | aac_config.bitsPerSample & aac_capability.bitsPerSample); |
| 168 | return is_codec_config_supported; |
| 169 | } |
| 170 | case CodecType::LDAC: { |
| 171 | LdacParameters ldac_config = codec_config.config.ldacConfig(); |
| 172 | LdacParameters ldac_capability = |
| 173 | codec_capability.capabilities.ldacCapabilities(); |
| 174 | is_codec_config_supported = |
| 175 | (ldac_config.sampleRate & ldac_capability.sampleRate && |
| 176 | ldac_config.channelMode & ldac_capability.channelMode && |
| 177 | ldac_config.bitsPerSample & ldac_capability.bitsPerSample); |
| 178 | return is_codec_config_supported; |
| 179 | } |
| 180 | case CodecType::APTX: |
| 181 | [[fallthrough]]; |
| 182 | case CodecType::APTX_HD: { |
| 183 | AptxParameters aptx_config = codec_config.config.aptxConfig(); |
| 184 | AptxParameters aptx_capability = |
| 185 | codec_capability.capabilities.aptxCapabilities(); |
| 186 | is_codec_config_supported = |
| 187 | (aptx_config.sampleRate & aptx_capability.sampleRate && |
| 188 | aptx_config.channelMode & aptx_capability.channelMode && |
| 189 | aptx_config.bitsPerSample & aptx_capability.bitsPerSample); |
| 190 | return is_codec_config_supported; |
| 191 | } |
| 192 | case CodecType::UNKNOWN: |
| 193 | return false; |
| 194 | } |
| 195 | } |
| 196 | }; |
| 197 | |
| 198 | } // namespace |
| 199 | |
| 200 | TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpSoftwareSession) { |
| 201 | test_transport_ = |
| 202 | new TestTransport(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH); |
| 203 | clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr); |
| 204 | AudioConfiguration audio_config = {}; |
| 205 | PcmParameters pcm_config = {}; |
| 206 | for (auto sample_rate : kSampleRates) { |
| 207 | pcm_config.sampleRate = sample_rate; |
| 208 | for (auto bits_per_sample : kBitsPerSamples) { |
| 209 | pcm_config.bitsPerSample = bits_per_sample; |
| 210 | for (auto channel_mode : kChannelModes) { |
| 211 | pcm_config.channelMode = channel_mode; |
| 212 | audio_config.pcmConfig(pcm_config); |
| 213 | clientif_->UpdateAudioConfig(audio_config); |
| 214 | if (IsSoftwarePcmParametersSupported(pcm_config)) { |
| 215 | EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess); |
| 216 | } else { |
| 217 | EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess); |
| 218 | } |
| 219 | EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess); |
| 220 | } // ChannelMode |
| 221 | } // BitsPerSampple |
| 222 | } // SampleRate |
| 223 | } |
| 224 | |
| 225 | TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpOffloadSbcSession) { |
| 226 | test_transport_ = |
| 227 | new TestTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH); |
| 228 | clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr); |
| 229 | AudioConfiguration audio_config = {}; |
| 230 | CodecConfiguration codec_config = {}; |
| 231 | SbcBlockLength block_lengths[4] = { |
| 232 | SbcBlockLength::BLOCKS_4, SbcBlockLength::BLOCKS_8, |
| 233 | SbcBlockLength::BLOCKS_12, SbcBlockLength::BLOCKS_16}; |
| 234 | SbcNumSubbands num_subbands[2] = {SbcNumSubbands::SUBBAND_4, |
| 235 | SbcNumSubbands::SUBBAND_8}; |
| 236 | SbcAllocMethod alloc_methods[2] = {SbcAllocMethod::ALLOC_MD_S, |
| 237 | SbcAllocMethod::ALLOC_MD_L}; |
| 238 | for (auto sample_rate : kSampleRates) { |
| 239 | for (auto bits_per_sample : kBitsPerSamples) { |
| 240 | for (auto channel_mode : kChannelModes) { |
| 241 | for (auto peer_mtu : kPeerMtus) { |
| 242 | for (auto block_length : block_lengths) { |
| 243 | for (auto num_subband : num_subbands) { |
| 244 | for (auto alloc_method : alloc_methods) { |
| 245 | codec_config.codecType = CodecType::SBC; |
| 246 | codec_config.peerMtu = peer_mtu; |
| 247 | codec_config.isScmstEnabled = false; |
| 248 | // A2DP_SBC_DEFAULT_BITRATE |
| 249 | codec_config.encodedAudioBitrate = 328000; |
| 250 | SbcParameters sbc = { |
| 251 | .sampleRate = sample_rate, |
| 252 | .channelMode = (channel_mode == ChannelMode::MONO |
| 253 | ? SbcChannelMode::MONO |
| 254 | : SbcChannelMode::JOINT_STEREO), |
| 255 | .blockLength = block_length, |
| 256 | .numSubbands = num_subband, |
| 257 | .allocMethod = alloc_method, |
| 258 | .bitsPerSample = bits_per_sample, |
| 259 | .minBitpool = 2, |
| 260 | .maxBitpool = 53}; |
| 261 | codec_config.config.sbcConfig(sbc); |
| 262 | audio_config.codecConfig(codec_config); |
| 263 | clientif_->UpdateAudioConfig(audio_config); |
| 264 | if (IsOffloadCodecConfigurationSupported(codec_config)) { |
| 265 | EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess); |
| 266 | } else { |
| 267 | EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess); |
| 268 | } |
| 269 | EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess); |
| 270 | } // SbcAllocMethod |
| 271 | } // SbcNumSubbands |
| 272 | } // SbcBlockLength |
| 273 | } // peerMtu |
| 274 | } // ChannelMode |
| 275 | } // BitsPerSampple |
| 276 | } // SampleRate |
| 277 | } |
| 278 | |
| 279 | TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpOffloadAacSession) { |
| 280 | test_transport_ = |
| 281 | new TestTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH); |
| 282 | clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr); |
| 283 | AudioConfiguration audio_config = {}; |
| 284 | CodecConfiguration codec_config = {}; |
| 285 | AacObjectType object_types[4] = { |
| 286 | AacObjectType::MPEG2_LC, AacObjectType::MPEG4_LC, |
| 287 | AacObjectType::MPEG4_LTP, AacObjectType::MPEG4_SCALABLE}; |
| 288 | AacVariableBitRate variable_bitrates[2] = {AacVariableBitRate::DISABLED, |
| 289 | AacVariableBitRate::ENABLED}; |
| 290 | for (auto sample_rate : kSampleRates) { |
| 291 | for (auto bits_per_sample : kBitsPerSamples) { |
| 292 | for (auto channel_mode : kChannelModes) { |
| 293 | for (auto peer_mtu : kPeerMtus) { |
| 294 | for (auto object_type : object_types) { |
| 295 | for (auto variable_bitrate : variable_bitrates) { |
| 296 | codec_config.codecType = CodecType::AAC; |
| 297 | codec_config.peerMtu = peer_mtu; |
| 298 | codec_config.isScmstEnabled = false; |
| 299 | // A2DP_AAC_DEFAULT_BITRATE |
| 300 | codec_config.encodedAudioBitrate = 320000; |
| 301 | AacParameters aac = {.objectType = object_type, |
| 302 | .sampleRate = sample_rate, |
| 303 | .channelMode = channel_mode, |
| 304 | .variableBitRateEnabled = variable_bitrate, |
| 305 | .bitsPerSample = bits_per_sample}; |
| 306 | codec_config.config.aacConfig(aac); |
| 307 | audio_config.codecConfig(codec_config); |
| 308 | clientif_->UpdateAudioConfig(audio_config); |
| 309 | if (IsOffloadCodecConfigurationSupported(codec_config)) { |
| 310 | EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess); |
| 311 | } else { |
| 312 | EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess); |
| 313 | } |
| 314 | EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess); |
| 315 | } // AacVariableBitRate |
| 316 | } // AacObjectType |
| 317 | } // peerMtu |
| 318 | } // ChannelMode |
| 319 | } // BitsPerSampple |
| 320 | } // SampleRate |
| 321 | } |
| 322 | |
| 323 | TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpOffloadLdacSession) { |
| 324 | test_transport_ = |
| 325 | new TestTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH); |
| 326 | clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr); |
| 327 | AudioConfiguration audio_config = {}; |
| 328 | CodecConfiguration codec_config = {}; |
| 329 | LdacQualityIndex quality_indexes[4] = { |
| 330 | LdacQualityIndex::QUALITY_HIGH, LdacQualityIndex::QUALITY_MID, |
| 331 | LdacQualityIndex::QUALITY_LOW, LdacQualityIndex::QUALITY_ABR}; |
| 332 | for (auto sample_rate : kSampleRates) { |
| 333 | for (auto bits_per_sample : kBitsPerSamples) { |
| 334 | for (auto channel_mode : kChannelModes) { |
| 335 | for (auto peer_mtu : kPeerMtus) { |
| 336 | for (auto quality_index : quality_indexes) { |
| 337 | codec_config.codecType = CodecType::LDAC; |
| 338 | codec_config.peerMtu = peer_mtu; |
| 339 | codec_config.isScmstEnabled = false; |
| 340 | codec_config.encodedAudioBitrate = 990000; |
| 341 | LdacParameters ldac = { |
| 342 | .sampleRate = sample_rate, |
| 343 | .channelMode = (channel_mode == ChannelMode::MONO |
| 344 | ? LdacChannelMode::MONO |
| 345 | : LdacChannelMode::STEREO), |
| 346 | .qualityIndex = quality_index, |
| 347 | .bitsPerSample = bits_per_sample}; |
| 348 | codec_config.config.ldacConfig(ldac); |
| 349 | audio_config.codecConfig(codec_config); |
| 350 | clientif_->UpdateAudioConfig(audio_config); |
| 351 | if (IsOffloadCodecConfigurationSupported(codec_config)) { |
| 352 | EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess); |
| 353 | } else { |
| 354 | EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess); |
| 355 | } |
| 356 | EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess); |
| 357 | } // LdacQualityIndex |
| 358 | } // peerMtu |
| 359 | } // ChannelMode |
| 360 | } // BitsPerSampple |
| 361 | } // SampleRate |
| 362 | } |
| 363 | |
| 364 | TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpOffloadAptxSession) { |
| 365 | test_transport_ = |
| 366 | new TestTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH); |
| 367 | clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr); |
| 368 | AudioConfiguration audio_config = {}; |
| 369 | CodecConfiguration codec_config = {}; |
| 370 | for (auto sample_rate : kSampleRates) { |
| 371 | for (auto bits_per_sample : kBitsPerSamples) { |
| 372 | for (auto channel_mode : kChannelModes) { |
| 373 | for (auto peer_mtu : kPeerMtus) { |
| 374 | codec_config.codecType = CodecType::APTX; |
| 375 | codec_config.peerMtu = peer_mtu; |
| 376 | codec_config.isScmstEnabled = false; |
| 377 | codec_config.encodedAudioBitrate = 352000; |
| 378 | AptxParameters aptx = {.sampleRate = sample_rate, |
| 379 | .channelMode = channel_mode, |
| 380 | .bitsPerSample = bits_per_sample}; |
| 381 | codec_config.config.aptxConfig(aptx); |
| 382 | audio_config.codecConfig(codec_config); |
| 383 | clientif_->UpdateAudioConfig(audio_config); |
| 384 | if (IsOffloadCodecConfigurationSupported(codec_config)) { |
| 385 | EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess); |
| 386 | } else { |
| 387 | EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess); |
| 388 | } |
| 389 | EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess); |
| 390 | } // peerMtu |
| 391 | } // ChannelMode |
| 392 | } // BitsPerSampple |
| 393 | } // SampleRate |
| 394 | } |
| 395 | |
| 396 | TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpOffloadAptxHdSession) { |
| 397 | test_transport_ = |
| 398 | new TestTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH); |
| 399 | clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr); |
| 400 | AudioConfiguration audio_config = {}; |
| 401 | CodecConfiguration codec_config = {}; |
| 402 | for (auto sample_rate : kSampleRates) { |
| 403 | for (auto bits_per_sample : kBitsPerSamples) { |
| 404 | for (auto channel_mode : kChannelModes) { |
| 405 | for (auto peer_mtu : kPeerMtus) { |
| 406 | codec_config.codecType = CodecType::APTX_HD; |
| 407 | codec_config.peerMtu = peer_mtu; |
| 408 | codec_config.isScmstEnabled = false; |
| 409 | codec_config.encodedAudioBitrate = 576000; |
| 410 | AptxParameters aptx = {.sampleRate = sample_rate, |
| 411 | .channelMode = channel_mode, |
| 412 | .bitsPerSample = bits_per_sample}; |
| 413 | codec_config.config.aptxConfig(aptx); |
| 414 | audio_config.codecConfig(codec_config); |
| 415 | clientif_->UpdateAudioConfig(audio_config); |
| 416 | if (IsOffloadCodecConfigurationSupported(codec_config)) { |
| 417 | EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess); |
| 418 | } else { |
| 419 | EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess); |
| 420 | } |
| 421 | EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess); |
| 422 | } // peerMtu |
| 423 | } // ChannelMode |
| 424 | } // BitsPerSampple |
| 425 | } // SampleRate |
| 426 | } |
| 427 | |
| 428 | TEST_F(BluetoothAudioClientInterfaceTest, |
| 429 | StartAndEndA2dpOffloadUnknownSession) { |
| 430 | test_transport_ = |
| 431 | new TestTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH); |
| 432 | clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr); |
| 433 | AudioConfiguration audio_config = {}; |
| 434 | CodecConfiguration codec_config = {}; |
| 435 | codec_config.codecType = CodecType::UNKNOWN; |
| 436 | codec_config.peerMtu = 1005; |
| 437 | codec_config.isScmstEnabled = false; |
| 438 | codec_config.encodedAudioBitrate = 328000; |
| 439 | codec_config.config = {}; |
| 440 | audio_config.codecConfig(codec_config); |
| 441 | clientif_->UpdateAudioConfig(audio_config); |
| 442 | if (IsOffloadCodecConfigurationSupported(codec_config)) { |
| 443 | EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess); |
| 444 | } else { |
| 445 | EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess); |
| 446 | } |
| 447 | EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess); |
| 448 | } |
| 449 | |
| 450 | TEST_F(BluetoothAudioClientInterfaceTest, |
| 451 | StartAndEndHearingAidSoftwareSession) { |
| 452 | test_transport_ = |
| 453 | new TestTransport(SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH); |
| 454 | clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr); |
| 455 | AudioConfiguration audio_config = {}; |
| 456 | PcmParameters pcm_config = {}; |
| 457 | for (auto sample_rate : kSampleRates) { |
| 458 | pcm_config.sampleRate = sample_rate; |
| 459 | for (auto bits_per_sample : kBitsPerSamples) { |
| 460 | pcm_config.bitsPerSample = bits_per_sample; |
| 461 | for (auto channel_mode : kChannelModes) { |
| 462 | pcm_config.channelMode = channel_mode; |
| 463 | audio_config.pcmConfig(pcm_config); |
| 464 | clientif_->UpdateAudioConfig(audio_config); |
| 465 | if (IsSoftwarePcmParametersSupported(pcm_config)) { |
| 466 | EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess); |
| 467 | } else { |
| 468 | EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess); |
| 469 | } |
| 470 | EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess); |
| 471 | } // ChannelMode |
| 472 | } // BitsPerSampple |
| 473 | } // SampleRate |
| 474 | } |