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 #include "codec_status.h"
21
22 namespace {
23
24 using ::android::hardware::bluetooth::audio::V2_0::AacObjectType;
25 using ::android::hardware::bluetooth::audio::V2_0::AacParameters;
26 using ::android::hardware::bluetooth::audio::V2_0::AacVariableBitRate;
27 using ::android::hardware::bluetooth::audio::V2_0::AptxParameters;
28 using ::android::hardware::bluetooth::audio::V2_0::CodecCapabilities;
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::BluetoothAudioClientInterface;
42 using ::bluetooth::audio::BluetoothAudioStatus;
43 using ::bluetooth::audio::PcmParameters;
44 using ::bluetooth::audio::SessionType;
45 using ::bluetooth::audio::codec::A2dpCodecToHalBitsPerSample;
46 using ::bluetooth::audio::codec::A2dpCodecToHalChannelMode;
47 using ::bluetooth::audio::codec::A2dpCodecToHalSampleRate;
48 using ::bluetooth::audio::codec::BitsPerSample;
49 using ::bluetooth::audio::codec::ChannelMode;
50 using ::bluetooth::audio::codec::CodecConfiguration;
51 using ::bluetooth::audio::codec::IsCodecOffloadingEnabled;
52 using ::bluetooth::audio::codec::SampleRate;
53 using ::bluetooth::audio::codec::UpdateOffloadingCapabilities;
54 using ::testing::Test;
55
56 struct SampleRatePair {
57 SampleRate hal_sample_rate_;
58 btav_a2dp_codec_sample_rate_t btav_sample_rate_;
59 };
60 constexpr SampleRatePair kSampleRatePairs[9] = {
61 {.hal_sample_rate_ = SampleRate::RATE_UNKNOWN,
62 .btav_sample_rate_ = BTAV_A2DP_CODEC_SAMPLE_RATE_NONE},
63 {.hal_sample_rate_ = SampleRate::RATE_44100,
64 .btav_sample_rate_ = BTAV_A2DP_CODEC_SAMPLE_RATE_44100},
65 {.hal_sample_rate_ = SampleRate::RATE_48000,
66 .btav_sample_rate_ = BTAV_A2DP_CODEC_SAMPLE_RATE_48000},
67 {.hal_sample_rate_ = SampleRate::RATE_88200,
68 .btav_sample_rate_ = BTAV_A2DP_CODEC_SAMPLE_RATE_88200},
69 {.hal_sample_rate_ = SampleRate::RATE_96000,
70 .btav_sample_rate_ = BTAV_A2DP_CODEC_SAMPLE_RATE_96000},
71 {.hal_sample_rate_ = SampleRate::RATE_176400,
72 .btav_sample_rate_ = BTAV_A2DP_CODEC_SAMPLE_RATE_176400},
73 {.hal_sample_rate_ = SampleRate::RATE_192000,
74 .btav_sample_rate_ = BTAV_A2DP_CODEC_SAMPLE_RATE_192000},
75 {.hal_sample_rate_ = SampleRate::RATE_16000,
76 .btav_sample_rate_ = BTAV_A2DP_CODEC_SAMPLE_RATE_16000},
77 {.hal_sample_rate_ = SampleRate::RATE_24000,
78 .btav_sample_rate_ = BTAV_A2DP_CODEC_SAMPLE_RATE_24000}};
79
80 struct BitsPerSamplePair {
81 BitsPerSample hal_bits_per_sample_;
82 btav_a2dp_codec_bits_per_sample_t btav_bits_per_sample_;
83 };
84 constexpr BitsPerSamplePair kBitsPerSamplePairs[4] = {
85 {.hal_bits_per_sample_ = BitsPerSample::BITS_UNKNOWN,
86 .btav_bits_per_sample_ = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE},
87 {.hal_bits_per_sample_ = BitsPerSample::BITS_16,
88 .btav_bits_per_sample_ = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16},
89 {.hal_bits_per_sample_ = BitsPerSample::BITS_24,
90 .btav_bits_per_sample_ = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24},
91 {.hal_bits_per_sample_ = BitsPerSample::BITS_32,
92 .btav_bits_per_sample_ = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32}};
93
94 struct ChannelModePair {
95 ChannelMode hal_channel_mode_;
96 btav_a2dp_codec_channel_mode_t btav_channel_mode_;
97 };
98 constexpr ChannelModePair kChannelModePairs[3] = {
99 {.hal_channel_mode_ = ChannelMode::UNKNOWN,
100 .btav_channel_mode_ = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE},
101 {.hal_channel_mode_ = ChannelMode::MONO,
102 .btav_channel_mode_ = BTAV_A2DP_CODEC_CHANNEL_MODE_MONO},
103 {.hal_channel_mode_ = ChannelMode::STEREO,
104 .btav_channel_mode_ = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO}};
105
106 constexpr btav_a2dp_codec_index_t codec_indexes[] = {
107 BTAV_A2DP_CODEC_INDEX_SOURCE_SBC, BTAV_A2DP_CODEC_INDEX_SOURCE_AAC,
108 BTAV_A2DP_CODEC_INDEX_SOURCE_APTX, BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD,
109 BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC, BTAV_A2DP_CODEC_INDEX_SINK_SBC,
110 BTAV_A2DP_CODEC_INDEX_SINK_AAC, BTAV_A2DP_CODEC_INDEX_SINK_LDAC};
111 constexpr uint16_t kPeerMtus[5] = {660, 663, 883, 1005, 1500};
112
113 class TestTransport : public bluetooth::audio::IBluetoothTransportInstance {
114 private:
115 static constexpr uint64_t kRemoteDelayReportMs = 200;
116
117 public:
TestTransport(SessionType session_type)118 TestTransport(SessionType session_type)
119 : bluetooth::audio::IBluetoothTransportInstance(session_type, {}){};
StartRequest()120 bluetooth::audio::BluetoothAudioCtrlAck StartRequest() override {
121 return bluetooth::audio::BluetoothAudioCtrlAck::SUCCESS_FINISHED;
122 }
SuspendRequest()123 bluetooth::audio::BluetoothAudioCtrlAck SuspendRequest() override {
124 return bluetooth::audio::BluetoothAudioCtrlAck::SUCCESS_FINISHED;
125 }
StopRequest()126 void StopRequest() override {}
GetPresentationPosition(uint64_t * remote_delay_report_ns,uint64_t * total_bytes_readed,timespec * data_position)127 bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
128 uint64_t* total_bytes_readed,
129 timespec* data_position) override {
130 if (remote_delay_report_ns) {
131 *remote_delay_report_ns = kRemoteDelayReportMs * 1000000;
132 }
133 if (total_bytes_readed) {
134 *total_bytes_readed = 0;
135 }
136 if (data_position) {
137 clock_gettime(CLOCK_MONOTONIC, data_position);
138 }
139 return true;
140 }
MetadataChanged(const source_metadata_t & source_metadata __unused)141 void MetadataChanged(
142 const source_metadata_t& source_metadata __unused) override {}
ResetPresentationPosition()143 void ResetPresentationPosition() override{};
LogBytesRead(size_t bytes_readed __unused)144 void LogBytesRead(size_t bytes_readed __unused) override{};
145 };
146
147 class BluetoothAudioClientInterfaceTest : public Test {
148 protected:
149 TestTransport* test_transport_ = nullptr;
150 BluetoothAudioClientInterface* clientif_ = nullptr;
151
152 static constexpr int kClientIfReturnSuccess = 0;
153
SetUp()154 void SetUp() override {}
155
TearDown()156 void TearDown() override {
157 if (clientif_ != nullptr) delete clientif_;
158 clientif_ = nullptr;
159 if (test_transport_ != nullptr) delete test_transport_;
160 test_transport_ = nullptr;
161 }
162
IsSoftwarePcmParametersSupported(const PcmParameters & pcm_config)163 bool IsSoftwarePcmParametersSupported(const PcmParameters& pcm_config) {
164 const std::vector<AudioCapabilities>& capabilities =
165 clientif_->GetAudioCapabilities();
166 PcmParameters pcm_capabilities = capabilities[0].pcmCapabilities();
167 bool is_pcm_config_valid =
168 (pcm_config.sampleRate != SampleRate::RATE_UNKNOWN &&
169 pcm_config.bitsPerSample != BitsPerSample::BITS_UNKNOWN &&
170 pcm_config.channelMode != ChannelMode::UNKNOWN);
171 bool is_pcm_config_supported =
172 (pcm_config.sampleRate & pcm_capabilities.sampleRate &&
173 pcm_config.bitsPerSample & pcm_capabilities.bitsPerSample &&
174 pcm_config.channelMode & pcm_capabilities.channelMode);
175 return (is_pcm_config_valid && is_pcm_config_supported);
176 }
177
IsCodecOffloadingSupported(const CodecConfiguration & codec_config)178 bool IsCodecOffloadingSupported(const CodecConfiguration& codec_config) {
179 CodecCapabilities codec_capability = {};
180 for (auto audio_capability : clientif_->GetAudioCapabilities()) {
181 if (audio_capability.codecCapabilities().codecType ==
182 codec_config.codecType) {
183 codec_capability = audio_capability.codecCapabilities();
184 }
185 }
186 if (codec_capability.codecType != codec_config.codecType) {
187 // codec is unsupported
188 return false;
189 }
190 bool is_codec_config_supported = false;
191 switch (codec_config.codecType) {
192 case CodecType::SBC: {
193 SbcParameters sbc_config = codec_config.config.sbcConfig();
194 SbcParameters sbc_capability =
195 codec_capability.capabilities.sbcCapabilities();
196 is_codec_config_supported =
197 (sbc_config.sampleRate & sbc_capability.sampleRate &&
198 sbc_config.channelMode & sbc_capability.channelMode &&
199 sbc_config.blockLength & sbc_capability.blockLength &&
200 sbc_config.numSubbands & sbc_capability.numSubbands &&
201 sbc_config.allocMethod & sbc_capability.allocMethod &&
202 sbc_config.bitsPerSample & sbc_capability.bitsPerSample &&
203 (sbc_capability.minBitpool <= sbc_config.minBitpool &&
204 sbc_config.minBitpool <= sbc_config.maxBitpool &&
205 sbc_config.maxBitpool <= sbc_capability.maxBitpool));
206 return is_codec_config_supported;
207 }
208 case CodecType::AAC: {
209 AacParameters aac_config = codec_config.config.aacConfig();
210 AacParameters aac_capability =
211 codec_capability.capabilities.aacCapabilities();
212 is_codec_config_supported =
213 (aac_config.objectType & aac_capability.objectType &&
214 aac_config.sampleRate & aac_capability.sampleRate &&
215 aac_config.channelMode & aac_capability.channelMode &&
216 (aac_config.variableBitRateEnabled ==
217 AacVariableBitRate::DISABLED ||
218 aac_capability.variableBitRateEnabled ==
219 AacVariableBitRate::ENABLED) &&
220 aac_config.bitsPerSample & aac_capability.bitsPerSample);
221 return is_codec_config_supported;
222 }
223 case CodecType::LDAC: {
224 LdacParameters ldac_config = codec_config.config.ldacConfig();
225 LdacParameters ldac_capability =
226 codec_capability.capabilities.ldacCapabilities();
227 is_codec_config_supported =
228 (ldac_config.sampleRate & ldac_capability.sampleRate &&
229 ldac_config.channelMode & ldac_capability.channelMode &&
230 ldac_config.bitsPerSample & ldac_capability.bitsPerSample);
231 return is_codec_config_supported;
232 }
233 case CodecType::APTX:
234 [[fallthrough]];
235 case CodecType::APTX_HD: {
236 AptxParameters aptx_config = codec_config.config.aptxConfig();
237 AptxParameters aptx_capability =
238 codec_capability.capabilities.aptxCapabilities();
239 is_codec_config_supported =
240 (aptx_config.sampleRate & aptx_capability.sampleRate &&
241 aptx_config.channelMode & aptx_capability.channelMode &&
242 aptx_config.bitsPerSample & aptx_capability.bitsPerSample);
243 return is_codec_config_supported;
244 }
245 case CodecType::UNKNOWN:
246 return false;
247 }
248 }
249 };
250
251 } // namespace
252
TEST_F(BluetoothAudioClientInterfaceTest,A2dpCodecToHalPcmConfig)253 TEST_F(BluetoothAudioClientInterfaceTest, A2dpCodecToHalPcmConfig) {
254 btav_a2dp_codec_config_t a2dp_codec_config = {};
255 for (auto sample_rate_pair : kSampleRatePairs) {
256 a2dp_codec_config.sample_rate = sample_rate_pair.btav_sample_rate_;
257 for (auto bits_per_sample_pair : kBitsPerSamplePairs) {
258 a2dp_codec_config.bits_per_sample =
259 bits_per_sample_pair.btav_bits_per_sample_;
260 for (auto channel_mode_pair : kChannelModePairs) {
261 a2dp_codec_config.channel_mode = channel_mode_pair.btav_channel_mode_;
262 EXPECT_EQ(A2dpCodecToHalSampleRate(a2dp_codec_config),
263 sample_rate_pair.hal_sample_rate_);
264 EXPECT_EQ(A2dpCodecToHalBitsPerSample(a2dp_codec_config),
265 bits_per_sample_pair.hal_bits_per_sample_);
266 EXPECT_EQ(A2dpCodecToHalChannelMode(a2dp_codec_config),
267 channel_mode_pair.hal_channel_mode_);
268 } // ChannelMode
269 } // BitsPerSampple
270 } // SampleRate
271 }
272
TEST_F(BluetoothAudioClientInterfaceTest,StartAndEndA2dpSoftwareSession)273 TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpSoftwareSession) {
274 test_transport_ =
275 new TestTransport(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
276 clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr);
277 AudioConfiguration audio_config = {};
278 PcmParameters pcm_config = {};
279 for (auto sample_rate_pair : kSampleRatePairs) {
280 pcm_config.sampleRate = sample_rate_pair.hal_sample_rate_;
281 for (auto bits_per_sample_pair : kBitsPerSamplePairs) {
282 pcm_config.bitsPerSample = bits_per_sample_pair.hal_bits_per_sample_;
283 for (auto channel_mode_pair : kChannelModePairs) {
284 pcm_config.channelMode = channel_mode_pair.hal_channel_mode_;
285 audio_config.pcmConfig(pcm_config);
286 clientif_->UpdateAudioConfig(audio_config);
287 if (IsSoftwarePcmParametersSupported(pcm_config)) {
288 EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess);
289 } else {
290 EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess);
291 }
292 EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess);
293 } // ChannelMode
294 } // BitsPerSampple
295 } // SampleRate
296 }
297
298 struct CodecOffloadingPreference {
299 bool is_target_codec_included_;
300 std::vector<btav_a2dp_codec_config_t> preference_;
301 };
302
CodecOffloadingPreferenceGenerator(btav_a2dp_codec_index_t target_codec_index)303 std::vector<CodecOffloadingPreference> CodecOffloadingPreferenceGenerator(
304 btav_a2dp_codec_index_t target_codec_index) {
305 std::vector<CodecOffloadingPreference> codec_offloading_preferences = {
306 {.is_target_codec_included_ = false,
307 .preference_ = std::vector<btav_a2dp_codec_config_t>(0)}};
308 btav_a2dp_codec_config_t a2dp_codec_config = {};
309 for (auto codec_index : codec_indexes) {
310 a2dp_codec_config.codec_type = codec_index;
311 auto duplicated_preferences = codec_offloading_preferences;
312 for (auto iter = duplicated_preferences.begin();
313 iter != duplicated_preferences.end(); ++iter) {
314 if (codec_index == target_codec_index) {
315 iter->is_target_codec_included_ = true;
316 }
317 iter->preference_.push_back(a2dp_codec_config);
318 }
319 codec_offloading_preferences.insert(codec_offloading_preferences.end(),
320 duplicated_preferences.begin(),
321 duplicated_preferences.end());
322 }
323 return codec_offloading_preferences;
324 }
325
SbcCodecConfigurationsGenerator()326 std::vector<CodecConfiguration> SbcCodecConfigurationsGenerator() {
327 std::vector<CodecConfiguration> sbc_codec_configs;
328 CodecConfiguration codec_config = {};
329 SbcBlockLength block_lengths[4] = {
330 SbcBlockLength::BLOCKS_4, SbcBlockLength::BLOCKS_8,
331 SbcBlockLength::BLOCKS_12, SbcBlockLength::BLOCKS_16};
332 SbcNumSubbands num_subbands[2] = {SbcNumSubbands::SUBBAND_4,
333 SbcNumSubbands::SUBBAND_8};
334 SbcAllocMethod alloc_methods[2] = {SbcAllocMethod::ALLOC_MD_S,
335 SbcAllocMethod::ALLOC_MD_L};
336 for (auto sample_rate_pair : kSampleRatePairs) {
337 for (auto bits_per_sample_pair : kBitsPerSamplePairs) {
338 for (auto channel_mode_pair : kChannelModePairs) {
339 for (auto peer_mtu : kPeerMtus) {
340 for (auto block_length : block_lengths) {
341 for (auto num_subband : num_subbands) {
342 for (auto alloc_method : alloc_methods) {
343 codec_config.codecType = CodecType::SBC;
344 codec_config.peerMtu = peer_mtu;
345 codec_config.isScmstEnabled = false;
346 // A2DP_SBC_DEFAULT_BITRATE
347 codec_config.encodedAudioBitrate = 328000;
348 SbcParameters sbc = {
349 .sampleRate = sample_rate_pair.hal_sample_rate_,
350 .channelMode = (channel_mode_pair.hal_channel_mode_ ==
351 ChannelMode::MONO
352 ? SbcChannelMode::MONO
353 : SbcChannelMode::JOINT_STEREO),
354 .blockLength = block_length,
355 .numSubbands = num_subband,
356 .allocMethod = alloc_method,
357 .bitsPerSample = bits_per_sample_pair.hal_bits_per_sample_,
358 .minBitpool = 2,
359 .maxBitpool = 53};
360 codec_config.config.sbcConfig(sbc);
361 sbc_codec_configs.push_back(codec_config);
362 } // SbcAllocMethod
363 } // SbcNumSubbands
364 } // SbcBlockLength
365 } // peerMtu
366 } // ChannelMode
367 } // BitsPerSampple
368 } // SampleRate
369 return sbc_codec_configs;
370 }
371
TEST_F(BluetoothAudioClientInterfaceTest,A2dpSbcCodecOffloadingState)372 TEST_F(BluetoothAudioClientInterfaceTest, A2dpSbcCodecOffloadingState) {
373 test_transport_ =
374 new TestTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
375 clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr);
376 auto sbc_codec_configs = SbcCodecConfigurationsGenerator();
377 for (auto codec_offloading_preference :
378 CodecOffloadingPreferenceGenerator(BTAV_A2DP_CODEC_INDEX_SOURCE_SBC)) {
379 UpdateOffloadingCapabilities(codec_offloading_preference.preference_);
380 for (CodecConfiguration codec_config : sbc_codec_configs) {
381 if (IsCodecOffloadingSupported(codec_config) &&
382 codec_offloading_preference.is_target_codec_included_) {
383 ASSERT_TRUE(IsCodecOffloadingEnabled(codec_config));
384 } else {
385 ASSERT_FALSE(IsCodecOffloadingEnabled(codec_config));
386 }
387 }
388 }
389 }
390
TEST_F(BluetoothAudioClientInterfaceTest,StartAndEndA2dpOffloadSbcSession)391 TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpOffloadSbcSession) {
392 test_transport_ =
393 new TestTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
394 clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr);
395 AudioConfiguration audio_config = {};
396 for (CodecConfiguration codec_config : SbcCodecConfigurationsGenerator()) {
397 audio_config.codecConfig(codec_config);
398 clientif_->UpdateAudioConfig(audio_config);
399 if (IsCodecOffloadingSupported(codec_config)) {
400 EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess);
401 } else {
402 EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess);
403 }
404 EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess);
405 }
406 }
407
AacCodecConfigurationsGenerator()408 std::vector<CodecConfiguration> AacCodecConfigurationsGenerator() {
409 std::vector<CodecConfiguration> aac_codec_configs;
410 CodecConfiguration codec_config = {};
411 AacObjectType object_types[4] = {
412 AacObjectType::MPEG2_LC, AacObjectType::MPEG4_LC,
413 AacObjectType::MPEG4_LTP, AacObjectType::MPEG4_SCALABLE};
414 AacVariableBitRate variable_bitrates[2] = {AacVariableBitRate::DISABLED,
415 AacVariableBitRate::ENABLED};
416 for (auto sample_rate_pair : kSampleRatePairs) {
417 for (auto bits_per_sample_pair : kBitsPerSamplePairs) {
418 for (auto channel_mode_pair : kChannelModePairs) {
419 for (auto peer_mtu : kPeerMtus) {
420 for (auto object_type : object_types) {
421 for (auto variable_bitrate : variable_bitrates) {
422 codec_config.codecType = CodecType::AAC;
423 codec_config.peerMtu = peer_mtu;
424 codec_config.isScmstEnabled = false;
425 // A2DP_AAC_DEFAULT_BITRATE
426 codec_config.encodedAudioBitrate = 320000;
427 AacParameters aac = {
428 .objectType = object_type,
429 .sampleRate = sample_rate_pair.hal_sample_rate_,
430 .channelMode = channel_mode_pair.hal_channel_mode_,
431 .variableBitRateEnabled = variable_bitrate,
432 .bitsPerSample = bits_per_sample_pair.hal_bits_per_sample_};
433 codec_config.config.aacConfig(aac);
434 aac_codec_configs.push_back(codec_config);
435 } // AacVariableBitRate
436 } // AacObjectType
437 } // peerMtu
438 } // ChannelMode
439 } // BitsPerSampple
440 } // SampleRate
441 return aac_codec_configs;
442 }
443
TEST_F(BluetoothAudioClientInterfaceTest,A2dpAacCodecOffloadingState)444 TEST_F(BluetoothAudioClientInterfaceTest, A2dpAacCodecOffloadingState) {
445 test_transport_ =
446 new TestTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
447 clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr);
448 auto aac_codec_configs = AacCodecConfigurationsGenerator();
449 for (auto codec_offloading_preference :
450 CodecOffloadingPreferenceGenerator(BTAV_A2DP_CODEC_INDEX_SOURCE_AAC)) {
451 UpdateOffloadingCapabilities(codec_offloading_preference.preference_);
452 for (CodecConfiguration codec_config : aac_codec_configs) {
453 if (IsCodecOffloadingSupported(codec_config) &&
454 codec_offloading_preference.is_target_codec_included_) {
455 ASSERT_TRUE(IsCodecOffloadingEnabled(codec_config));
456 } else {
457 ASSERT_FALSE(IsCodecOffloadingEnabled(codec_config));
458 }
459 }
460 }
461 }
462
TEST_F(BluetoothAudioClientInterfaceTest,StartAndEndA2dpOffloadAacSession)463 TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpOffloadAacSession) {
464 test_transport_ =
465 new TestTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
466 clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr);
467 AudioConfiguration audio_config = {};
468 for (CodecConfiguration codec_config : AacCodecConfigurationsGenerator()) {
469 audio_config.codecConfig(codec_config);
470 clientif_->UpdateAudioConfig(audio_config);
471 if (IsCodecOffloadingSupported(codec_config)) {
472 EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess);
473 } else {
474 EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess);
475 }
476 EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess);
477 }
478 }
479
LdacCodecConfigurationsGenerator()480 std::vector<CodecConfiguration> LdacCodecConfigurationsGenerator() {
481 std::vector<CodecConfiguration> ldac_codec_configs;
482 CodecConfiguration codec_config = {};
483 LdacQualityIndex quality_indexes[4] = {
484 LdacQualityIndex::QUALITY_HIGH, LdacQualityIndex::QUALITY_MID,
485 LdacQualityIndex::QUALITY_LOW, LdacQualityIndex::QUALITY_ABR};
486 for (auto sample_rate_pair : kSampleRatePairs) {
487 for (auto bits_per_sample_pair : kBitsPerSamplePairs) {
488 for (auto channel_mode_pair : kChannelModePairs) {
489 for (auto peer_mtu : kPeerMtus) {
490 for (auto quality_index : quality_indexes) {
491 codec_config.codecType = CodecType::LDAC;
492 codec_config.peerMtu = peer_mtu;
493 codec_config.isScmstEnabled = false;
494 codec_config.encodedAudioBitrate = 990000;
495 LdacParameters ldac = {
496 .sampleRate = sample_rate_pair.hal_sample_rate_,
497 .channelMode =
498 (channel_mode_pair.hal_channel_mode_ == ChannelMode::MONO
499 ? LdacChannelMode::MONO
500 : LdacChannelMode::STEREO),
501 .qualityIndex = quality_index,
502 .bitsPerSample = bits_per_sample_pair.hal_bits_per_sample_};
503 codec_config.config.ldacConfig(ldac);
504 ldac_codec_configs.push_back(codec_config);
505 } // LdacQualityIndex
506 } // peerMtu
507 } // ChannelMode
508 } // BitsPerSampple
509 } // SampleRate
510 return ldac_codec_configs;
511 }
512
TEST_F(BluetoothAudioClientInterfaceTest,A2dpLdacCodecOffloadingState)513 TEST_F(BluetoothAudioClientInterfaceTest, A2dpLdacCodecOffloadingState) {
514 test_transport_ =
515 new TestTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
516 clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr);
517 auto ldac_codec_configs = LdacCodecConfigurationsGenerator();
518 for (auto codec_offloading_preference :
519 CodecOffloadingPreferenceGenerator(BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC)) {
520 UpdateOffloadingCapabilities(codec_offloading_preference.preference_);
521 for (CodecConfiguration codec_config : ldac_codec_configs) {
522 if (IsCodecOffloadingSupported(codec_config) &&
523 codec_offloading_preference.is_target_codec_included_) {
524 ASSERT_TRUE(IsCodecOffloadingEnabled(codec_config));
525 } else {
526 ASSERT_FALSE(IsCodecOffloadingEnabled(codec_config));
527 }
528 }
529 }
530 }
531
TEST_F(BluetoothAudioClientInterfaceTest,StartAndEndA2dpOffloadLdacSession)532 TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpOffloadLdacSession) {
533 test_transport_ =
534 new TestTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
535 clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr);
536 AudioConfiguration audio_config = {};
537 for (CodecConfiguration codec_config : LdacCodecConfigurationsGenerator()) {
538 audio_config.codecConfig(codec_config);
539 clientif_->UpdateAudioConfig(audio_config);
540 if (IsCodecOffloadingSupported(codec_config)) {
541 EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess);
542 } else {
543 EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess);
544 }
545 EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess);
546 }
547 }
548
AptxCodecConfigurationsGenerator(CodecType codec_type)549 std::vector<CodecConfiguration> AptxCodecConfigurationsGenerator(
550 CodecType codec_type) {
551 std::vector<CodecConfiguration> aptx_codec_configs;
552 if (codec_type != CodecType::APTX && codec_type != CodecType::APTX_HD)
553 return aptx_codec_configs;
554 CodecConfiguration codec_config = {};
555 for (auto sample_rate_pair : kSampleRatePairs) {
556 for (auto bits_per_sample_pair : kBitsPerSamplePairs) {
557 for (auto channel_mode_pair : kChannelModePairs) {
558 for (auto peer_mtu : kPeerMtus) {
559 codec_config.codecType = codec_type;
560 codec_config.peerMtu = peer_mtu;
561 codec_config.isScmstEnabled = false;
562 codec_config.encodedAudioBitrate =
563 (codec_type == CodecType::APTX ? 352000 : 576000);
564 AptxParameters aptx = {
565 .sampleRate = sample_rate_pair.hal_sample_rate_,
566 .channelMode = channel_mode_pair.hal_channel_mode_,
567 .bitsPerSample = bits_per_sample_pair.hal_bits_per_sample_};
568 codec_config.config.aptxConfig(aptx);
569 aptx_codec_configs.push_back(codec_config);
570 } // peerMtu
571 } // ChannelMode
572 } // BitsPerSampple
573 } // SampleRate
574 return aptx_codec_configs;
575 }
576
TEST_F(BluetoothAudioClientInterfaceTest,A2dpAptxCodecOffloadingState)577 TEST_F(BluetoothAudioClientInterfaceTest, A2dpAptxCodecOffloadingState) {
578 test_transport_ =
579 new TestTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
580 clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr);
581 auto aptx_codec_configs = AptxCodecConfigurationsGenerator(CodecType::APTX);
582 for (auto codec_offloading_preference :
583 CodecOffloadingPreferenceGenerator(BTAV_A2DP_CODEC_INDEX_SOURCE_APTX)) {
584 UpdateOffloadingCapabilities(codec_offloading_preference.preference_);
585 for (CodecConfiguration codec_config : aptx_codec_configs) {
586 if (IsCodecOffloadingSupported(codec_config) &&
587 codec_offloading_preference.is_target_codec_included_) {
588 ASSERT_TRUE(IsCodecOffloadingEnabled(codec_config));
589 } else {
590 ASSERT_FALSE(IsCodecOffloadingEnabled(codec_config));
591 }
592 }
593 }
594 }
595
TEST_F(BluetoothAudioClientInterfaceTest,StartAndEndA2dpOffloadAptxSession)596 TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpOffloadAptxSession) {
597 test_transport_ =
598 new TestTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
599 clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr);
600 AudioConfiguration audio_config = {};
601 for (CodecConfiguration codec_config :
602 AptxCodecConfigurationsGenerator(CodecType::APTX)) {
603 audio_config.codecConfig(codec_config);
604 clientif_->UpdateAudioConfig(audio_config);
605 if (IsCodecOffloadingSupported(codec_config)) {
606 EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess);
607 } else {
608 EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess);
609 }
610 EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess);
611 }
612 }
613
TEST_F(BluetoothAudioClientInterfaceTest,A2dpAptxHdCodecOffloadingState)614 TEST_F(BluetoothAudioClientInterfaceTest, A2dpAptxHdCodecOffloadingState) {
615 test_transport_ =
616 new TestTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
617 clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr);
618 auto aptx_hd_codec_configs =
619 AptxCodecConfigurationsGenerator(CodecType::APTX_HD);
620 for (auto codec_offloading_preference : CodecOffloadingPreferenceGenerator(
621 BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD)) {
622 UpdateOffloadingCapabilities(codec_offloading_preference.preference_);
623 for (CodecConfiguration codec_config : aptx_hd_codec_configs) {
624 if (IsCodecOffloadingSupported(codec_config) &&
625 codec_offloading_preference.is_target_codec_included_) {
626 ASSERT_TRUE(IsCodecOffloadingEnabled(codec_config));
627 } else {
628 ASSERT_FALSE(IsCodecOffloadingEnabled(codec_config));
629 }
630 }
631 }
632 }
633
TEST_F(BluetoothAudioClientInterfaceTest,StartAndEndA2dpOffloadAptxHdSession)634 TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpOffloadAptxHdSession) {
635 test_transport_ =
636 new TestTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
637 clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr);
638 AudioConfiguration audio_config = {};
639 for (CodecConfiguration codec_config :
640 AptxCodecConfigurationsGenerator(CodecType::APTX_HD)) {
641 audio_config.codecConfig(codec_config);
642 clientif_->UpdateAudioConfig(audio_config);
643 if (IsCodecOffloadingSupported(codec_config)) {
644 EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess);
645 } else {
646 EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess);
647 }
648 EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess);
649 }
650 }
651
TEST_F(BluetoothAudioClientInterfaceTest,StartAndEndA2dpOffloadUnknownSession)652 TEST_F(BluetoothAudioClientInterfaceTest,
653 StartAndEndA2dpOffloadUnknownSession) {
654 test_transport_ =
655 new TestTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
656 clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr);
657 AudioConfiguration audio_config = {};
658 CodecConfiguration codec_config = {};
659 codec_config.codecType = CodecType::UNKNOWN;
660 codec_config.peerMtu = 1005;
661 codec_config.isScmstEnabled = false;
662 codec_config.encodedAudioBitrate = 328000;
663 codec_config.config = {};
664 audio_config.codecConfig(codec_config);
665 clientif_->UpdateAudioConfig(audio_config);
666 if (IsCodecOffloadingSupported(codec_config)) {
667 EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess);
668 } else {
669 EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess);
670 }
671 EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess);
672 }
673
TEST_F(BluetoothAudioClientInterfaceTest,StartAndEndHearingAidSoftwareSession)674 TEST_F(BluetoothAudioClientInterfaceTest,
675 StartAndEndHearingAidSoftwareSession) {
676 test_transport_ =
677 new TestTransport(SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
678 clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr);
679 AudioConfiguration audio_config = {};
680 PcmParameters pcm_config = {};
681 for (auto sample_rate_pair : kSampleRatePairs) {
682 pcm_config.sampleRate = sample_rate_pair.hal_sample_rate_;
683 for (auto bits_per_sample_pair : kBitsPerSamplePairs) {
684 pcm_config.bitsPerSample = bits_per_sample_pair.hal_bits_per_sample_;
685 for (auto channel_mode_pair : kChannelModePairs) {
686 pcm_config.channelMode = channel_mode_pair.hal_channel_mode_;
687 audio_config.pcmConfig(pcm_config);
688 clientif_->UpdateAudioConfig(audio_config);
689 if (IsSoftwarePcmParametersSupported(pcm_config)) {
690 EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess);
691 } else {
692 EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess);
693 }
694 EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess);
695 } // ChannelMode
696 } // BitsPerSampple
697 } // SampleRate
698 }
699