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