1 /*
2 * Copyright 2018 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 <android-base/logging.h>
20 #include <android/hardware/bluetooth/audio/2.0/IBluetoothAudioPort.h>
21 #include <android/hardware/bluetooth/audio/2.0/IBluetoothAudioProvider.h>
22 #include <android/hardware/bluetooth/audio/2.0/IBluetoothAudioProvidersFactory.h>
23 #include <fmq/MessageQueue.h>
24 #include <gtest/gtest.h>
25 #include <hidl/GtestPrinter.h>
26 #include <hidl/MQDescriptor.h>
27 #include <hidl/ServiceManagement.h>
28 #include <utils/Log.h>
29
30 #include <VtsHalHidlTargetCallbackBase.h>
31
32 using ::android::sp;
33 using ::android::hardware::hidl_vec;
34 using ::android::hardware::kSynchronizedReadWrite;
35 using ::android::hardware::MessageQueue;
36 using ::android::hardware::Return;
37 using ::android::hardware::Void;
38 using ::android::hardware::audio::common::V5_0::SourceMetadata;
39 using ::android::hardware::bluetooth::audio::V2_0::AacObjectType;
40 using ::android::hardware::bluetooth::audio::V2_0::AacParameters;
41 using ::android::hardware::bluetooth::audio::V2_0::AacVariableBitRate;
42 using ::android::hardware::bluetooth::audio::V2_0::AptxParameters;
43 using ::android::hardware::bluetooth::audio::V2_0::AudioCapabilities;
44 using ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration;
45 using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
46 using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
47 using ::android::hardware::bluetooth::audio::V2_0::CodecCapabilities;
48 using ::android::hardware::bluetooth::audio::V2_0::CodecConfiguration;
49 using ::android::hardware::bluetooth::audio::V2_0::CodecType;
50 using ::android::hardware::bluetooth::audio::V2_0::IBluetoothAudioPort;
51 using ::android::hardware::bluetooth::audio::V2_0::IBluetoothAudioProvider;
52 using ::android::hardware::bluetooth::audio::V2_0::
53 IBluetoothAudioProvidersFactory;
54 using ::android::hardware::bluetooth::audio::V2_0::LdacChannelMode;
55 using ::android::hardware::bluetooth::audio::V2_0::LdacParameters;
56 using ::android::hardware::bluetooth::audio::V2_0::LdacQualityIndex;
57 using ::android::hardware::bluetooth::audio::V2_0::PcmParameters;
58 using ::android::hardware::bluetooth::audio::V2_0::SampleRate;
59 using ::android::hardware::bluetooth::audio::V2_0::SbcAllocMethod;
60 using ::android::hardware::bluetooth::audio::V2_0::SbcBlockLength;
61 using ::android::hardware::bluetooth::audio::V2_0::SbcChannelMode;
62 using ::android::hardware::bluetooth::audio::V2_0::SbcNumSubbands;
63 using ::android::hardware::bluetooth::audio::V2_0::SbcParameters;
64 using ::android::hardware::bluetooth::audio::V2_0::SessionType;
65
66 using DataMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
67 using BluetoothAudioStatus =
68 ::android::hardware::bluetooth::audio::V2_0::Status;
69 using CodecSpecificConfig = ::android::hardware::bluetooth::audio::V2_0::
70 CodecConfiguration::CodecSpecific;
71
72 namespace {
73 constexpr SampleRate a2dp_sample_rates[5] = {
74 SampleRate::RATE_UNKNOWN, SampleRate::RATE_44100, SampleRate::RATE_48000,
75 SampleRate::RATE_88200, SampleRate::RATE_96000};
76 constexpr BitsPerSample a2dp_bits_per_samples[4] = {
77 BitsPerSample::BITS_UNKNOWN, BitsPerSample::BITS_16, BitsPerSample::BITS_24,
78 BitsPerSample::BITS_32};
79 constexpr ChannelMode a2dp_channel_modes[3] = {
80 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
81 constexpr CodecType a2dp_codec_types[6] = {CodecType::UNKNOWN, CodecType::SBC,
82 CodecType::AAC, CodecType::APTX,
83 CodecType::APTX_HD, CodecType::LDAC};
84
85 template <typename T>
ExtractValuesFromBitmask(T bitmasks,uint32_t bitfield,bool supported)86 std::vector<T> ExtractValuesFromBitmask(T bitmasks, uint32_t bitfield,
87 bool supported) {
88 std::vector<T> retval;
89 if (!supported) {
90 retval.push_back(static_cast<T>(bitfield));
91 }
92 uint32_t test_bit = 0x00000001;
93 while (test_bit <= static_cast<uint32_t>(bitmasks) && test_bit <= bitfield) {
94 if ((bitfield & test_bit)) {
95 if ((!(bitmasks & test_bit) && !supported) ||
96 ((bitmasks & test_bit) && supported)) {
97 retval.push_back(static_cast<T>(test_bit));
98 }
99 }
100 if (test_bit == 0x80000000) {
101 break;
102 }
103 test_bit <<= 1;
104 }
105 return retval;
106 }
107 } // namespace
108
109 // The base test class for Bluetooth Audio HAL.
110 class BluetoothAudioProvidersFactoryHidlTest
111 : public ::testing::TestWithParam<std::string> {
112 public:
SetUp()113 virtual void SetUp() override {
114 providers_factory_ =
115 IBluetoothAudioProvidersFactory::getService(GetParam());
116 ASSERT_NE(providers_factory_, nullptr);
117 }
118
TearDown()119 virtual void TearDown() override { providers_factory_ = nullptr; }
120
121 // A simple test implementation of IBluetoothAudioPort.
122 class BluetoothAudioPort : public ::testing::VtsHalHidlTargetCallbackBase<
123 BluetoothAudioProvidersFactoryHidlTest>,
124 public IBluetoothAudioPort {
125 BluetoothAudioProvidersFactoryHidlTest& parent_;
126
127 public:
BluetoothAudioPort(BluetoothAudioProvidersFactoryHidlTest & parent)128 BluetoothAudioPort(BluetoothAudioProvidersFactoryHidlTest& parent)
129 : parent_(parent) {}
130 virtual ~BluetoothAudioPort() = default;
131
startStream()132 Return<void> startStream() override {
133 parent_.audio_provider_->streamStarted(BluetoothAudioStatus::SUCCESS);
134 return Void();
135 }
136
suspendStream()137 Return<void> suspendStream() override {
138 parent_.audio_provider_->streamSuspended(BluetoothAudioStatus::SUCCESS);
139 return Void();
140 }
141
stopStream()142 Return<void> stopStream() override { return Void(); }
143
getPresentationPosition(getPresentationPosition_cb _hidl_cb)144 Return<void> getPresentationPosition(getPresentationPosition_cb _hidl_cb) {
145 _hidl_cb(BluetoothAudioStatus::SUCCESS, 0, 0, {.tvSec = 0, .tvNSec = 0});
146 return Void();
147 }
148
updateMetadata(const SourceMetadata & sourceMetadata __unused)149 Return<void> updateMetadata(const SourceMetadata& sourceMetadata __unused) {
150 return Void();
151 }
152 };
153
GetProviderCapabilitiesHelper(const SessionType & session_type)154 void GetProviderCapabilitiesHelper(const SessionType& session_type) {
155 temp_provider_capabilities_.clear();
156 auto hidl_cb = [& temp_capabilities = this->temp_provider_capabilities_](
157 const hidl_vec<AudioCapabilities>& audioCapabilities) {
158 for (auto audioCapability : audioCapabilities)
159 temp_capabilities.push_back(audioCapability);
160 };
161 auto hidl_retval =
162 providers_factory_->getProviderCapabilities(session_type, hidl_cb);
163 // HIDL calls should not be failed and callback has to be executed
164 ASSERT_TRUE(hidl_retval.isOk());
165 if (session_type == SessionType::UNKNOWN) {
166 ASSERT_TRUE(temp_provider_capabilities_.empty());
167 } else if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
168 // All software paths are mandatory and must have exact 1 "PcmParameters"
169 ASSERT_EQ(temp_provider_capabilities_.size(), 1);
170 ASSERT_EQ(temp_provider_capabilities_[0].getDiscriminator(),
171 AudioCapabilities::hidl_discriminator::pcmCapabilities);
172 } else {
173 uint32_t codec_type_bitmask = 0x00000000;
174 // empty capability means offload is unsupported
175 for (auto audio_capability : temp_provider_capabilities_) {
176 ASSERT_EQ(audio_capability.getDiscriminator(),
177 AudioCapabilities::hidl_discriminator::codecCapabilities);
178 const CodecCapabilities& codec_capabilities =
179 audio_capability.codecCapabilities();
180 // Every codec can present once at most
181 ASSERT_EQ(codec_type_bitmask &
182 static_cast<uint32_t>(codec_capabilities.codecType),
183 0);
184 switch (codec_capabilities.codecType) {
185 case CodecType::SBC:
186 ASSERT_EQ(codec_capabilities.capabilities.getDiscriminator(),
187 CodecCapabilities::Capabilities::hidl_discriminator::
188 sbcCapabilities);
189 break;
190 case CodecType::AAC:
191 ASSERT_EQ(codec_capabilities.capabilities.getDiscriminator(),
192 CodecCapabilities::Capabilities::hidl_discriminator::
193 aacCapabilities);
194 break;
195 case CodecType::APTX:
196 FALLTHROUGH_INTENDED;
197 case CodecType::APTX_HD:
198 ASSERT_EQ(codec_capabilities.capabilities.getDiscriminator(),
199 CodecCapabilities::Capabilities::hidl_discriminator::
200 aptxCapabilities);
201 break;
202 case CodecType::LDAC:
203 ASSERT_EQ(codec_capabilities.capabilities.getDiscriminator(),
204 CodecCapabilities::Capabilities::hidl_discriminator::
205 ldacCapabilities);
206 break;
207 case CodecType::UNKNOWN:
208 break;
209 }
210 codec_type_bitmask |= codec_capabilities.codecType;
211 }
212 }
213 }
214
215 // This helps to open the specified provider and check the openProvider()
216 // has corruct return values. BUT, to keep it simple, it does not consider
217 // the capability, and please do so at the SetUp of each session's test.
OpenProviderHelper(const SessionType & session_type)218 void OpenProviderHelper(const SessionType& session_type) {
219 BluetoothAudioStatus cb_status;
220 auto hidl_cb = [&cb_status, &local_provider = this->audio_provider_](
221 BluetoothAudioStatus status,
222 const sp<IBluetoothAudioProvider>& provider) {
223 cb_status = status;
224 local_provider = provider;
225 };
226 auto hidl_retval = providers_factory_->openProvider(session_type, hidl_cb);
227 // HIDL calls should not be failed and callback has to be executed
228 ASSERT_TRUE(hidl_retval.isOk());
229 if (cb_status == BluetoothAudioStatus::SUCCESS) {
230 ASSERT_NE(session_type, SessionType::UNKNOWN);
231 ASSERT_NE(audio_provider_, nullptr);
232 audio_port_ = new BluetoothAudioPort(*this);
233 } else {
234 // A2DP_HARDWARE_OFFLOAD_DATAPATH is optional
235 ASSERT_TRUE(session_type == SessionType::UNKNOWN ||
236 session_type == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
237 ASSERT_EQ(cb_status, BluetoothAudioStatus::FAILURE);
238 ASSERT_EQ(audio_provider_, nullptr);
239 }
240 }
241
IsPcmParametersSupported(const PcmParameters & pcm_parameters)242 bool IsPcmParametersSupported(const PcmParameters& pcm_parameters) {
243 if (temp_provider_capabilities_.size() != 1 ||
244 temp_provider_capabilities_[0].getDiscriminator() !=
245 AudioCapabilities::hidl_discriminator::pcmCapabilities) {
246 return false;
247 }
248 auto pcm_capability = temp_provider_capabilities_[0].pcmCapabilities();
249 bool is_parameter_valid =
250 (pcm_parameters.sampleRate != SampleRate::RATE_UNKNOWN &&
251 pcm_parameters.channelMode != ChannelMode::UNKNOWN &&
252 pcm_parameters.bitsPerSample != BitsPerSample::BITS_UNKNOWN);
253 bool is_parameter_in_capability =
254 (pcm_capability.sampleRate & pcm_parameters.sampleRate &&
255 pcm_capability.channelMode & pcm_parameters.channelMode &&
256 pcm_capability.bitsPerSample & pcm_parameters.bitsPerSample);
257 return is_parameter_valid && is_parameter_in_capability;
258 }
259
260 sp<IBluetoothAudioProvidersFactory> providers_factory_;
261
262 // temp storage saves the specified provider capability by
263 // GetProviderCapabilitiesHelper()
264 std::vector<AudioCapabilities> temp_provider_capabilities_;
265
266 // audio_provider_ is for the Bluetooth stack to report session started/ended
267 // and handled audio stream started / suspended
268 sp<IBluetoothAudioProvider> audio_provider_;
269
270 // audio_port_ is for the Audio HAL to send stream start/suspend/stop commands
271 // to Bluetooth stack
272 sp<IBluetoothAudioPort> audio_port_;
273
274 static constexpr SessionType session_types_[4] = {
275 SessionType::UNKNOWN, SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
276 SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH,
277 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH};
278 };
279
280 /**
281 * Test whether we can get the FactoryService from HIDL
282 */
TEST_P(BluetoothAudioProvidersFactoryHidlTest,GetProvidersFactoryService)283 TEST_P(BluetoothAudioProvidersFactoryHidlTest, GetProvidersFactoryService) {}
284
285 /**
286 * Test whether we can open a provider for each provider returned by
287 * getProviderCapabilities() with non-empty capabalities
288 */
TEST_P(BluetoothAudioProvidersFactoryHidlTest,OpenProviderAndCheckCapabilitiesBySession)289 TEST_P(BluetoothAudioProvidersFactoryHidlTest,
290 OpenProviderAndCheckCapabilitiesBySession) {
291 for (auto session_type : session_types_) {
292 GetProviderCapabilitiesHelper(session_type);
293 OpenProviderHelper(session_type);
294 // We must be able to open a provider if its getProviderCapabilities()
295 // returns non-empty list.
296 EXPECT_TRUE(temp_provider_capabilities_.empty() ||
297 audio_provider_ != nullptr);
298 }
299 }
300
301 /**
302 * openProvider A2DP_SOFTWARE_ENCODING_DATAPATH
303 */
304 class BluetoothAudioProviderA2dpSoftwareHidlTest
305 : public BluetoothAudioProvidersFactoryHidlTest {
306 public:
SetUp()307 virtual void SetUp() override {
308 BluetoothAudioProvidersFactoryHidlTest::SetUp();
309 GetProviderCapabilitiesHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
310 OpenProviderHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
311 ASSERT_NE(audio_provider_, nullptr);
312 }
313
TearDown()314 virtual void TearDown() override {
315 audio_port_ = nullptr;
316 audio_provider_ = nullptr;
317 BluetoothAudioProvidersFactoryHidlTest::TearDown();
318 }
319 };
320
321 /**
322 * Test whether we can open a provider of type
323 */
TEST_P(BluetoothAudioProviderA2dpSoftwareHidlTest,OpenA2dpSoftwareProvider)324 TEST_P(BluetoothAudioProviderA2dpSoftwareHidlTest, OpenA2dpSoftwareProvider) {}
325
326 /**
327 * Test whether each provider of type
328 * SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH can be started and stopped with
329 * different PCM config
330 */
TEST_P(BluetoothAudioProviderA2dpSoftwareHidlTest,StartAndEndA2dpSoftwareSessionWithPossiblePcmConfig)331 TEST_P(BluetoothAudioProviderA2dpSoftwareHidlTest,
332 StartAndEndA2dpSoftwareSessionWithPossiblePcmConfig) {
333 bool is_codec_config_valid;
334 std::unique_ptr<DataMQ> tempDataMQ;
335 auto hidl_cb = [&is_codec_config_valid, &tempDataMQ](
336 BluetoothAudioStatus status,
337 const DataMQ::Descriptor& dataMQ) {
338 if (is_codec_config_valid) {
339 ASSERT_EQ(status, BluetoothAudioStatus::SUCCESS);
340 ASSERT_TRUE(dataMQ.isHandleValid());
341 tempDataMQ.reset(new DataMQ(dataMQ));
342 } else {
343 EXPECT_EQ(status, BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION);
344 EXPECT_FALSE(dataMQ.isHandleValid());
345 }
346 };
347 AudioConfiguration audio_config = {};
348 PcmParameters pcm_parameters = {};
349 for (auto sample_rate : a2dp_sample_rates) {
350 pcm_parameters.sampleRate = sample_rate;
351 for (auto bits_per_sample : a2dp_bits_per_samples) {
352 pcm_parameters.bitsPerSample = bits_per_sample;
353 for (auto channel_mode : a2dp_channel_modes) {
354 pcm_parameters.channelMode = channel_mode;
355 is_codec_config_valid = IsPcmParametersSupported(pcm_parameters);
356 audio_config.pcmConfig(pcm_parameters);
357 auto hidl_retval =
358 audio_provider_->startSession(audio_port_, audio_config, hidl_cb);
359 // HIDL calls should not be failed and callback has to be executed
360 ASSERT_TRUE(hidl_retval.isOk());
361 if (is_codec_config_valid) {
362 EXPECT_TRUE(tempDataMQ != nullptr && tempDataMQ->isValid());
363 }
364 EXPECT_TRUE(audio_provider_->endSession().isOk());
365 } // ChannelMode
366 } // BitsPerSampple
367 } // SampleRate
368 }
369
370 /**
371 * openProvider A2DP_HARDWARE_OFFLOAD_DATAPATH
372 */
373 class BluetoothAudioProviderA2dpHardwareHidlTest
374 : public BluetoothAudioProvidersFactoryHidlTest {
375 public:
SetUp()376 virtual void SetUp() override {
377 BluetoothAudioProvidersFactoryHidlTest::SetUp();
378 GetProviderCapabilitiesHelper(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
379 OpenProviderHelper(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
380 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
381 audio_provider_ != nullptr);
382 }
383
TearDown()384 virtual void TearDown() override {
385 audio_port_ = nullptr;
386 audio_provider_ = nullptr;
387 BluetoothAudioProvidersFactoryHidlTest::TearDown();
388 }
389
IsOffloadSupported()390 bool IsOffloadSupported() { return (temp_provider_capabilities_.size() > 0); }
391
GetOffloadCodecCapabilityHelper(const CodecType & codec_type)392 void GetOffloadCodecCapabilityHelper(const CodecType& codec_type) {
393 temp_codec_capabilities_ = {};
394 for (auto codec_capability : temp_provider_capabilities_) {
395 if (codec_capability.codecCapabilities().codecType != codec_type) {
396 continue;
397 }
398 temp_codec_capabilities_ = codec_capability.codecCapabilities();
399 }
400 }
401
GetSbcCodecSpecificSupportedList(bool supported)402 std::vector<CodecSpecificConfig> GetSbcCodecSpecificSupportedList(
403 bool supported) {
404 std::vector<CodecSpecificConfig> sbc_codec_specifics;
405 GetOffloadCodecCapabilityHelper(CodecType::SBC);
406 if (temp_codec_capabilities_.codecType != CodecType::SBC) {
407 return sbc_codec_specifics;
408 }
409 // parse the capability
410 SbcParameters sbc_capability =
411 temp_codec_capabilities_.capabilities.sbcCapabilities();
412 if (sbc_capability.minBitpool > sbc_capability.maxBitpool) {
413 return sbc_codec_specifics;
414 }
415 std::vector<SampleRate> sample_rates = ExtractValuesFromBitmask<SampleRate>(
416 sbc_capability.sampleRate, 0xff, supported);
417 std::vector<SbcChannelMode> channel_modes =
418 ExtractValuesFromBitmask<SbcChannelMode>(sbc_capability.channelMode,
419 0x0f, supported);
420 std::vector<SbcBlockLength> block_lengths =
421 ExtractValuesFromBitmask<SbcBlockLength>(sbc_capability.blockLength,
422 0xf0, supported);
423 std::vector<SbcNumSubbands> num_subbandss =
424 ExtractValuesFromBitmask<SbcNumSubbands>(sbc_capability.numSubbands,
425 0x0c, supported);
426 std::vector<SbcAllocMethod> alloc_methods =
427 ExtractValuesFromBitmask<SbcAllocMethod>(sbc_capability.allocMethod,
428 0x03, supported);
429 std::vector<BitsPerSample> bits_per_samples =
430 ExtractValuesFromBitmask<BitsPerSample>(sbc_capability.bitsPerSample,
431 0x07, supported);
432 // combine those parameters into one list of
433 // CodecConfiguration::CodecSpecific
434 CodecSpecificConfig codec_specific = {};
435 SbcParameters sbc_data;
436 for (auto sample_rate : sample_rates) {
437 for (auto channel_mode : channel_modes) {
438 for (auto block_length : block_lengths) {
439 for (auto num_subbands : num_subbandss) {
440 for (auto alloc_method : alloc_methods) {
441 for (auto bits_per_sample : bits_per_samples) {
442 sbc_data = {.sampleRate = sample_rate,
443 .channelMode = channel_mode,
444 .blockLength = block_length,
445 .numSubbands = num_subbands,
446 .allocMethod = alloc_method,
447 .bitsPerSample = bits_per_sample,
448 .minBitpool = sbc_capability.minBitpool,
449 .maxBitpool = sbc_capability.maxBitpool};
450 codec_specific.sbcConfig(sbc_data);
451 sbc_codec_specifics.push_back(codec_specific);
452 }
453 }
454 }
455 }
456 }
457 }
458 return sbc_codec_specifics;
459 }
460
GetAacCodecSpecificSupportedList(bool supported)461 std::vector<CodecSpecificConfig> GetAacCodecSpecificSupportedList(
462 bool supported) {
463 std::vector<CodecSpecificConfig> aac_codec_specifics;
464 GetOffloadCodecCapabilityHelper(CodecType::AAC);
465 if (temp_codec_capabilities_.codecType != CodecType::AAC) {
466 return aac_codec_specifics;
467 }
468 // parse the capability
469 AacParameters aac_capability =
470 temp_codec_capabilities_.capabilities.aacCapabilities();
471 std::vector<AacObjectType> object_types =
472 ExtractValuesFromBitmask<AacObjectType>(aac_capability.objectType, 0xf0,
473 supported);
474 std::vector<SampleRate> sample_rates = ExtractValuesFromBitmask<SampleRate>(
475 aac_capability.sampleRate, 0xff, supported);
476 std::vector<ChannelMode> channel_modes =
477 ExtractValuesFromBitmask<ChannelMode>(aac_capability.channelMode, 0x03,
478 supported);
479 std::vector<AacVariableBitRate> variable_bit_rate_enableds = {
480 AacVariableBitRate::DISABLED};
481 if (aac_capability.variableBitRateEnabled == AacVariableBitRate::ENABLED) {
482 variable_bit_rate_enableds.push_back(AacVariableBitRate::ENABLED);
483 }
484 std::vector<BitsPerSample> bits_per_samples =
485 ExtractValuesFromBitmask<BitsPerSample>(aac_capability.bitsPerSample,
486 0x07, supported);
487 // combine those parameters into one list of
488 // CodecConfiguration::CodecSpecific
489 CodecSpecificConfig codec_specific = {};
490 AacParameters aac_data;
491 for (auto object_type : object_types) {
492 for (auto sample_rate : sample_rates) {
493 for (auto channel_mode : channel_modes) {
494 for (auto variable_bit_rate_enabled : variable_bit_rate_enableds) {
495 for (auto bits_per_sample : bits_per_samples) {
496 aac_data = {.objectType = object_type,
497 .sampleRate = sample_rate,
498 .channelMode = channel_mode,
499 .variableBitRateEnabled = variable_bit_rate_enabled,
500 .bitsPerSample = bits_per_sample};
501 codec_specific.aacConfig(aac_data);
502 aac_codec_specifics.push_back(codec_specific);
503 }
504 }
505 }
506 }
507 }
508 return aac_codec_specifics;
509 }
510
GetLdacCodecSpecificSupportedList(bool supported)511 std::vector<CodecSpecificConfig> GetLdacCodecSpecificSupportedList(
512 bool supported) {
513 std::vector<CodecSpecificConfig> ldac_codec_specifics;
514 GetOffloadCodecCapabilityHelper(CodecType::LDAC);
515 if (temp_codec_capabilities_.codecType != CodecType::LDAC) {
516 return ldac_codec_specifics;
517 }
518 // parse the capability
519 LdacParameters ldac_capability =
520 temp_codec_capabilities_.capabilities.ldacCapabilities();
521 std::vector<SampleRate> sample_rates = ExtractValuesFromBitmask<SampleRate>(
522 ldac_capability.sampleRate, 0xff, supported);
523 std::vector<LdacChannelMode> channel_modes =
524 ExtractValuesFromBitmask<LdacChannelMode>(ldac_capability.channelMode,
525 0x07, supported);
526 std::vector<LdacQualityIndex> quality_indexes = {
527 LdacQualityIndex::QUALITY_HIGH, LdacQualityIndex::QUALITY_MID,
528 LdacQualityIndex::QUALITY_LOW, LdacQualityIndex::QUALITY_ABR};
529 std::vector<BitsPerSample> bits_per_samples =
530 ExtractValuesFromBitmask<BitsPerSample>(ldac_capability.bitsPerSample,
531 0x07, supported);
532 // combine those parameters into one list of
533 // CodecConfiguration::CodecSpecific
534 CodecSpecificConfig codec_specific = {};
535 LdacParameters ldac_data;
536 for (auto sample_rate : sample_rates) {
537 for (auto channel_mode : channel_modes) {
538 for (auto quality_index : quality_indexes) {
539 for (auto bits_per_sample : bits_per_samples) {
540 ldac_data = {.sampleRate = sample_rate,
541 .channelMode = channel_mode,
542 .qualityIndex = quality_index,
543 .bitsPerSample = bits_per_sample};
544 codec_specific.ldacConfig(ldac_data);
545 ldac_codec_specifics.push_back(codec_specific);
546 }
547 }
548 }
549 }
550 return ldac_codec_specifics;
551 }
552
GetAptxCodecSpecificSupportedList(bool is_hd,bool supported)553 std::vector<CodecSpecificConfig> GetAptxCodecSpecificSupportedList(
554 bool is_hd, bool supported) {
555 std::vector<CodecSpecificConfig> aptx_codec_specifics;
556 GetOffloadCodecCapabilityHelper(
557 (is_hd ? CodecType::APTX_HD : CodecType::APTX));
558 if ((is_hd && temp_codec_capabilities_.codecType != CodecType::APTX_HD) ||
559 (!is_hd && temp_codec_capabilities_.codecType != CodecType::APTX)) {
560 return aptx_codec_specifics;
561 }
562 // parse the capability
563 AptxParameters aptx_capability =
564 temp_codec_capabilities_.capabilities.aptxCapabilities();
565 std::vector<SampleRate> sample_rates = ExtractValuesFromBitmask<SampleRate>(
566 aptx_capability.sampleRate, 0xff, supported);
567 std::vector<ChannelMode> channel_modes =
568 ExtractValuesFromBitmask<ChannelMode>(aptx_capability.channelMode, 0x03,
569 supported);
570 std::vector<BitsPerSample> bits_per_samples =
571 ExtractValuesFromBitmask<BitsPerSample>(aptx_capability.bitsPerSample,
572 0x07, supported);
573 // combine those parameters into one list of
574 // CodecConfiguration::CodecSpecific
575 CodecSpecificConfig codec_specific = {};
576 AptxParameters aptx_data;
577 for (auto sample_rate : sample_rates) {
578 for (auto channel_mode : channel_modes) {
579 for (auto bits_per_sample : bits_per_samples) {
580 aptx_data = {.sampleRate = sample_rate,
581 .channelMode = channel_mode,
582 .bitsPerSample = bits_per_sample};
583 codec_specific.aptxConfig(aptx_data);
584 aptx_codec_specifics.push_back(codec_specific);
585 }
586 }
587 }
588 return aptx_codec_specifics;
589 }
590
591 // temp storage saves the specified codec capability by
592 // GetOffloadCodecCapabilityHelper()
593 CodecCapabilities temp_codec_capabilities_;
594 };
595
596 /**
597 * Test whether we can open a provider of type
598 */
TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,OpenA2dpHardwareProvider)599 TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest, OpenA2dpHardwareProvider) {}
600
601 /**
602 * Test whether each provider of type
603 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
604 * SBC hardware encoding config
605 */
TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,StartAndEndA2dpSbcHardwareSession)606 TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,
607 StartAndEndA2dpSbcHardwareSession) {
608 if (!IsOffloadSupported()) {
609 return;
610 }
611
612 CodecConfiguration codec_config = {};
613 codec_config.codecType = CodecType::SBC;
614 codec_config.encodedAudioBitrate = 328000;
615 codec_config.peerMtu = 1005;
616 codec_config.isScmstEnabled = false;
617 AudioConfiguration audio_config = {};
618 std::vector<CodecSpecificConfig> sbc_codec_specifics =
619 GetSbcCodecSpecificSupportedList(true);
620 auto hidl_cb = [](BluetoothAudioStatus status,
621 const DataMQ::Descriptor& dataMQ) {
622 EXPECT_EQ(status, BluetoothAudioStatus::SUCCESS);
623 EXPECT_FALSE(dataMQ.isHandleValid());
624 };
625 for (auto codec_specific : sbc_codec_specifics) {
626 codec_config.config = codec_specific;
627 audio_config.codecConfig(codec_config);
628 auto hidl_retval =
629 audio_provider_->startSession(audio_port_, audio_config, hidl_cb);
630 // HIDL calls should not be failed and callback has to be executed
631 ASSERT_TRUE(hidl_retval.isOk());
632 EXPECT_TRUE(audio_provider_->endSession().isOk());
633 }
634 }
635
636 /**
637 * Test whether each provider of type
638 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
639 * AAC hardware encoding config
640 */
TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,StartAndEndA2dpAacHardwareSession)641 TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,
642 StartAndEndA2dpAacHardwareSession) {
643 if (!IsOffloadSupported()) {
644 return;
645 }
646
647 CodecConfiguration codec_config = {};
648 codec_config.codecType = CodecType::AAC;
649 codec_config.encodedAudioBitrate = 320000;
650 codec_config.peerMtu = 1005;
651 codec_config.isScmstEnabled = false;
652 AudioConfiguration audio_config = {};
653 std::vector<CodecSpecificConfig> aac_codec_specifics =
654 GetAacCodecSpecificSupportedList(true);
655 auto hidl_cb = [](BluetoothAudioStatus status,
656 const DataMQ::Descriptor& dataMQ) {
657 EXPECT_EQ(status, BluetoothAudioStatus::SUCCESS);
658 EXPECT_FALSE(dataMQ.isHandleValid());
659 };
660 for (auto codec_specific : aac_codec_specifics) {
661 codec_config.config = codec_specific;
662 audio_config.codecConfig(codec_config);
663 auto hidl_retval =
664 audio_provider_->startSession(audio_port_, audio_config, hidl_cb);
665 // HIDL calls should not be failed and callback has to be executed
666 ASSERT_TRUE(hidl_retval.isOk());
667 EXPECT_TRUE(audio_provider_->endSession().isOk());
668 }
669 }
670
671 /**
672 * Test whether each provider of type
673 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
674 * LDAC hardware encoding config
675 */
TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,StartAndEndA2dpLdacHardwareSession)676 TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,
677 StartAndEndA2dpLdacHardwareSession) {
678 if (!IsOffloadSupported()) {
679 return;
680 }
681
682 CodecConfiguration codec_config = {};
683 codec_config.codecType = CodecType::LDAC;
684 codec_config.encodedAudioBitrate = 990000;
685 codec_config.peerMtu = 1005;
686 codec_config.isScmstEnabled = false;
687 AudioConfiguration audio_config = {};
688 std::vector<CodecSpecificConfig> ldac_codec_specifics =
689 GetLdacCodecSpecificSupportedList(true);
690 auto hidl_cb = [](BluetoothAudioStatus status,
691 const DataMQ::Descriptor& dataMQ) {
692 EXPECT_EQ(status, BluetoothAudioStatus::SUCCESS);
693 EXPECT_FALSE(dataMQ.isHandleValid());
694 };
695 for (auto codec_specific : ldac_codec_specifics) {
696 codec_config.config = codec_specific;
697 audio_config.codecConfig(codec_config);
698 auto hidl_retval =
699 audio_provider_->startSession(audio_port_, audio_config, hidl_cb);
700 // HIDL calls should not be failed and callback has to be executed
701 ASSERT_TRUE(hidl_retval.isOk());
702 EXPECT_TRUE(audio_provider_->endSession().isOk());
703 }
704 }
705
706 /**
707 * Test whether each provider of type
708 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
709 * AptX hardware encoding config
710 */
TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,StartAndEndA2dpAptxHardwareSession)711 TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,
712 StartAndEndA2dpAptxHardwareSession) {
713 if (!IsOffloadSupported()) {
714 return;
715 }
716
717 for (auto codec_type : {CodecType::APTX, CodecType::APTX_HD}) {
718 CodecConfiguration codec_config = {};
719 codec_config.codecType = codec_type;
720 codec_config.encodedAudioBitrate =
721 (codec_type == CodecType::APTX ? 352000 : 576000);
722 codec_config.peerMtu = 1005;
723 codec_config.isScmstEnabled = false;
724 AudioConfiguration audio_config = {};
725 std::vector<CodecSpecificConfig> aptx_codec_specifics =
726 GetAptxCodecSpecificSupportedList(
727 (codec_type == CodecType::APTX_HD ? true : false), true);
728 auto hidl_cb = [](BluetoothAudioStatus status,
729 const DataMQ::Descriptor& dataMQ) {
730 EXPECT_EQ(status, BluetoothAudioStatus::SUCCESS);
731 EXPECT_FALSE(dataMQ.isHandleValid());
732 };
733 for (auto codec_specific : aptx_codec_specifics) {
734 codec_config.config = codec_specific;
735 audio_config.codecConfig(codec_config);
736 auto hidl_retval =
737 audio_provider_->startSession(audio_port_, audio_config, hidl_cb);
738 // HIDL calls should not be failed and callback has to be executed
739 ASSERT_TRUE(hidl_retval.isOk());
740 EXPECT_TRUE(audio_provider_->endSession().isOk());
741 }
742 }
743 }
744
745 /**
746 * Test whether each provider of type
747 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
748 * an invalid codec config
749 */
TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,StartAndEndA2dpHardwareSessionInvalidCodecConfig)750 TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,
751 StartAndEndA2dpHardwareSessionInvalidCodecConfig) {
752 if (!IsOffloadSupported()) {
753 return;
754 }
755 ASSERT_NE(audio_provider_, nullptr);
756
757 std::vector<CodecSpecificConfig> codec_specifics;
758 for (auto codec_type : a2dp_codec_types) {
759 switch (codec_type) {
760 case CodecType::SBC:
761 codec_specifics = GetSbcCodecSpecificSupportedList(false);
762 break;
763 case CodecType::AAC:
764 codec_specifics = GetAacCodecSpecificSupportedList(false);
765 break;
766 case CodecType::LDAC:
767 codec_specifics = GetLdacCodecSpecificSupportedList(false);
768 break;
769 case CodecType::APTX:
770 codec_specifics = GetAptxCodecSpecificSupportedList(false, false);
771 break;
772 case CodecType::APTX_HD:
773 codec_specifics = GetAptxCodecSpecificSupportedList(true, false);
774 break;
775 case CodecType::UNKNOWN:
776 codec_specifics.clear();
777 break;
778 }
779 if (codec_specifics.empty()) {
780 continue;
781 }
782
783 CodecConfiguration codec_config = {};
784 codec_config.codecType = codec_type;
785 codec_config.encodedAudioBitrate = 328000;
786 codec_config.peerMtu = 1005;
787 codec_config.isScmstEnabled = false;
788 AudioConfiguration audio_config = {};
789 auto hidl_cb = [](BluetoothAudioStatus status,
790 const DataMQ::Descriptor& dataMQ) {
791 EXPECT_EQ(status, BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION);
792 EXPECT_FALSE(dataMQ.isHandleValid());
793 };
794 for (auto codec_specific : codec_specifics) {
795 codec_config.config = codec_specific;
796 audio_config.codecConfig(codec_config);
797 auto hidl_retval =
798 audio_provider_->startSession(audio_port_, audio_config, hidl_cb);
799 // HIDL calls should not be failed and callback has to be executed
800 ASSERT_TRUE(hidl_retval.isOk());
801 EXPECT_TRUE(audio_provider_->endSession().isOk());
802 }
803 }
804 }
805
806 /**
807 * openProvider HEARING_AID_SOFTWARE_ENCODING_DATAPATH
808 */
809 class BluetoothAudioProviderHearingAidSoftwareHidlTest
810 : public BluetoothAudioProvidersFactoryHidlTest {
811 public:
SetUp()812 virtual void SetUp() override {
813 BluetoothAudioProvidersFactoryHidlTest::SetUp();
814 GetProviderCapabilitiesHelper(
815 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
816 OpenProviderHelper(SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
817 ASSERT_NE(audio_provider_, nullptr);
818 }
819
TearDown()820 virtual void TearDown() override {
821 audio_port_ = nullptr;
822 audio_provider_ = nullptr;
823 BluetoothAudioProvidersFactoryHidlTest::TearDown();
824 }
825
826 static constexpr SampleRate hearing_aid_sample_rates_[3] = {
827 SampleRate::RATE_UNKNOWN, SampleRate::RATE_16000, SampleRate::RATE_24000};
828 static constexpr BitsPerSample hearing_aid_bits_per_samples_[3] = {
829 BitsPerSample::BITS_UNKNOWN, BitsPerSample::BITS_16,
830 BitsPerSample::BITS_24};
831 static constexpr ChannelMode hearing_aid_channel_modes_[3] = {
832 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
833 };
834
835 /**
836 * Test whether each provider of type
837 * SessionType::HEARING_AID_HARDWARE_ENCODING_DATAPATH can be started and
838 * stopped with SBC hardware encoding config
839 */
TEST_P(BluetoothAudioProviderHearingAidSoftwareHidlTest,OpenHearingAidSoftwareProvider)840 TEST_P(BluetoothAudioProviderHearingAidSoftwareHidlTest,
841 OpenHearingAidSoftwareProvider) {}
842
843 /**
844 * Test whether each provider of type
845 * SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH can be started and
846 * stopped with different PCM config
847 */
TEST_P(BluetoothAudioProviderHearingAidSoftwareHidlTest,StartAndEndHearingAidSessionWithPossiblePcmConfig)848 TEST_P(BluetoothAudioProviderHearingAidSoftwareHidlTest,
849 StartAndEndHearingAidSessionWithPossiblePcmConfig) {
850 bool is_codec_config_valid;
851 std::unique_ptr<DataMQ> tempDataMQ;
852 auto hidl_cb = [&is_codec_config_valid, &tempDataMQ](
853 BluetoothAudioStatus status,
854 const DataMQ::Descriptor& dataMQ) {
855 if (is_codec_config_valid) {
856 ASSERT_EQ(status, BluetoothAudioStatus::SUCCESS);
857 ASSERT_TRUE(dataMQ.isHandleValid());
858 tempDataMQ.reset(new DataMQ(dataMQ));
859 } else {
860 EXPECT_EQ(status, BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION);
861 EXPECT_FALSE(dataMQ.isHandleValid());
862 }
863 };
864 AudioConfiguration audio_config = {};
865 PcmParameters pcm_parameters = {};
866 for (auto sample_rate : hearing_aid_sample_rates_) {
867 pcm_parameters.sampleRate = sample_rate;
868 for (auto bits_per_sample : hearing_aid_bits_per_samples_) {
869 pcm_parameters.bitsPerSample = bits_per_sample;
870 for (auto channel_mode : hearing_aid_channel_modes_) {
871 pcm_parameters.channelMode = channel_mode;
872 is_codec_config_valid = IsPcmParametersSupported(pcm_parameters);
873 audio_config.pcmConfig(pcm_parameters);
874 auto hidl_retval =
875 audio_provider_->startSession(audio_port_, audio_config, hidl_cb);
876 // HIDL calls should not be failed and callback has to be executed
877 ASSERT_TRUE(hidl_retval.isOk());
878 if (is_codec_config_valid) {
879 EXPECT_TRUE(tempDataMQ != nullptr && tempDataMQ->isValid());
880 }
881 EXPECT_TRUE(audio_provider_->endSession().isOk());
882 } // ChannelMode
883 } // BitsPerSampple
884 } // SampleRate
885 }
886
887 static const std::vector<std::string> kAudioInstances =
888 android::hardware::getAllHalInstanceNames(
889 IBluetoothAudioProvidersFactory::descriptor);
890
891 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
892 BluetoothAudioProvidersFactoryHidlTest);
893 INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProvidersFactoryHidlTest,
894 testing::ValuesIn(kAudioInstances),
895 android::hardware::PrintInstanceNameToString);
896
897 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
898 BluetoothAudioProviderA2dpSoftwareHidlTest);
899 INSTANTIATE_TEST_SUITE_P(PerInstance,
900 BluetoothAudioProviderA2dpSoftwareHidlTest,
901 testing::ValuesIn(kAudioInstances),
902 android::hardware::PrintInstanceNameToString);
903
904 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
905 BluetoothAudioProviderA2dpHardwareHidlTest);
906 INSTANTIATE_TEST_SUITE_P(PerInstance,
907 BluetoothAudioProviderA2dpHardwareHidlTest,
908 testing::ValuesIn(kAudioInstances),
909 android::hardware::PrintInstanceNameToString);
910
911 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
912 BluetoothAudioProviderHearingAidSoftwareHidlTest);
913 INSTANTIATE_TEST_SUITE_P(PerInstance,
914 BluetoothAudioProviderHearingAidSoftwareHidlTest,
915 testing::ValuesIn(kAudioInstances),
916 android::hardware::PrintInstanceNameToString);