1 /*
2 * Copyright 2020 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_audio_hidl_hal_test"
18
19 #include <VtsHalHidlTargetCallbackBase.h>
20 #include <android-base/logging.h>
21 #include <android/hardware/bluetooth/audio/2.0/IBluetoothAudioPort.h>
22 #include <android/hardware/bluetooth/audio/2.1/IBluetoothAudioProvider.h>
23 #include <android/hardware/bluetooth/audio/2.1/IBluetoothAudioProvidersFactory.h>
24 #include <fmq/MessageQueue.h>
25 #include <gtest/gtest.h>
26 #include <hidl/GtestPrinter.h>
27 #include <hidl/MQDescriptor.h>
28 #include <hidl/ServiceManagement.h>
29 #include <utils/Log.h>
30
31 using ::android::sp;
32 using ::android::hardware::hidl_vec;
33 using ::android::hardware::kSynchronizedReadWrite;
34 using ::android::hardware::MessageQueue;
35 using ::android::hardware::Return;
36 using ::android::hardware::Void;
37 using ::android::hardware::audio::common::V5_0::SourceMetadata;
38 using ::android::hardware::bluetooth::audio::V2_0::AacObjectType;
39 using ::android::hardware::bluetooth::audio::V2_0::AacParameters;
40 using ::android::hardware::bluetooth::audio::V2_0::AacVariableBitRate;
41 using ::android::hardware::bluetooth::audio::V2_0::AptxParameters;
42 using ::android::hardware::bluetooth::audio::V2_0::AudioCapabilities;
43 using ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration;
44 using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
45 using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
46 using ::android::hardware::bluetooth::audio::V2_0::CodecCapabilities;
47 using ::android::hardware::bluetooth::audio::V2_0::CodecConfiguration;
48 using ::android::hardware::bluetooth::audio::V2_0::CodecType;
49 using ::android::hardware::bluetooth::audio::V2_0::IBluetoothAudioPort;
50 using ::android::hardware::bluetooth::audio::V2_0::IBluetoothAudioProvider;
51 using ::android::hardware::bluetooth::audio::V2_0::LdacChannelMode;
52 using ::android::hardware::bluetooth::audio::V2_0::LdacParameters;
53 using ::android::hardware::bluetooth::audio::V2_0::LdacQualityIndex;
54 using ::android::hardware::bluetooth::audio::V2_0::PcmParameters;
55 using ::android::hardware::bluetooth::audio::V2_0::SbcAllocMethod;
56 using ::android::hardware::bluetooth::audio::V2_0::SbcBlockLength;
57 using ::android::hardware::bluetooth::audio::V2_0::SbcChannelMode;
58 using ::android::hardware::bluetooth::audio::V2_0::SbcNumSubbands;
59 using ::android::hardware::bluetooth::audio::V2_0::SbcParameters;
60 using ::android::hardware::bluetooth::audio::V2_0::SessionType;
61 using ::android::hardware::bluetooth::audio::V2_1::
62 IBluetoothAudioProvidersFactory;
63 using ::android::hardware::bluetooth::audio::V2_1::SampleRate;
64
65 using DataMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
66 using BluetoothAudioStatus =
67 ::android::hardware::bluetooth::audio::V2_0::Status;
68 using CodecSpecificConfig = ::android::hardware::bluetooth::audio::V2_0::
69 CodecConfiguration::CodecSpecific;
70
71 namespace {
72 constexpr android::hardware::bluetooth::audio::V2_0::SampleRate
73 a2dp_sample_rates[5] = {
74 android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_UNKNOWN,
75 android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_44100,
76 android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_48000,
77 android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_88200,
78 android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_96000};
79 constexpr BitsPerSample a2dp_bits_per_samples[4] = {
80 BitsPerSample::BITS_UNKNOWN, BitsPerSample::BITS_16, BitsPerSample::BITS_24,
81 BitsPerSample::BITS_32};
82 constexpr ChannelMode a2dp_channel_modes[3] = {
83 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
84 constexpr CodecType a2dp_codec_types[6] = {CodecType::UNKNOWN, CodecType::SBC,
85 CodecType::AAC, CodecType::APTX,
86 CodecType::APTX_HD, CodecType::LDAC};
87
88 template <typename T>
ExtractValuesFromBitmask(T bitmasks,uint32_t bitfield,bool supported)89 std::vector<T> ExtractValuesFromBitmask(T bitmasks, uint32_t bitfield,
90 bool supported) {
91 std::vector<T> retval;
92 if (!supported) {
93 retval.push_back(static_cast<T>(bitfield));
94 }
95 uint32_t test_bit = 0x00000001;
96 while (test_bit <= static_cast<uint32_t>(bitmasks) && test_bit <= bitfield) {
97 if ((bitfield & test_bit)) {
98 if ((!(bitmasks & test_bit) && !supported) ||
99 ((bitmasks & test_bit) && supported)) {
100 retval.push_back(static_cast<T>(test_bit));
101 }
102 }
103 if (test_bit == 0x80000000) {
104 break;
105 }
106 test_bit <<= 1;
107 }
108 return retval;
109 }
110 } // namespace
111
112 // The base test class for Bluetooth Audio HAL.
113 class BluetoothAudioProvidersFactoryHidlTest
114 : public ::testing::TestWithParam<std::string> {
115 public:
SetUp()116 virtual void SetUp() override {
117 providers_factory_ =
118 IBluetoothAudioProvidersFactory::getService(GetParam());
119 ASSERT_NE(providers_factory_, nullptr);
120 }
121
TearDown()122 virtual void TearDown() override { providers_factory_ = nullptr; }
123
124 // A simple test implementation of IBluetoothAudioPort.
125 class BluetoothAudioPort : public ::testing::VtsHalHidlTargetCallbackBase<
126 BluetoothAudioProvidersFactoryHidlTest>,
127 public IBluetoothAudioPort {
128 BluetoothAudioProvidersFactoryHidlTest& parent_;
129
130 public:
BluetoothAudioPort(BluetoothAudioProvidersFactoryHidlTest & parent)131 BluetoothAudioPort(BluetoothAudioProvidersFactoryHidlTest& parent)
132 : parent_(parent) {}
133 virtual ~BluetoothAudioPort() = default;
134
startStream()135 Return<void> startStream() override {
136 parent_.audio_provider_->streamStarted(BluetoothAudioStatus::SUCCESS);
137 return Void();
138 }
139
suspendStream()140 Return<void> suspendStream() override {
141 parent_.audio_provider_->streamSuspended(BluetoothAudioStatus::SUCCESS);
142 return Void();
143 }
144
stopStream()145 Return<void> stopStream() override { return Void(); }
146
getPresentationPosition(getPresentationPosition_cb _hidl_cb)147 Return<void> getPresentationPosition(getPresentationPosition_cb _hidl_cb) {
148 _hidl_cb(BluetoothAudioStatus::SUCCESS, 0, 0, {.tvSec = 0, .tvNSec = 0});
149 return Void();
150 }
151
updateMetadata(const SourceMetadata & sourceMetadata __unused)152 Return<void> updateMetadata(const SourceMetadata& sourceMetadata __unused) {
153 return Void();
154 }
155 };
156
GetProviderCapabilitiesHelper(const SessionType & session_type)157 void GetProviderCapabilitiesHelper(const SessionType& session_type) {
158 temp_provider_capabilities_.clear();
159 auto hidl_cb = [&temp_capabilities = this->temp_provider_capabilities_](
160 const hidl_vec<AudioCapabilities>& audioCapabilities) {
161 for (auto audioCapability : audioCapabilities)
162 temp_capabilities.push_back(audioCapability);
163 };
164 auto hidl_retval =
165 providers_factory_->getProviderCapabilities(session_type, hidl_cb);
166 // HIDL calls should not be failed and callback has to be executed
167 ASSERT_TRUE(hidl_retval.isOk());
168 if (session_type == SessionType::UNKNOWN) {
169 ASSERT_TRUE(temp_provider_capabilities_.empty());
170 } else if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
171 // All software paths are mandatory and must have exact 1 "PcmParameters"
172 ASSERT_EQ(temp_provider_capabilities_.size(), 1);
173 ASSERT_EQ(temp_provider_capabilities_[0].getDiscriminator(),
174 AudioCapabilities::hidl_discriminator::pcmCapabilities);
175 } else {
176 uint32_t codec_type_bitmask = 0x00000000;
177 // empty capability means offload is unsupported
178 for (auto audio_capability : temp_provider_capabilities_) {
179 ASSERT_EQ(audio_capability.getDiscriminator(),
180 AudioCapabilities::hidl_discriminator::codecCapabilities);
181 const CodecCapabilities& codec_capabilities =
182 audio_capability.codecCapabilities();
183 // Every codec can present once at most
184 ASSERT_EQ(codec_type_bitmask &
185 static_cast<uint32_t>(codec_capabilities.codecType),
186 0);
187 switch (codec_capabilities.codecType) {
188 case CodecType::SBC:
189 ASSERT_EQ(codec_capabilities.capabilities.getDiscriminator(),
190 CodecCapabilities::Capabilities::hidl_discriminator::
191 sbcCapabilities);
192 break;
193 case CodecType::AAC:
194 ASSERT_EQ(codec_capabilities.capabilities.getDiscriminator(),
195 CodecCapabilities::Capabilities::hidl_discriminator::
196 aacCapabilities);
197 break;
198 case CodecType::APTX:
199 FALLTHROUGH_INTENDED;
200 case CodecType::APTX_HD:
201 ASSERT_EQ(codec_capabilities.capabilities.getDiscriminator(),
202 CodecCapabilities::Capabilities::hidl_discriminator::
203 aptxCapabilities);
204 break;
205 case CodecType::LDAC:
206 ASSERT_EQ(codec_capabilities.capabilities.getDiscriminator(),
207 CodecCapabilities::Capabilities::hidl_discriminator::
208 ldacCapabilities);
209 break;
210 case CodecType::UNKNOWN:
211 break;
212 }
213 codec_type_bitmask |= codec_capabilities.codecType;
214 }
215 }
216 }
217
GetProviderCapabilitiesHelper_2_1(const android::hardware::bluetooth::audio::V2_1::SessionType & session_type)218 void GetProviderCapabilitiesHelper_2_1(
219 const android::hardware::bluetooth::audio::V2_1::SessionType&
220 session_type) {
221 temp_provider_capabilities_2_1_.clear();
222 auto hidl_cb =
223 [&temp_capabilities = this->temp_provider_capabilities_2_1_](
224 const hidl_vec<
225 android::hardware::bluetooth::audio::V2_1::AudioCapabilities>&
226 audioCapabilities) {
227 for (auto audioCapability : audioCapabilities)
228 temp_capabilities.push_back(audioCapability);
229 };
230 auto hidl_retval =
231 providers_factory_->getProviderCapabilities_2_1(session_type, hidl_cb);
232 // HIDL calls should not be failed and callback has to be executed
233 ASSERT_TRUE(hidl_retval.isOk());
234
235 // All software paths are mandatory and must have exact 1 "PcmParameters"
236 ASSERT_EQ(temp_provider_capabilities_2_1_.size(), 1);
237 ASSERT_EQ(temp_provider_capabilities_2_1_[0].getDiscriminator(),
238 android::hardware::bluetooth::audio::V2_1::AudioCapabilities::
239 hidl_discriminator::pcmCapabilities);
240 }
241
242 // This helps to open the specified provider and check the openProvider()
243 // has corruct return values. BUT, to keep it simple, it does not consider
244 // the capability, and please do so at the SetUp of each session's test.
OpenProviderHelper(const SessionType & session_type)245 void OpenProviderHelper(const SessionType& session_type) {
246 BluetoothAudioStatus cb_status;
247 auto hidl_cb = [&cb_status, &local_provider = this->audio_provider_](
248 BluetoothAudioStatus status,
249 const sp<IBluetoothAudioProvider>& provider) {
250 cb_status = status;
251 local_provider = provider;
252 };
253 auto hidl_retval = providers_factory_->openProvider(session_type, hidl_cb);
254 // HIDL calls should not be failed and callback has to be executed
255 ASSERT_TRUE(hidl_retval.isOk());
256 if (cb_status == BluetoothAudioStatus::SUCCESS) {
257 ASSERT_NE(session_type, SessionType::UNKNOWN);
258 ASSERT_NE(audio_provider_, nullptr);
259 audio_port_ = new BluetoothAudioPort(*this);
260 } else {
261 // A2DP_HARDWARE_OFFLOAD_DATAPATH is optional
262 ASSERT_TRUE(session_type == SessionType::UNKNOWN ||
263 session_type == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
264 ASSERT_EQ(cb_status, BluetoothAudioStatus::FAILURE);
265 ASSERT_EQ(audio_provider_, nullptr);
266 }
267 }
268
269 // This helps to open the specified provider and check the openProvider_2_1()
270 // has corruct return values. BUT, to keep it simple, it does not consider
271 // the capability, and please do so at the SetUp of each session's test.
OpenProviderHelper_2_1(const android::hardware::bluetooth::audio::V2_1::SessionType & session_type)272 void OpenProviderHelper_2_1(
273 const android::hardware::bluetooth::audio::V2_1::SessionType&
274 session_type) {
275 BluetoothAudioStatus cb_status;
276 auto hidl_cb = [&cb_status, &local_provider = this->audio_provider_2_1_](
277 BluetoothAudioStatus status,
278 const sp<android::hardware::bluetooth::audio::V2_1::
279 IBluetoothAudioProvider>& provider) {
280 cb_status = status;
281 local_provider = provider;
282 };
283 auto hidl_retval =
284 providers_factory_->openProvider_2_1(session_type, hidl_cb);
285 // HIDL calls should not be failed and callback has to be executed
286 ASSERT_TRUE(hidl_retval.isOk());
287 if (cb_status == BluetoothAudioStatus::SUCCESS) {
288 ASSERT_NE(
289 session_type,
290 android::hardware::bluetooth::audio::V2_1::SessionType::UNKNOWN);
291 ASSERT_NE(audio_provider_2_1_, nullptr);
292 audio_port_ = new BluetoothAudioPort(*this);
293 } else {
294 ASSERT_TRUE(
295 session_type ==
296 android::hardware::bluetooth::audio::V2_1::SessionType::UNKNOWN);
297 ASSERT_EQ(cb_status, BluetoothAudioStatus::FAILURE);
298 ASSERT_EQ(audio_provider_2_1_, nullptr);
299 }
300 }
301
IsPcmParametersSupported(const PcmParameters & pcm_parameters)302 bool IsPcmParametersSupported(const PcmParameters& pcm_parameters) {
303 if (temp_provider_capabilities_.size() != 1 ||
304 temp_provider_capabilities_[0].getDiscriminator() !=
305 AudioCapabilities::hidl_discriminator::pcmCapabilities) {
306 return false;
307 }
308 auto pcm_capability = temp_provider_capabilities_[0].pcmCapabilities();
309 bool is_parameter_valid =
310 (pcm_parameters.sampleRate != android::hardware::bluetooth::audio::
311 V2_0::SampleRate::RATE_UNKNOWN &&
312 pcm_parameters.channelMode != ChannelMode::UNKNOWN &&
313 pcm_parameters.bitsPerSample != BitsPerSample::BITS_UNKNOWN);
314 bool is_parameter_in_capability =
315 (pcm_capability.sampleRate & pcm_parameters.sampleRate &&
316 pcm_capability.channelMode & pcm_parameters.channelMode &&
317 pcm_capability.bitsPerSample & pcm_parameters.bitsPerSample);
318 return is_parameter_valid && is_parameter_in_capability;
319 }
320
IsPcmParametersSupported_2_1(const android::hardware::bluetooth::audio::V2_1::PcmParameters & pcm_parameters)321 bool IsPcmParametersSupported_2_1(
322 const android::hardware::bluetooth::audio::V2_1::PcmParameters&
323 pcm_parameters) {
324 if (temp_provider_capabilities_2_1_.size() != 1 ||
325 temp_provider_capabilities_2_1_[0].getDiscriminator() !=
326 android::hardware::bluetooth::audio::V2_1::AudioCapabilities::
327 hidl_discriminator::pcmCapabilities) {
328 return false;
329 }
330 auto pcm_capability = temp_provider_capabilities_2_1_[0].pcmCapabilities();
331 bool is_parameter_valid =
332 (pcm_parameters.sampleRate != SampleRate::RATE_UNKNOWN &&
333 pcm_parameters.channelMode != ChannelMode::UNKNOWN &&
334 pcm_parameters.bitsPerSample != BitsPerSample::BITS_UNKNOWN &&
335 pcm_parameters.dataIntervalUs != 0);
336 bool is_parameter_in_capability =
337 (pcm_capability.sampleRate & pcm_parameters.sampleRate &&
338 pcm_capability.channelMode & pcm_parameters.channelMode &&
339 pcm_capability.bitsPerSample & pcm_parameters.bitsPerSample);
340 return is_parameter_valid && is_parameter_in_capability;
341 }
342
343 sp<IBluetoothAudioProvidersFactory> providers_factory_;
344
345 // temp storage saves the specified provider capability by
346 // GetProviderCapabilitiesHelper()
347 std::vector<AudioCapabilities> temp_provider_capabilities_;
348 std::vector<android::hardware::bluetooth::audio::V2_1::AudioCapabilities>
349 temp_provider_capabilities_2_1_;
350
351 // audio_provider_ is for the Bluetooth stack to report session started/ended
352 // and handled audio stream started / suspended
353 sp<IBluetoothAudioProvider> audio_provider_;
354 sp<android::hardware::bluetooth::audio::V2_1::IBluetoothAudioProvider>
355 audio_provider_2_1_;
356
357 // audio_port_ is for the Audio HAL to send stream start/suspend/stop commands
358 // to Bluetooth stack
359 sp<IBluetoothAudioPort> audio_port_;
360
361 static constexpr SessionType session_types_[4] = {
362 SessionType::UNKNOWN, SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
363 SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH,
364 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH};
365 };
366
367 /**
368 * Test whether we can get the FactoryService from HIDL
369 */
TEST_P(BluetoothAudioProvidersFactoryHidlTest,GetProvidersFactoryService)370 TEST_P(BluetoothAudioProvidersFactoryHidlTest, GetProvidersFactoryService) {}
371
372 /**
373 * Test whether we can open a provider for each provider returned by
374 * getProviderCapabilities() with non-empty capabalities
375 */
TEST_P(BluetoothAudioProvidersFactoryHidlTest,OpenProviderAndCheckCapabilitiesBySession)376 TEST_P(BluetoothAudioProvidersFactoryHidlTest,
377 OpenProviderAndCheckCapabilitiesBySession) {
378 for (auto session_type : session_types_) {
379 GetProviderCapabilitiesHelper(session_type);
380 OpenProviderHelper(session_type);
381 // We must be able to open a provider if its getProviderCapabilities()
382 // returns non-empty list.
383 EXPECT_TRUE(temp_provider_capabilities_.empty() ||
384 audio_provider_ != nullptr);
385 }
386 }
387
388 /**
389 * openProvider A2DP_SOFTWARE_ENCODING_DATAPATH
390 */
391 class BluetoothAudioProviderA2dpSoftwareHidlTest
392 : public BluetoothAudioProvidersFactoryHidlTest {
393 public:
SetUp()394 virtual void SetUp() override {
395 BluetoothAudioProvidersFactoryHidlTest::SetUp();
396 GetProviderCapabilitiesHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
397 OpenProviderHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
398 ASSERT_NE(audio_provider_, nullptr);
399 }
400
TearDown()401 virtual void TearDown() override {
402 audio_port_ = nullptr;
403 audio_provider_ = nullptr;
404 BluetoothAudioProvidersFactoryHidlTest::TearDown();
405 }
406 };
407
408 /**
409 * Test whether we can open a provider of type
410 */
TEST_P(BluetoothAudioProviderA2dpSoftwareHidlTest,OpenA2dpSoftwareProvider)411 TEST_P(BluetoothAudioProviderA2dpSoftwareHidlTest, OpenA2dpSoftwareProvider) {}
412
413 /**
414 * Test whether each provider of type
415 * SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH can be started and stopped with
416 * different PCM config
417 */
TEST_P(BluetoothAudioProviderA2dpSoftwareHidlTest,StartAndEndA2dpSoftwareSessionWithPossiblePcmConfig)418 TEST_P(BluetoothAudioProviderA2dpSoftwareHidlTest,
419 StartAndEndA2dpSoftwareSessionWithPossiblePcmConfig) {
420 bool is_codec_config_valid;
421 std::unique_ptr<DataMQ> tempDataMQ;
422 auto hidl_cb = [&is_codec_config_valid, &tempDataMQ](
423 BluetoothAudioStatus status,
424 const DataMQ::Descriptor& dataMQ) {
425 if (is_codec_config_valid) {
426 ASSERT_EQ(status, BluetoothAudioStatus::SUCCESS);
427 ASSERT_TRUE(dataMQ.isHandleValid());
428 tempDataMQ.reset(new DataMQ(dataMQ));
429 } else {
430 EXPECT_EQ(status, BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION);
431 EXPECT_FALSE(dataMQ.isHandleValid());
432 }
433 };
434 AudioConfiguration audio_config = {};
435 PcmParameters pcm_parameters = {};
436 for (auto sample_rate : a2dp_sample_rates) {
437 pcm_parameters.sampleRate = sample_rate;
438 for (auto bits_per_sample : a2dp_bits_per_samples) {
439 pcm_parameters.bitsPerSample = bits_per_sample;
440 for (auto channel_mode : a2dp_channel_modes) {
441 pcm_parameters.channelMode = channel_mode;
442 is_codec_config_valid = IsPcmParametersSupported(pcm_parameters);
443 audio_config.pcmConfig(pcm_parameters);
444 auto hidl_retval =
445 audio_provider_->startSession(audio_port_, audio_config, hidl_cb);
446 // HIDL calls should not be failed and callback has to be executed
447 ASSERT_TRUE(hidl_retval.isOk());
448 if (is_codec_config_valid) {
449 EXPECT_TRUE(tempDataMQ != nullptr && tempDataMQ->isValid());
450 }
451 EXPECT_TRUE(audio_provider_->endSession().isOk());
452 } // ChannelMode
453 } // BitsPerSampple
454 } // SampleRate
455 }
456
457 /**
458 * openProvider A2DP_HARDWARE_OFFLOAD_DATAPATH
459 */
460 class BluetoothAudioProviderA2dpHardwareHidlTest
461 : public BluetoothAudioProvidersFactoryHidlTest {
462 public:
SetUp()463 virtual void SetUp() override {
464 BluetoothAudioProvidersFactoryHidlTest::SetUp();
465 GetProviderCapabilitiesHelper(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
466 OpenProviderHelper(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
467 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
468 audio_provider_ != nullptr);
469 }
470
TearDown()471 virtual void TearDown() override {
472 audio_port_ = nullptr;
473 audio_provider_ = nullptr;
474 BluetoothAudioProvidersFactoryHidlTest::TearDown();
475 }
476
IsOffloadSupported()477 bool IsOffloadSupported() { return (temp_provider_capabilities_.size() > 0); }
478
GetOffloadCodecCapabilityHelper(const CodecType & codec_type)479 void GetOffloadCodecCapabilityHelper(const CodecType& codec_type) {
480 temp_codec_capabilities_ = {};
481 for (auto codec_capability : temp_provider_capabilities_) {
482 if (codec_capability.codecCapabilities().codecType != codec_type) {
483 continue;
484 }
485 temp_codec_capabilities_ = codec_capability.codecCapabilities();
486 }
487 }
488
GetSbcCodecSpecificSupportedList(bool supported)489 std::vector<CodecSpecificConfig> GetSbcCodecSpecificSupportedList(
490 bool supported) {
491 std::vector<CodecSpecificConfig> sbc_codec_specifics;
492 GetOffloadCodecCapabilityHelper(CodecType::SBC);
493 if (temp_codec_capabilities_.codecType != CodecType::SBC) {
494 return sbc_codec_specifics;
495 }
496 // parse the capability
497 SbcParameters sbc_capability =
498 temp_codec_capabilities_.capabilities.sbcCapabilities();
499 if (sbc_capability.minBitpool > sbc_capability.maxBitpool) {
500 return sbc_codec_specifics;
501 }
502 std::vector<android::hardware::bluetooth::audio::V2_0::SampleRate>
503 sample_rates = ExtractValuesFromBitmask<
504 android::hardware::bluetooth::audio::V2_0::SampleRate>(
505 sbc_capability.sampleRate, 0xff, supported);
506 std::vector<SbcChannelMode> channel_modes =
507 ExtractValuesFromBitmask<SbcChannelMode>(sbc_capability.channelMode,
508 0x0f, supported);
509 std::vector<SbcBlockLength> block_lengths =
510 ExtractValuesFromBitmask<SbcBlockLength>(sbc_capability.blockLength,
511 0xf0, supported);
512 std::vector<SbcNumSubbands> num_subbandss =
513 ExtractValuesFromBitmask<SbcNumSubbands>(sbc_capability.numSubbands,
514 0x0c, supported);
515 std::vector<SbcAllocMethod> alloc_methods =
516 ExtractValuesFromBitmask<SbcAllocMethod>(sbc_capability.allocMethod,
517 0x03, supported);
518 std::vector<BitsPerSample> bits_per_samples =
519 ExtractValuesFromBitmask<BitsPerSample>(sbc_capability.bitsPerSample,
520 0x07, supported);
521 // combine those parameters into one list of
522 // CodecConfiguration::CodecSpecific
523 CodecSpecificConfig codec_specific = {};
524 SbcParameters sbc_data;
525 for (auto sample_rate : sample_rates) {
526 for (auto channel_mode : channel_modes) {
527 for (auto block_length : block_lengths) {
528 for (auto num_subbands : num_subbandss) {
529 for (auto alloc_method : alloc_methods) {
530 for (auto bits_per_sample : bits_per_samples) {
531 sbc_data = {.sampleRate = sample_rate,
532 .channelMode = channel_mode,
533 .blockLength = block_length,
534 .numSubbands = num_subbands,
535 .allocMethod = alloc_method,
536 .bitsPerSample = bits_per_sample,
537 .minBitpool = sbc_capability.minBitpool,
538 .maxBitpool = sbc_capability.maxBitpool};
539 codec_specific.sbcConfig(sbc_data);
540 sbc_codec_specifics.push_back(codec_specific);
541 }
542 }
543 }
544 }
545 }
546 }
547 return sbc_codec_specifics;
548 }
549
GetAacCodecSpecificSupportedList(bool supported)550 std::vector<CodecSpecificConfig> GetAacCodecSpecificSupportedList(
551 bool supported) {
552 std::vector<CodecSpecificConfig> aac_codec_specifics;
553 GetOffloadCodecCapabilityHelper(CodecType::AAC);
554 if (temp_codec_capabilities_.codecType != CodecType::AAC) {
555 return aac_codec_specifics;
556 }
557 // parse the capability
558 AacParameters aac_capability =
559 temp_codec_capabilities_.capabilities.aacCapabilities();
560 std::vector<AacObjectType> object_types =
561 ExtractValuesFromBitmask<AacObjectType>(aac_capability.objectType, 0xf0,
562 supported);
563 std::vector<android::hardware::bluetooth::audio::V2_0::SampleRate>
564 sample_rates = ExtractValuesFromBitmask<
565 android::hardware::bluetooth::audio::V2_0::SampleRate>(
566 aac_capability.sampleRate, 0xff, supported);
567 std::vector<ChannelMode> channel_modes =
568 ExtractValuesFromBitmask<ChannelMode>(aac_capability.channelMode, 0x03,
569 supported);
570 std::vector<AacVariableBitRate> variable_bit_rate_enableds = {
571 AacVariableBitRate::DISABLED};
572 if (aac_capability.variableBitRateEnabled == AacVariableBitRate::ENABLED) {
573 variable_bit_rate_enableds.push_back(AacVariableBitRate::ENABLED);
574 }
575 std::vector<BitsPerSample> bits_per_samples =
576 ExtractValuesFromBitmask<BitsPerSample>(aac_capability.bitsPerSample,
577 0x07, supported);
578 // combine those parameters into one list of
579 // CodecConfiguration::CodecSpecific
580 CodecSpecificConfig codec_specific = {};
581 AacParameters aac_data;
582 for (auto object_type : object_types) {
583 for (auto sample_rate : sample_rates) {
584 for (auto channel_mode : channel_modes) {
585 for (auto variable_bit_rate_enabled : variable_bit_rate_enableds) {
586 for (auto bits_per_sample : bits_per_samples) {
587 aac_data = {.objectType = object_type,
588 .sampleRate = sample_rate,
589 .channelMode = channel_mode,
590 .variableBitRateEnabled = variable_bit_rate_enabled,
591 .bitsPerSample = bits_per_sample};
592 codec_specific.aacConfig(aac_data);
593 aac_codec_specifics.push_back(codec_specific);
594 }
595 }
596 }
597 }
598 }
599 return aac_codec_specifics;
600 }
601
GetLdacCodecSpecificSupportedList(bool supported)602 std::vector<CodecSpecificConfig> GetLdacCodecSpecificSupportedList(
603 bool supported) {
604 std::vector<CodecSpecificConfig> ldac_codec_specifics;
605 GetOffloadCodecCapabilityHelper(CodecType::LDAC);
606 if (temp_codec_capabilities_.codecType != CodecType::LDAC) {
607 return ldac_codec_specifics;
608 }
609 // parse the capability
610 LdacParameters ldac_capability =
611 temp_codec_capabilities_.capabilities.ldacCapabilities();
612 std::vector<android::hardware::bluetooth::audio::V2_0::SampleRate>
613 sample_rates = ExtractValuesFromBitmask<
614 android::hardware::bluetooth::audio::V2_0::SampleRate>(
615 ldac_capability.sampleRate, 0xff, supported);
616 std::vector<LdacChannelMode> channel_modes =
617 ExtractValuesFromBitmask<LdacChannelMode>(ldac_capability.channelMode,
618 0x07, supported);
619 std::vector<LdacQualityIndex> quality_indexes = {
620 LdacQualityIndex::QUALITY_HIGH, LdacQualityIndex::QUALITY_MID,
621 LdacQualityIndex::QUALITY_LOW, LdacQualityIndex::QUALITY_ABR};
622 std::vector<BitsPerSample> bits_per_samples =
623 ExtractValuesFromBitmask<BitsPerSample>(ldac_capability.bitsPerSample,
624 0x07, supported);
625 // combine those parameters into one list of
626 // CodecConfiguration::CodecSpecific
627 CodecSpecificConfig codec_specific = {};
628 LdacParameters ldac_data;
629 for (auto sample_rate : sample_rates) {
630 for (auto channel_mode : channel_modes) {
631 for (auto quality_index : quality_indexes) {
632 for (auto bits_per_sample : bits_per_samples) {
633 ldac_data = {.sampleRate = sample_rate,
634 .channelMode = channel_mode,
635 .qualityIndex = quality_index,
636 .bitsPerSample = bits_per_sample};
637 codec_specific.ldacConfig(ldac_data);
638 ldac_codec_specifics.push_back(codec_specific);
639 }
640 }
641 }
642 }
643 return ldac_codec_specifics;
644 }
645
GetAptxCodecSpecificSupportedList(bool is_hd,bool supported)646 std::vector<CodecSpecificConfig> GetAptxCodecSpecificSupportedList(
647 bool is_hd, bool supported) {
648 std::vector<CodecSpecificConfig> aptx_codec_specifics;
649 GetOffloadCodecCapabilityHelper(
650 (is_hd ? CodecType::APTX_HD : CodecType::APTX));
651 if ((is_hd && temp_codec_capabilities_.codecType != CodecType::APTX_HD) ||
652 (!is_hd && temp_codec_capabilities_.codecType != CodecType::APTX)) {
653 return aptx_codec_specifics;
654 }
655 // parse the capability
656 AptxParameters aptx_capability =
657 temp_codec_capabilities_.capabilities.aptxCapabilities();
658 std::vector<android::hardware::bluetooth::audio::V2_0::SampleRate>
659 sample_rates = ExtractValuesFromBitmask<
660 android::hardware::bluetooth::audio::V2_0::SampleRate>(
661 aptx_capability.sampleRate, 0xff, supported);
662 std::vector<ChannelMode> channel_modes =
663 ExtractValuesFromBitmask<ChannelMode>(aptx_capability.channelMode, 0x03,
664 supported);
665 std::vector<BitsPerSample> bits_per_samples =
666 ExtractValuesFromBitmask<BitsPerSample>(aptx_capability.bitsPerSample,
667 0x07, supported);
668 // combine those parameters into one list of
669 // CodecConfiguration::CodecSpecific
670 CodecSpecificConfig codec_specific = {};
671 AptxParameters aptx_data;
672 for (auto sample_rate : sample_rates) {
673 for (auto channel_mode : channel_modes) {
674 for (auto bits_per_sample : bits_per_samples) {
675 aptx_data = {.sampleRate = sample_rate,
676 .channelMode = channel_mode,
677 .bitsPerSample = bits_per_sample};
678 codec_specific.aptxConfig(aptx_data);
679 aptx_codec_specifics.push_back(codec_specific);
680 }
681 }
682 }
683 return aptx_codec_specifics;
684 }
685
686 // temp storage saves the specified codec capability by
687 // GetOffloadCodecCapabilityHelper()
688 CodecCapabilities temp_codec_capabilities_;
689 };
690
691 /**
692 * Test whether we can open a provider of type
693 */
TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,OpenA2dpHardwareProvider)694 TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest, OpenA2dpHardwareProvider) {}
695
696 /**
697 * Test whether each provider of type
698 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
699 * SBC hardware encoding config
700 */
TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,StartAndEndA2dpSbcHardwareSession)701 TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,
702 StartAndEndA2dpSbcHardwareSession) {
703 if (!IsOffloadSupported()) {
704 return;
705 }
706
707 CodecConfiguration codec_config = {};
708 codec_config.codecType = CodecType::SBC;
709 codec_config.encodedAudioBitrate = 328000;
710 codec_config.peerMtu = 1005;
711 codec_config.isScmstEnabled = false;
712 AudioConfiguration audio_config = {};
713 std::vector<CodecSpecificConfig> sbc_codec_specifics =
714 GetSbcCodecSpecificSupportedList(true);
715 auto hidl_cb = [](BluetoothAudioStatus status,
716 const DataMQ::Descriptor& dataMQ) {
717 EXPECT_EQ(status, BluetoothAudioStatus::SUCCESS);
718 EXPECT_FALSE(dataMQ.isHandleValid());
719 };
720 for (auto codec_specific : sbc_codec_specifics) {
721 codec_config.config = codec_specific;
722 audio_config.codecConfig(codec_config);
723 auto hidl_retval =
724 audio_provider_->startSession(audio_port_, audio_config, hidl_cb);
725 // HIDL calls should not be failed and callback has to be executed
726 ASSERT_TRUE(hidl_retval.isOk());
727 EXPECT_TRUE(audio_provider_->endSession().isOk());
728 }
729 }
730
731 /**
732 * Test whether each provider of type
733 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
734 * AAC hardware encoding config
735 */
TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,StartAndEndA2dpAacHardwareSession)736 TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,
737 StartAndEndA2dpAacHardwareSession) {
738 if (!IsOffloadSupported()) {
739 return;
740 }
741
742 CodecConfiguration codec_config = {};
743 codec_config.codecType = CodecType::AAC;
744 codec_config.encodedAudioBitrate = 320000;
745 codec_config.peerMtu = 1005;
746 codec_config.isScmstEnabled = false;
747 AudioConfiguration audio_config = {};
748 std::vector<CodecSpecificConfig> aac_codec_specifics =
749 GetAacCodecSpecificSupportedList(true);
750 auto hidl_cb = [](BluetoothAudioStatus status,
751 const DataMQ::Descriptor& dataMQ) {
752 EXPECT_EQ(status, BluetoothAudioStatus::SUCCESS);
753 EXPECT_FALSE(dataMQ.isHandleValid());
754 };
755 for (auto codec_specific : aac_codec_specifics) {
756 codec_config.config = codec_specific;
757 audio_config.codecConfig(codec_config);
758 auto hidl_retval =
759 audio_provider_->startSession(audio_port_, audio_config, hidl_cb);
760 // HIDL calls should not be failed and callback has to be executed
761 ASSERT_TRUE(hidl_retval.isOk());
762 EXPECT_TRUE(audio_provider_->endSession().isOk());
763 }
764 }
765
766 /**
767 * Test whether each provider of type
768 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
769 * LDAC hardware encoding config
770 */
TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,StartAndEndA2dpLdacHardwareSession)771 TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,
772 StartAndEndA2dpLdacHardwareSession) {
773 if (!IsOffloadSupported()) {
774 return;
775 }
776
777 CodecConfiguration codec_config = {};
778 codec_config.codecType = CodecType::LDAC;
779 codec_config.encodedAudioBitrate = 990000;
780 codec_config.peerMtu = 1005;
781 codec_config.isScmstEnabled = false;
782 AudioConfiguration audio_config = {};
783 std::vector<CodecSpecificConfig> ldac_codec_specifics =
784 GetLdacCodecSpecificSupportedList(true);
785 auto hidl_cb = [](BluetoothAudioStatus status,
786 const DataMQ::Descriptor& dataMQ) {
787 EXPECT_EQ(status, BluetoothAudioStatus::SUCCESS);
788 EXPECT_FALSE(dataMQ.isHandleValid());
789 };
790 for (auto codec_specific : ldac_codec_specifics) {
791 codec_config.config = codec_specific;
792 audio_config.codecConfig(codec_config);
793 auto hidl_retval =
794 audio_provider_->startSession(audio_port_, audio_config, hidl_cb);
795 // HIDL calls should not be failed and callback has to be executed
796 ASSERT_TRUE(hidl_retval.isOk());
797 EXPECT_TRUE(audio_provider_->endSession().isOk());
798 }
799 }
800
801 /**
802 * Test whether each provider of type
803 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
804 * AptX hardware encoding config
805 */
TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,StartAndEndA2dpAptxHardwareSession)806 TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,
807 StartAndEndA2dpAptxHardwareSession) {
808 if (!IsOffloadSupported()) {
809 return;
810 }
811
812 for (auto codec_type : {CodecType::APTX, CodecType::APTX_HD}) {
813 CodecConfiguration codec_config = {};
814 codec_config.codecType = codec_type;
815 codec_config.encodedAudioBitrate =
816 (codec_type == CodecType::APTX ? 352000 : 576000);
817 codec_config.peerMtu = 1005;
818 codec_config.isScmstEnabled = false;
819 AudioConfiguration audio_config = {};
820 std::vector<CodecSpecificConfig> aptx_codec_specifics =
821 GetAptxCodecSpecificSupportedList(
822 (codec_type == CodecType::APTX_HD ? true : false), true);
823 auto hidl_cb = [](BluetoothAudioStatus status,
824 const DataMQ::Descriptor& dataMQ) {
825 EXPECT_EQ(status, BluetoothAudioStatus::SUCCESS);
826 EXPECT_FALSE(dataMQ.isHandleValid());
827 };
828 for (auto codec_specific : aptx_codec_specifics) {
829 codec_config.config = codec_specific;
830 audio_config.codecConfig(codec_config);
831 auto hidl_retval =
832 audio_provider_->startSession(audio_port_, audio_config, hidl_cb);
833 // HIDL calls should not be failed and callback has to be executed
834 ASSERT_TRUE(hidl_retval.isOk());
835 EXPECT_TRUE(audio_provider_->endSession().isOk());
836 }
837 }
838 }
839
840 /**
841 * Test whether each provider of type
842 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
843 * an invalid codec config
844 */
TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,StartAndEndA2dpHardwareSessionInvalidCodecConfig)845 TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,
846 StartAndEndA2dpHardwareSessionInvalidCodecConfig) {
847 if (!IsOffloadSupported()) {
848 return;
849 }
850 ASSERT_NE(audio_provider_, nullptr);
851
852 std::vector<CodecSpecificConfig> codec_specifics;
853 for (auto codec_type : a2dp_codec_types) {
854 switch (codec_type) {
855 case CodecType::SBC:
856 codec_specifics = GetSbcCodecSpecificSupportedList(false);
857 break;
858 case CodecType::AAC:
859 codec_specifics = GetAacCodecSpecificSupportedList(false);
860 break;
861 case CodecType::LDAC:
862 codec_specifics = GetLdacCodecSpecificSupportedList(false);
863 break;
864 case CodecType::APTX:
865 codec_specifics = GetAptxCodecSpecificSupportedList(false, false);
866 break;
867 case CodecType::APTX_HD:
868 codec_specifics = GetAptxCodecSpecificSupportedList(true, false);
869 break;
870 case CodecType::UNKNOWN:
871 codec_specifics.clear();
872 break;
873 }
874 if (codec_specifics.empty()) {
875 continue;
876 }
877
878 CodecConfiguration codec_config = {};
879 codec_config.codecType = codec_type;
880 codec_config.encodedAudioBitrate = 328000;
881 codec_config.peerMtu = 1005;
882 codec_config.isScmstEnabled = false;
883 AudioConfiguration audio_config = {};
884 auto hidl_cb = [](BluetoothAudioStatus status,
885 const DataMQ::Descriptor& dataMQ) {
886 EXPECT_EQ(status, BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION);
887 EXPECT_FALSE(dataMQ.isHandleValid());
888 };
889 for (auto codec_specific : codec_specifics) {
890 codec_config.config = codec_specific;
891 audio_config.codecConfig(codec_config);
892 auto hidl_retval =
893 audio_provider_->startSession(audio_port_, audio_config, hidl_cb);
894 // HIDL calls should not be failed and callback has to be executed
895 ASSERT_TRUE(hidl_retval.isOk());
896 EXPECT_TRUE(audio_provider_->endSession().isOk());
897 }
898 }
899 }
900
901 /**
902 * openProvider HEARING_AID_SOFTWARE_ENCODING_DATAPATH
903 */
904 class BluetoothAudioProviderHearingAidSoftwareHidlTest
905 : public BluetoothAudioProvidersFactoryHidlTest {
906 public:
SetUp()907 virtual void SetUp() override {
908 BluetoothAudioProvidersFactoryHidlTest::SetUp();
909 GetProviderCapabilitiesHelper(
910 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
911 OpenProviderHelper(SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
912 ASSERT_NE(audio_provider_, nullptr);
913 }
914
TearDown()915 virtual void TearDown() override {
916 audio_port_ = nullptr;
917 audio_provider_ = nullptr;
918 BluetoothAudioProvidersFactoryHidlTest::TearDown();
919 }
920
921 static constexpr android::hardware::bluetooth::audio::V2_0::SampleRate
922 hearing_aid_sample_rates_[3] = {
923 android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_UNKNOWN,
924 android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_16000,
925 android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_24000};
926 static constexpr BitsPerSample hearing_aid_bits_per_samples_[3] = {
927 BitsPerSample::BITS_UNKNOWN, BitsPerSample::BITS_16,
928 BitsPerSample::BITS_24};
929 static constexpr ChannelMode hearing_aid_channel_modes_[3] = {
930 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
931 };
932
933 /**
934 * Test whether each provider of type
935 * SessionType::HEARING_AID_HARDWARE_ENCODING_DATAPATH can be started and
936 * stopped with SBC hardware encoding config
937 */
TEST_P(BluetoothAudioProviderHearingAidSoftwareHidlTest,OpenHearingAidSoftwareProvider)938 TEST_P(BluetoothAudioProviderHearingAidSoftwareHidlTest,
939 OpenHearingAidSoftwareProvider) {}
940
941 /**
942 * Test whether each provider of type
943 * SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH can be started and
944 * stopped with different PCM config
945 */
TEST_P(BluetoothAudioProviderHearingAidSoftwareHidlTest,StartAndEndHearingAidSessionWithPossiblePcmConfig)946 TEST_P(BluetoothAudioProviderHearingAidSoftwareHidlTest,
947 StartAndEndHearingAidSessionWithPossiblePcmConfig) {
948 bool is_codec_config_valid;
949 std::unique_ptr<DataMQ> tempDataMQ;
950 auto hidl_cb = [&is_codec_config_valid, &tempDataMQ](
951 BluetoothAudioStatus status,
952 const DataMQ::Descriptor& dataMQ) {
953 if (is_codec_config_valid) {
954 ASSERT_EQ(status, BluetoothAudioStatus::SUCCESS);
955 ASSERT_TRUE(dataMQ.isHandleValid());
956 tempDataMQ.reset(new DataMQ(dataMQ));
957 } else {
958 EXPECT_EQ(status, BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION);
959 EXPECT_FALSE(dataMQ.isHandleValid());
960 }
961 };
962 AudioConfiguration audio_config = {};
963 PcmParameters pcm_parameters = {};
964 for (auto sample_rate : hearing_aid_sample_rates_) {
965 pcm_parameters.sampleRate = sample_rate;
966 for (auto bits_per_sample : hearing_aid_bits_per_samples_) {
967 pcm_parameters.bitsPerSample = bits_per_sample;
968 for (auto channel_mode : hearing_aid_channel_modes_) {
969 pcm_parameters.channelMode = channel_mode;
970 is_codec_config_valid = IsPcmParametersSupported(pcm_parameters);
971 audio_config.pcmConfig(pcm_parameters);
972 auto hidl_retval =
973 audio_provider_->startSession(audio_port_, audio_config, hidl_cb);
974 // HIDL calls should not be failed and callback has to be executed
975 ASSERT_TRUE(hidl_retval.isOk());
976 if (is_codec_config_valid) {
977 EXPECT_TRUE(tempDataMQ != nullptr && tempDataMQ->isValid());
978 }
979 EXPECT_TRUE(audio_provider_->endSession().isOk());
980 } // ChannelMode
981 } // BitsPerSampple
982 } // SampleRate
983 }
984
985 /**
986 * openProvider LE_AUDIO_SOFTWARE_ENCODING_DATAPATH
987 */
988 class BluetoothAudioProviderLeAudioOutputSoftwareHidlTest
989 : public BluetoothAudioProvidersFactoryHidlTest {
990 public:
SetUp()991 virtual void SetUp() override {
992 BluetoothAudioProvidersFactoryHidlTest::SetUp();
993 GetProviderCapabilitiesHelper_2_1(
994 android::hardware::bluetooth::audio::V2_1::SessionType::
995 LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
996 OpenProviderHelper_2_1(
997 android::hardware::bluetooth::audio::V2_1::SessionType::
998 LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
999 ASSERT_NE(audio_provider_2_1_, nullptr);
1000 }
1001
TearDown()1002 virtual void TearDown() override {
1003 audio_port_ = nullptr;
1004 audio_provider_2_1_ = nullptr;
1005 BluetoothAudioProvidersFactoryHidlTest::TearDown();
1006 }
1007
1008 static constexpr SampleRate le_audio_output_sample_rates_[11] = {
1009 SampleRate::RATE_UNKNOWN, SampleRate::RATE_8000, SampleRate::RATE_16000,
1010 SampleRate::RATE_24000, SampleRate::RATE_32000, SampleRate::RATE_44100,
1011 SampleRate::RATE_48000};
1012 static constexpr BitsPerSample le_audio_output_bits_per_samples_[3] = {
1013 BitsPerSample::BITS_UNKNOWN, BitsPerSample::BITS_16,
1014 BitsPerSample::BITS_24};
1015 static constexpr ChannelMode le_audio_output_channel_modes_[3] = {
1016 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
1017 static constexpr uint32_t le_audio_output_data_interval_us_[2] = {
1018 0 /* Invalid */, 10000 /* Valid 10ms */};
1019 };
1020
1021 /**
1022 * Test whether each provider of type
1023 * SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH can be started and
1024 * stopped
1025 */
TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareHidlTest,OpenLeAudioOutputSoftwareProvider)1026 TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareHidlTest,
1027 OpenLeAudioOutputSoftwareProvider) {}
1028
1029 /**
1030 * Test whether each provider of type
1031 * SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH can be started and
1032 * stopped with different PCM config
1033 */
TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareHidlTest,DISABLED_StartAndEndLeAudioOutputSessionWithPossiblePcmConfig)1034 TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareHidlTest,
1035 DISABLED_StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
1036 bool is_codec_config_valid;
1037 std::unique_ptr<DataMQ> tempDataMQ;
1038 auto hidl_cb = [&is_codec_config_valid, &tempDataMQ](
1039 BluetoothAudioStatus status,
1040 const DataMQ::Descriptor& dataMQ) {
1041 if (is_codec_config_valid) {
1042 ASSERT_EQ(status, BluetoothAudioStatus::SUCCESS);
1043 ASSERT_TRUE(dataMQ.isHandleValid());
1044 tempDataMQ.reset(new DataMQ(dataMQ));
1045 } else {
1046 EXPECT_EQ(status, BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION);
1047 EXPECT_FALSE(dataMQ.isHandleValid());
1048 tempDataMQ.reset(nullptr);
1049 }
1050 };
1051 android::hardware::bluetooth::audio::V2_1::AudioConfiguration audio_config =
1052 {};
1053 android::hardware::bluetooth::audio::V2_1::PcmParameters pcm_parameters = {};
1054 for (auto sample_rate : le_audio_output_sample_rates_) {
1055 pcm_parameters.sampleRate = sample_rate;
1056 for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
1057 pcm_parameters.bitsPerSample = bits_per_sample;
1058 for (auto channel_mode : le_audio_output_channel_modes_) {
1059 pcm_parameters.channelMode = channel_mode;
1060 for (auto data_interval_us : le_audio_output_data_interval_us_) {
1061 pcm_parameters.dataIntervalUs = data_interval_us;
1062 is_codec_config_valid = IsPcmParametersSupported_2_1(pcm_parameters);
1063 audio_config.pcmConfig(pcm_parameters);
1064 auto hidl_retval = audio_provider_2_1_->startSession_2_1(
1065 audio_port_, audio_config, hidl_cb);
1066 // HIDL calls should not be failed and callback has to be executed
1067 ASSERT_TRUE(hidl_retval.isOk());
1068 if (is_codec_config_valid) {
1069 EXPECT_TRUE(tempDataMQ != nullptr && tempDataMQ->isValid());
1070 } else {
1071 EXPECT_TRUE(tempDataMQ == nullptr);
1072 }
1073 EXPECT_TRUE(audio_provider_2_1_->endSession().isOk());
1074 } // uint32_t (data interval in microseconds)
1075 } // ChannelMode
1076 } // BitsPerSampple
1077 } // SampleRate
1078 }
1079
1080 /**
1081 * openProvider LE_AUDIO_SOFTWARE_DECODED_DATAPATH
1082 */
1083 class BluetoothAudioProviderLeAudioInputSoftwareHidlTest
1084 : public BluetoothAudioProvidersFactoryHidlTest {
1085 public:
SetUp()1086 virtual void SetUp() override {
1087 BluetoothAudioProvidersFactoryHidlTest::SetUp();
1088 GetProviderCapabilitiesHelper_2_1(
1089 android::hardware::bluetooth::audio::V2_1::SessionType::
1090 LE_AUDIO_SOFTWARE_DECODED_DATAPATH);
1091 OpenProviderHelper_2_1(android::hardware::bluetooth::audio::V2_1::
1092 SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH);
1093 ASSERT_NE(audio_provider_2_1_, nullptr);
1094 }
1095
TearDown()1096 virtual void TearDown() override {
1097 audio_port_ = nullptr;
1098 audio_provider_2_1_ = nullptr;
1099 BluetoothAudioProvidersFactoryHidlTest::TearDown();
1100 }
1101
1102 static constexpr SampleRate le_audio_output_sample_rates_[11] = {
1103 SampleRate::RATE_UNKNOWN, SampleRate::RATE_8000, SampleRate::RATE_16000,
1104 SampleRate::RATE_24000, SampleRate::RATE_32000, SampleRate::RATE_44100,
1105 SampleRate::RATE_48000};
1106 static constexpr BitsPerSample le_audio_output_bits_per_samples_[3] = {
1107 BitsPerSample::BITS_UNKNOWN, BitsPerSample::BITS_16,
1108 BitsPerSample::BITS_24};
1109 static constexpr ChannelMode le_audio_output_channel_modes_[3] = {
1110 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
1111 static constexpr uint32_t le_audio_output_data_interval_us_[2] = {
1112 0 /* Invalid */, 10000 /* Valid 10ms */};
1113 };
1114
1115 /**
1116 * Test whether each provider of type
1117 * SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH can be started and
1118 * stopped
1119 */
TEST_P(BluetoothAudioProviderLeAudioInputSoftwareHidlTest,OpenLeAudioInputSoftwareProvider)1120 TEST_P(BluetoothAudioProviderLeAudioInputSoftwareHidlTest,
1121 OpenLeAudioInputSoftwareProvider) {}
1122
1123 /**
1124 * Test whether each provider of type
1125 * SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH can be started and
1126 * stopped with different PCM config
1127 */
TEST_P(BluetoothAudioProviderLeAudioInputSoftwareHidlTest,DISABLED_StartAndEndLeAudioInputSessionWithPossiblePcmConfig)1128 TEST_P(BluetoothAudioProviderLeAudioInputSoftwareHidlTest,
1129 DISABLED_StartAndEndLeAudioInputSessionWithPossiblePcmConfig) {
1130 bool is_codec_config_valid;
1131 std::unique_ptr<DataMQ> tempDataMQ;
1132 auto hidl_cb = [&is_codec_config_valid, &tempDataMQ](
1133 BluetoothAudioStatus status,
1134 const DataMQ::Descriptor& dataMQ) {
1135 if (is_codec_config_valid) {
1136 ASSERT_EQ(status, BluetoothAudioStatus::SUCCESS);
1137 ASSERT_TRUE(dataMQ.isHandleValid());
1138 tempDataMQ.reset(new DataMQ(dataMQ));
1139 } else {
1140 EXPECT_EQ(status, BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION);
1141 EXPECT_FALSE(dataMQ.isHandleValid());
1142 tempDataMQ.reset(nullptr);
1143 }
1144 };
1145 android::hardware::bluetooth::audio::V2_1::AudioConfiguration audio_config =
1146 {};
1147 android::hardware::bluetooth::audio::V2_1::PcmParameters pcm_parameters = {};
1148 for (auto sample_rate : le_audio_output_sample_rates_) {
1149 pcm_parameters.sampleRate = sample_rate;
1150 for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
1151 pcm_parameters.bitsPerSample = bits_per_sample;
1152 for (auto channel_mode : le_audio_output_channel_modes_) {
1153 pcm_parameters.channelMode = channel_mode;
1154 for (auto data_interval_us : le_audio_output_data_interval_us_) {
1155 pcm_parameters.dataIntervalUs = data_interval_us;
1156 is_codec_config_valid = IsPcmParametersSupported_2_1(pcm_parameters);
1157 audio_config.pcmConfig(pcm_parameters);
1158 auto hidl_retval = audio_provider_2_1_->startSession_2_1(
1159 audio_port_, audio_config, hidl_cb);
1160 // HIDL calls should not be failed and callback has to be executed
1161 ASSERT_TRUE(hidl_retval.isOk());
1162 if (is_codec_config_valid) {
1163 EXPECT_TRUE(tempDataMQ != nullptr && tempDataMQ->isValid());
1164 } else {
1165 EXPECT_TRUE(tempDataMQ == nullptr);
1166 }
1167 EXPECT_TRUE(audio_provider_2_1_->endSession().isOk());
1168 } // uint32_t (data interval in microseconds)
1169 } // ChannelMode
1170 } // BitsPerSampple
1171 } // SampleRate
1172 }
1173
1174 static const std::vector<std::string> kAudioInstances =
1175 android::hardware::getAllHalInstanceNames(
1176 IBluetoothAudioProvidersFactory::descriptor);
1177
1178 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
1179 BluetoothAudioProvidersFactoryHidlTest);
1180 INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProvidersFactoryHidlTest,
1181 testing::ValuesIn(kAudioInstances),
1182 android::hardware::PrintInstanceNameToString);
1183
1184 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
1185 BluetoothAudioProviderA2dpSoftwareHidlTest);
1186 INSTANTIATE_TEST_SUITE_P(PerInstance,
1187 BluetoothAudioProviderA2dpSoftwareHidlTest,
1188 testing::ValuesIn(kAudioInstances),
1189 android::hardware::PrintInstanceNameToString);
1190
1191 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
1192 BluetoothAudioProviderA2dpHardwareHidlTest);
1193 INSTANTIATE_TEST_SUITE_P(PerInstance,
1194 BluetoothAudioProviderA2dpHardwareHidlTest,
1195 testing::ValuesIn(kAudioInstances),
1196 android::hardware::PrintInstanceNameToString);
1197
1198 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
1199 BluetoothAudioProviderHearingAidSoftwareHidlTest);
1200 INSTANTIATE_TEST_SUITE_P(PerInstance,
1201 BluetoothAudioProviderHearingAidSoftwareHidlTest,
1202 testing::ValuesIn(kAudioInstances),
1203 android::hardware::PrintInstanceNameToString);
1204
1205 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
1206 BluetoothAudioProviderLeAudioOutputSoftwareHidlTest);
1207 INSTANTIATE_TEST_SUITE_P(PerInstance,
1208 BluetoothAudioProviderLeAudioOutputSoftwareHidlTest,
1209 testing::ValuesIn(kAudioInstances),
1210 android::hardware::PrintInstanceNameToString);
1211
1212 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
1213 BluetoothAudioProviderLeAudioInputSoftwareHidlTest);
1214 INSTANTIATE_TEST_SUITE_P(PerInstance,
1215 BluetoothAudioProviderLeAudioInputSoftwareHidlTest,
1216 testing::ValuesIn(kAudioInstances),
1217 android::hardware::PrintInstanceNameToString);
1218