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);