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