• 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 #include <gtest/gtest.h>
18 
19 #include "client_interface.h"
20 
21 namespace {
22 
23 using ::android::hardware::bluetooth::audio::V2_0::AacObjectType;
24 using ::android::hardware::bluetooth::audio::V2_0::AacParameters;
25 using ::android::hardware::bluetooth::audio::V2_0::AacVariableBitRate;
26 using ::android::hardware::bluetooth::audio::V2_0::AptxParameters;
27 using ::android::hardware::bluetooth::audio::V2_0::CodecCapabilities;
28 using ::android::hardware::bluetooth::audio::V2_0::CodecConfiguration;
29 using ::android::hardware::bluetooth::audio::V2_0::CodecType;
30 using ::android::hardware::bluetooth::audio::V2_0::LdacChannelMode;
31 using ::android::hardware::bluetooth::audio::V2_0::LdacParameters;
32 using ::android::hardware::bluetooth::audio::V2_0::LdacQualityIndex;
33 using ::android::hardware::bluetooth::audio::V2_0::SbcAllocMethod;
34 using ::android::hardware::bluetooth::audio::V2_0::SbcBlockLength;
35 using ::android::hardware::bluetooth::audio::V2_0::SbcChannelMode;
36 using ::android::hardware::bluetooth::audio::V2_0::SbcNumSubbands;
37 using ::android::hardware::bluetooth::audio::V2_0::SbcParameters;
38 
39 using ::bluetooth::audio::AudioCapabilities;
40 using ::bluetooth::audio::AudioConfiguration;
41 using ::bluetooth::audio::BitsPerSample;
42 using ::bluetooth::audio::BluetoothAudioClientInterface;
43 using ::bluetooth::audio::BluetoothAudioStatus;
44 using ::bluetooth::audio::ChannelMode;
45 using ::bluetooth::audio::PcmParameters;
46 using ::bluetooth::audio::SampleRate;
47 using ::bluetooth::audio::SessionType;
48 using ::testing::Test;
49 
50 constexpr SampleRate kSampleRates[9] = {
51     SampleRate::RATE_UNKNOWN, SampleRate::RATE_44100, SampleRate::RATE_48000,
52     SampleRate::RATE_88200,   SampleRate::RATE_96000, SampleRate::RATE_176400,
53     SampleRate::RATE_192000,  SampleRate::RATE_16000, SampleRate::RATE_24000};
54 constexpr BitsPerSample kBitsPerSamples[4] = {
55     BitsPerSample::BITS_UNKNOWN, BitsPerSample::BITS_16, BitsPerSample::BITS_24,
56     BitsPerSample::BITS_32};
57 constexpr ChannelMode kChannelModes[3] = {
58     ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
59 constexpr uint16_t kPeerMtus[5] = {660, 663, 883, 1005, 1500};
60 
61 class TestTransport : public bluetooth::audio::IBluetoothTransportInstance {
62  private:
63   static constexpr uint64_t kRemoteDelayReportMs = 200;
64 
65  public:
TestTransport(SessionType session_type)66   TestTransport(SessionType session_type)
67       : bluetooth::audio::IBluetoothTransportInstance(session_type, {}){};
StartRequest()68   bluetooth::audio::BluetoothAudioCtrlAck StartRequest() {
69     return bluetooth::audio::BluetoothAudioCtrlAck::SUCCESS_FINISHED;
70   }
SuspendRequest()71   bluetooth::audio::BluetoothAudioCtrlAck SuspendRequest() {
72     return bluetooth::audio::BluetoothAudioCtrlAck::SUCCESS_FINISHED;
73   }
StopRequest()74   void StopRequest() {}
GetPresentationPosition(uint64_t * remote_delay_report_ns,uint64_t * total_bytes_readed,timespec * data_position)75   bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
76                                uint64_t* total_bytes_readed,
77                                timespec* data_position) {
78     if (remote_delay_report_ns) {
79       *remote_delay_report_ns = kRemoteDelayReportMs * 1000000;
80     }
81     if (total_bytes_readed) {
82       *total_bytes_readed = 0;
83     }
84     if (data_position) {
85       clock_gettime(CLOCK_MONOTONIC, data_position);
86     }
87     return true;
88   }
MetadataChanged(const source_metadata_t & source_metadata __unused)89   void MetadataChanged(const source_metadata_t& source_metadata __unused) {}
ResetPresentationPosition()90   void ResetPresentationPosition(){};
LogBytesRead(size_t bytes_readed __unused)91   void LogBytesRead(size_t bytes_readed __unused){};
92 };
93 
94 class BluetoothAudioClientInterfaceTest : public Test {
95  protected:
96   TestTransport* test_transport_;
97   BluetoothAudioClientInterface* clientif_;
98 
99   static constexpr int kClientIfReturnSuccess = 0;
100 
SetUp()101   virtual void SetUp() override {}
102 
TearDown()103   virtual void TearDown() override {
104     clientif_ = nullptr;
105     test_transport_ = nullptr;
106   }
107 
IsSoftwarePcmParametersSupported(const PcmParameters & pcm_config)108   bool IsSoftwarePcmParametersSupported(const PcmParameters& pcm_config) {
109     const std::vector<AudioCapabilities>& capabilities =
110         clientif_->GetAudioCapabilities();
111     PcmParameters pcm_capabilities = capabilities[0].pcmCapabilities();
112     bool is_pcm_config_valid =
113         (pcm_config.sampleRate != SampleRate::RATE_UNKNOWN &&
114          pcm_config.bitsPerSample != BitsPerSample::BITS_UNKNOWN &&
115          pcm_config.channelMode != ChannelMode::UNKNOWN);
116     bool is_pcm_config_supported =
117         (pcm_config.sampleRate & pcm_capabilities.sampleRate &&
118          pcm_config.bitsPerSample & pcm_capabilities.bitsPerSample &&
119          pcm_config.channelMode & pcm_capabilities.channelMode);
120     return (is_pcm_config_valid && is_pcm_config_supported);
121   }
122 
IsOffloadCodecConfigurationSupported(const CodecConfiguration & codec_config)123   bool IsOffloadCodecConfigurationSupported(
124       const CodecConfiguration& codec_config) {
125     CodecCapabilities codec_capability = {};
126     for (auto audio_capability : clientif_->GetAudioCapabilities()) {
127       if (audio_capability.codecCapabilities().codecType ==
128           codec_config.codecType) {
129         codec_capability = audio_capability.codecCapabilities();
130       }
131     }
132     if (codec_capability.codecType != codec_config.codecType) {
133       // codec is unsupported
134       return false;
135     }
136     bool is_codec_config_supported = false;
137     switch (codec_config.codecType) {
138       case CodecType::SBC: {
139         SbcParameters sbc_config = codec_config.config.sbcConfig();
140         SbcParameters sbc_capability =
141             codec_capability.capabilities.sbcCapabilities();
142         is_codec_config_supported =
143             (sbc_config.sampleRate & sbc_capability.sampleRate &&
144              sbc_config.channelMode & sbc_capability.channelMode &&
145              sbc_config.blockLength & sbc_capability.blockLength &&
146              sbc_config.numSubbands & sbc_capability.numSubbands &&
147              sbc_config.allocMethod & sbc_capability.allocMethod &&
148              sbc_config.bitsPerSample & sbc_capability.bitsPerSample &&
149              (sbc_capability.minBitpool <= sbc_config.minBitpool &&
150               sbc_config.minBitpool <= sbc_config.maxBitpool &&
151               sbc_config.maxBitpool <= sbc_capability.maxBitpool));
152         return is_codec_config_supported;
153       }
154       case CodecType::AAC: {
155         AacParameters aac_config = codec_config.config.aacConfig();
156         AacParameters aac_capability =
157             codec_capability.capabilities.aacCapabilities();
158         is_codec_config_supported =
159             (aac_config.objectType & aac_capability.objectType &&
160              aac_config.sampleRate & aac_capability.sampleRate &&
161              aac_config.channelMode & aac_capability.channelMode &&
162              (aac_config.variableBitRateEnabled ==
163                   AacVariableBitRate::DISABLED ||
164               aac_capability.variableBitRateEnabled ==
165                   AacVariableBitRate::ENABLED) &&
166              aac_config.bitsPerSample & aac_capability.bitsPerSample);
167         return is_codec_config_supported;
168       }
169       case CodecType::LDAC: {
170         LdacParameters ldac_config = codec_config.config.ldacConfig();
171         LdacParameters ldac_capability =
172             codec_capability.capabilities.ldacCapabilities();
173         is_codec_config_supported =
174             (ldac_config.sampleRate & ldac_capability.sampleRate &&
175              ldac_config.channelMode & ldac_capability.channelMode &&
176              ldac_config.bitsPerSample & ldac_capability.bitsPerSample);
177         return is_codec_config_supported;
178       }
179       case CodecType::APTX:
180         [[fallthrough]];
181       case CodecType::APTX_HD: {
182         AptxParameters aptx_config = codec_config.config.aptxConfig();
183         AptxParameters aptx_capability =
184             codec_capability.capabilities.aptxCapabilities();
185         is_codec_config_supported =
186             (aptx_config.sampleRate & aptx_capability.sampleRate &&
187              aptx_config.channelMode & aptx_capability.channelMode &&
188              aptx_config.bitsPerSample & aptx_capability.bitsPerSample);
189         return is_codec_config_supported;
190       }
191       case CodecType::UNKNOWN:
192         return false;
193     }
194   }
195 };
196 
197 }  // namespace
198 
TEST_F(BluetoothAudioClientInterfaceTest,StartAndEndA2dpSoftwareSession)199 TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpSoftwareSession) {
200   test_transport_ =
201       new TestTransport(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
202   clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr);
203   AudioConfiguration audio_config = {};
204   PcmParameters pcm_config = {};
205   for (auto sample_rate : kSampleRates) {
206     pcm_config.sampleRate = sample_rate;
207     for (auto bits_per_sample : kBitsPerSamples) {
208       pcm_config.bitsPerSample = bits_per_sample;
209       for (auto channel_mode : kChannelModes) {
210         pcm_config.channelMode = channel_mode;
211         audio_config.pcmConfig(pcm_config);
212         clientif_->UpdateAudioConfig(audio_config);
213         if (IsSoftwarePcmParametersSupported(pcm_config)) {
214           EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess);
215         } else {
216           EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess);
217         }
218         EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess);
219       }  // ChannelMode
220     }    // BitsPerSampple
221   }      // SampleRate
222 }
223 
TEST_F(BluetoothAudioClientInterfaceTest,StartAndEndA2dpOffloadSbcSession)224 TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpOffloadSbcSession) {
225   test_transport_ =
226       new TestTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
227   clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr);
228   AudioConfiguration audio_config = {};
229   CodecConfiguration codec_config = {};
230   SbcBlockLength block_lengths[4] = {
231       SbcBlockLength::BLOCKS_4, SbcBlockLength::BLOCKS_8,
232       SbcBlockLength::BLOCKS_12, SbcBlockLength::BLOCKS_16};
233   SbcNumSubbands num_subbands[2] = {SbcNumSubbands::SUBBAND_4,
234                                     SbcNumSubbands::SUBBAND_8};
235   SbcAllocMethod alloc_methods[2] = {SbcAllocMethod::ALLOC_MD_S,
236                                      SbcAllocMethod::ALLOC_MD_L};
237   for (auto sample_rate : kSampleRates) {
238     for (auto bits_per_sample : kBitsPerSamples) {
239       for (auto channel_mode : kChannelModes) {
240         for (auto peer_mtu : kPeerMtus) {
241           for (auto block_length : block_lengths) {
242             for (auto num_subband : num_subbands) {
243               for (auto alloc_method : alloc_methods) {
244                 codec_config.codecType = CodecType::SBC;
245                 codec_config.peerMtu = peer_mtu;
246                 codec_config.isScmstEnabled = false;
247                 // A2DP_SBC_DEFAULT_BITRATE
248                 codec_config.encodedAudioBitrate = 328000;
249                 SbcParameters sbc = {
250                     .sampleRate = sample_rate,
251                     .channelMode = (channel_mode == ChannelMode::MONO
252                                         ? SbcChannelMode::MONO
253                                         : SbcChannelMode::JOINT_STEREO),
254                     .blockLength = block_length,
255                     .numSubbands = num_subband,
256                     .allocMethod = alloc_method,
257                     .bitsPerSample = bits_per_sample,
258                     .minBitpool = 2,
259                     .maxBitpool = 53};
260                 codec_config.config.sbcConfig(sbc);
261                 audio_config.codecConfig(codec_config);
262                 clientif_->UpdateAudioConfig(audio_config);
263                 if (IsOffloadCodecConfigurationSupported(codec_config)) {
264                   EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess);
265                 } else {
266                   EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess);
267                 }
268                 EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess);
269               }  // SbcAllocMethod
270             }    // SbcNumSubbands
271           }      // SbcBlockLength
272         }        // peerMtu
273       }          // ChannelMode
274     }            // BitsPerSampple
275   }              // SampleRate
276 }
277 
TEST_F(BluetoothAudioClientInterfaceTest,StartAndEndA2dpOffloadAacSession)278 TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpOffloadAacSession) {
279   test_transport_ =
280       new TestTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
281   clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr);
282   AudioConfiguration audio_config = {};
283   CodecConfiguration codec_config = {};
284   AacObjectType object_types[4] = {
285       AacObjectType::MPEG2_LC, AacObjectType::MPEG4_LC,
286       AacObjectType::MPEG4_LTP, AacObjectType::MPEG4_SCALABLE};
287   AacVariableBitRate variable_bitrates[2] = {AacVariableBitRate::DISABLED,
288                                              AacVariableBitRate::ENABLED};
289   for (auto sample_rate : kSampleRates) {
290     for (auto bits_per_sample : kBitsPerSamples) {
291       for (auto channel_mode : kChannelModes) {
292         for (auto peer_mtu : kPeerMtus) {
293           for (auto object_type : object_types) {
294             for (auto variable_bitrate : variable_bitrates) {
295               codec_config.codecType = CodecType::AAC;
296               codec_config.peerMtu = peer_mtu;
297               codec_config.isScmstEnabled = false;
298               // A2DP_AAC_DEFAULT_BITRATE
299               codec_config.encodedAudioBitrate = 320000;
300               AacParameters aac = {.objectType = object_type,
301                                    .sampleRate = sample_rate,
302                                    .channelMode = channel_mode,
303                                    .variableBitRateEnabled = variable_bitrate,
304                                    .bitsPerSample = bits_per_sample};
305               codec_config.config.aacConfig(aac);
306               audio_config.codecConfig(codec_config);
307               clientif_->UpdateAudioConfig(audio_config);
308               if (IsOffloadCodecConfigurationSupported(codec_config)) {
309                 EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess);
310               } else {
311                 EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess);
312               }
313               EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess);
314             }  // AacVariableBitRate
315           }    // AacObjectType
316         }      // peerMtu
317       }        // ChannelMode
318     }          // BitsPerSampple
319   }            // SampleRate
320 }
321 
TEST_F(BluetoothAudioClientInterfaceTest,StartAndEndA2dpOffloadLdacSession)322 TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpOffloadLdacSession) {
323   test_transport_ =
324       new TestTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
325   clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr);
326   AudioConfiguration audio_config = {};
327   CodecConfiguration codec_config = {};
328   LdacQualityIndex quality_indexes[4] = {
329       LdacQualityIndex::QUALITY_HIGH, LdacQualityIndex::QUALITY_MID,
330       LdacQualityIndex::QUALITY_LOW, LdacQualityIndex::QUALITY_ABR};
331   for (auto sample_rate : kSampleRates) {
332     for (auto bits_per_sample : kBitsPerSamples) {
333       for (auto channel_mode : kChannelModes) {
334         for (auto peer_mtu : kPeerMtus) {
335           for (auto quality_index : quality_indexes) {
336             codec_config.codecType = CodecType::LDAC;
337             codec_config.peerMtu = peer_mtu;
338             codec_config.isScmstEnabled = false;
339             codec_config.encodedAudioBitrate = 990000;
340             LdacParameters ldac = {
341                 .sampleRate = sample_rate,
342                 .channelMode = (channel_mode == ChannelMode::MONO
343                                     ? LdacChannelMode::MONO
344                                     : LdacChannelMode::STEREO),
345                 .qualityIndex = quality_index,
346                 .bitsPerSample = bits_per_sample};
347             codec_config.config.ldacConfig(ldac);
348             audio_config.codecConfig(codec_config);
349             clientif_->UpdateAudioConfig(audio_config);
350             if (IsOffloadCodecConfigurationSupported(codec_config)) {
351               EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess);
352             } else {
353               EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess);
354             }
355             EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess);
356           }  // LdacQualityIndex
357         }    // peerMtu
358       }      // ChannelMode
359     }        // BitsPerSampple
360   }          // SampleRate
361 }
362 
TEST_F(BluetoothAudioClientInterfaceTest,StartAndEndA2dpOffloadAptxSession)363 TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpOffloadAptxSession) {
364   test_transport_ =
365       new TestTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
366   clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr);
367   AudioConfiguration audio_config = {};
368   CodecConfiguration codec_config = {};
369   for (auto sample_rate : kSampleRates) {
370     for (auto bits_per_sample : kBitsPerSamples) {
371       for (auto channel_mode : kChannelModes) {
372         for (auto peer_mtu : kPeerMtus) {
373           codec_config.codecType = CodecType::APTX;
374           codec_config.peerMtu = peer_mtu;
375           codec_config.isScmstEnabled = false;
376           codec_config.encodedAudioBitrate = 352000;
377           AptxParameters aptx = {.sampleRate = sample_rate,
378                                  .channelMode = channel_mode,
379                                  .bitsPerSample = bits_per_sample};
380           codec_config.config.aptxConfig(aptx);
381           audio_config.codecConfig(codec_config);
382           clientif_->UpdateAudioConfig(audio_config);
383           if (IsOffloadCodecConfigurationSupported(codec_config)) {
384             EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess);
385           } else {
386             EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess);
387           }
388           EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess);
389         }  // peerMtu
390       }    // ChannelMode
391     }      // BitsPerSampple
392   }        // SampleRate
393 }
394 
TEST_F(BluetoothAudioClientInterfaceTest,StartAndEndA2dpOffloadAptxHdSession)395 TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpOffloadAptxHdSession) {
396   test_transport_ =
397       new TestTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
398   clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr);
399   AudioConfiguration audio_config = {};
400   CodecConfiguration codec_config = {};
401   for (auto sample_rate : kSampleRates) {
402     for (auto bits_per_sample : kBitsPerSamples) {
403       for (auto channel_mode : kChannelModes) {
404         for (auto peer_mtu : kPeerMtus) {
405           codec_config.codecType = CodecType::APTX_HD;
406           codec_config.peerMtu = peer_mtu;
407           codec_config.isScmstEnabled = false;
408           codec_config.encodedAudioBitrate = 576000;
409           AptxParameters aptx = {.sampleRate = sample_rate,
410                                  .channelMode = channel_mode,
411                                  .bitsPerSample = bits_per_sample};
412           codec_config.config.aptxConfig(aptx);
413           audio_config.codecConfig(codec_config);
414           clientif_->UpdateAudioConfig(audio_config);
415           if (IsOffloadCodecConfigurationSupported(codec_config)) {
416             EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess);
417           } else {
418             EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess);
419           }
420           EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess);
421         }  // peerMtu
422       }    // ChannelMode
423     }      // BitsPerSampple
424   }        // SampleRate
425 }
426 
TEST_F(BluetoothAudioClientInterfaceTest,StartAndEndA2dpOffloadUnknownSession)427 TEST_F(BluetoothAudioClientInterfaceTest,
428        StartAndEndA2dpOffloadUnknownSession) {
429   test_transport_ =
430       new TestTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
431   clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr);
432   AudioConfiguration audio_config = {};
433   CodecConfiguration codec_config = {};
434   codec_config.codecType = CodecType::UNKNOWN;
435   codec_config.peerMtu = 1005;
436   codec_config.isScmstEnabled = false;
437   codec_config.encodedAudioBitrate = 328000;
438   codec_config.config = {};
439   audio_config.codecConfig(codec_config);
440   clientif_->UpdateAudioConfig(audio_config);
441   if (IsOffloadCodecConfigurationSupported(codec_config)) {
442     EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess);
443   } else {
444     EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess);
445   }
446   EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess);
447 }
448 
TEST_F(BluetoothAudioClientInterfaceTest,StartAndEndHearingAidSoftwareSession)449 TEST_F(BluetoothAudioClientInterfaceTest,
450        StartAndEndHearingAidSoftwareSession) {
451   test_transport_ =
452       new TestTransport(SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
453   clientif_ = new BluetoothAudioClientInterface(test_transport_, nullptr);
454   AudioConfiguration audio_config = {};
455   PcmParameters pcm_config = {};
456   for (auto sample_rate : kSampleRates) {
457     pcm_config.sampleRate = sample_rate;
458     for (auto bits_per_sample : kBitsPerSamples) {
459       pcm_config.bitsPerSample = bits_per_sample;
460       for (auto channel_mode : kChannelModes) {
461         pcm_config.channelMode = channel_mode;
462         audio_config.pcmConfig(pcm_config);
463         clientif_->UpdateAudioConfig(audio_config);
464         if (IsSoftwarePcmParametersSupported(pcm_config)) {
465           EXPECT_EQ(clientif_->StartSession(), kClientIfReturnSuccess);
466         } else {
467           EXPECT_NE(clientif_->StartSession(), kClientIfReturnSuccess);
468         }
469         EXPECT_EQ(clientif_->EndSession(), kClientIfReturnSuccess);
470       }  // ChannelMode
471     }    // BitsPerSampple
472   }      // SampleRate
473 }
474