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