• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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