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