1 /*
2 * Copyright (C) 2022 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 #include <aidl/Gtest.h>
17 #include <aidl/Vintf.h>
18 #include <aidl/android/hardware/bluetooth/audio/BnBluetoothAudioPort.h>
19 #include <aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.h>
20 #include <aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.h>
21 #include <android/binder_auto_utils.h>
22 #include <android/binder_manager.h>
23 #include <android/binder_process.h>
24 #include <binder/IServiceManager.h>
25 #include <binder/ProcessState.h>
26 #include <cutils/properties.h>
27 #include <fmq/AidlMessageQueue.h>
28
29 #include <cstdint>
30 #include <future>
31 #include <unordered_set>
32 #include <vector>
33
34 using aidl::android::hardware::audio::common::SinkMetadata;
35 using aidl::android::hardware::audio::common::SourceMetadata;
36 using aidl::android::hardware::bluetooth::audio::A2dpConfiguration;
37 using aidl::android::hardware::bluetooth::audio::A2dpConfigurationHint;
38 using aidl::android::hardware::bluetooth::audio::A2dpRemoteCapabilities;
39 using aidl::android::hardware::bluetooth::audio::A2dpStatus;
40 using aidl::android::hardware::bluetooth::audio::A2dpStreamConfiguration;
41 using aidl::android::hardware::bluetooth::audio::AacCapabilities;
42 using aidl::android::hardware::bluetooth::audio::AacConfiguration;
43 using aidl::android::hardware::bluetooth::audio::AptxAdaptiveLeCapabilities;
44 using aidl::android::hardware::bluetooth::audio::AptxAdaptiveLeConfiguration;
45 using aidl::android::hardware::bluetooth::audio::AptxCapabilities;
46 using aidl::android::hardware::bluetooth::audio::AptxConfiguration;
47 using aidl::android::hardware::bluetooth::audio::AudioCapabilities;
48 using aidl::android::hardware::bluetooth::audio::AudioConfiguration;
49 using aidl::android::hardware::bluetooth::audio::AudioContext;
50 using aidl::android::hardware::bluetooth::audio::BnBluetoothAudioPort;
51 using aidl::android::hardware::bluetooth::audio::BroadcastCapability;
52 using aidl::android::hardware::bluetooth::audio::ChannelMode;
53 using aidl::android::hardware::bluetooth::audio::CodecCapabilities;
54 using aidl::android::hardware::bluetooth::audio::CodecConfiguration;
55 using aidl::android::hardware::bluetooth::audio::CodecId;
56 using aidl::android::hardware::bluetooth::audio::CodecInfo;
57 using aidl::android::hardware::bluetooth::audio::CodecParameters;
58 using aidl::android::hardware::bluetooth::audio::CodecSpecificCapabilitiesLtv;
59 using aidl::android::hardware::bluetooth::audio::CodecSpecificConfigurationLtv;
60 using aidl::android::hardware::bluetooth::audio::CodecType;
61 using aidl::android::hardware::bluetooth::audio::ConfigurationFlags;
62 using aidl::android::hardware::bluetooth::audio::HfpConfiguration;
63 using aidl::android::hardware::bluetooth::audio::IBluetoothAudioPort;
64 using aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider;
65 using aidl::android::hardware::bluetooth::audio::IBluetoothAudioProviderFactory;
66 using aidl::android::hardware::bluetooth::audio::LatencyMode;
67 using aidl::android::hardware::bluetooth::audio::Lc3Capabilities;
68 using aidl::android::hardware::bluetooth::audio::Lc3Configuration;
69 using aidl::android::hardware::bluetooth::audio::LdacCapabilities;
70 using aidl::android::hardware::bluetooth::audio::LdacConfiguration;
71 using aidl::android::hardware::bluetooth::audio::LeAudioAseConfiguration;
72 using aidl::android::hardware::bluetooth::audio::LeAudioBisConfiguration;
73 using aidl::android::hardware::bluetooth::audio::LeAudioBroadcastConfiguration;
74 using aidl::android::hardware::bluetooth::audio::
75 LeAudioCodecCapabilitiesSetting;
76 using aidl::android::hardware::bluetooth::audio::LeAudioCodecConfiguration;
77 using aidl::android::hardware::bluetooth::audio::LeAudioConfiguration;
78 using aidl::android::hardware::bluetooth::audio::MetadataLtv;
79 using aidl::android::hardware::bluetooth::audio::OpusCapabilities;
80 using aidl::android::hardware::bluetooth::audio::OpusConfiguration;
81 using aidl::android::hardware::bluetooth::audio::PcmConfiguration;
82 using aidl::android::hardware::bluetooth::audio::PresentationPosition;
83 using aidl::android::hardware::bluetooth::audio::SbcAllocMethod;
84 using aidl::android::hardware::bluetooth::audio::SbcCapabilities;
85 using aidl::android::hardware::bluetooth::audio::SbcChannelMode;
86 using aidl::android::hardware::bluetooth::audio::SbcConfiguration;
87 using aidl::android::hardware::bluetooth::audio::SessionType;
88 using aidl::android::hardware::bluetooth::audio::UnicastCapability;
89 using aidl::android::hardware::common::fmq::MQDescriptor;
90 using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
91 using android::AidlMessageQueue;
92 using android::ProcessState;
93 using android::String16;
94 using ndk::ScopedAStatus;
95 using ndk::SpAIBinder;
96
97 using MqDataType = int8_t;
98 using MqDataMode = SynchronizedReadWrite;
99 using DataMQ = AidlMessageQueue<MqDataType, MqDataMode>;
100 using DataMQDesc = MQDescriptor<MqDataType, MqDataMode>;
101
102 using LeAudioAseConfigurationSetting =
103 IBluetoothAudioProvider::LeAudioAseConfigurationSetting;
104 using AseDirectionRequirement = IBluetoothAudioProvider::
105 LeAudioConfigurationRequirement::AseDirectionRequirement;
106 using AseDirectionConfiguration = IBluetoothAudioProvider::
107 LeAudioAseConfigurationSetting::AseDirectionConfiguration;
108 using AseQosDirectionRequirement = IBluetoothAudioProvider::
109 LeAudioAseQosConfigurationRequirement::AseQosDirectionRequirement;
110 using LeAudioAseQosConfigurationRequirement =
111 IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement;
112 using LeAudioAseQosConfiguration =
113 IBluetoothAudioProvider::LeAudioAseQosConfiguration;
114 using LeAudioDeviceCapabilities =
115 IBluetoothAudioProvider::LeAudioDeviceCapabilities;
116 using LeAudioConfigurationRequirement =
117 IBluetoothAudioProvider::LeAudioConfigurationRequirement;
118 using LeAudioBroadcastConfigurationRequirement =
119 IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement;
120 using LeAudioBroadcastSubgroupConfiguration =
121 IBluetoothAudioProvider::LeAudioBroadcastSubgroupConfiguration;
122 using LeAudioBroadcastSubgroupConfigurationRequirement =
123 IBluetoothAudioProvider::LeAudioBroadcastSubgroupConfigurationRequirement;
124 using LeAudioBroadcastConfigurationSetting =
125 IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting;
126 using LeAudioSubgroupBisConfiguration =
127 IBluetoothAudioProvider::LeAudioSubgroupBisConfiguration;
128
129 // Constants
130
131 static constexpr int32_t a2dp_sample_rates[] = {0, 44100, 48000, 88200, 96000};
132 static constexpr int8_t a2dp_bits_per_samples[] = {0, 16, 24, 32};
133 static constexpr ChannelMode a2dp_channel_modes[] = {
134 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
135 static std::vector<LatencyMode> latency_modes = {LatencyMode::FREE};
136
137 enum class BluetoothAudioHalVersion : int32_t {
138 VERSION_UNAVAILABLE = 0,
139 VERSION_2_0,
140 VERSION_2_1,
141 VERSION_AIDL_V1,
142 VERSION_AIDL_V2,
143 VERSION_AIDL_V3,
144 VERSION_AIDL_V4,
145 VERSION_AIDL_V5,
146 };
147
148 // Some valid configs for HFP PCM configuration (software sessions)
149 static constexpr int32_t hfp_sample_rates_[] = {8000, 16000, 32000};
150 static constexpr int8_t hfp_bits_per_samples_[] = {16};
151 static constexpr ChannelMode hfp_channel_modes_[] = {ChannelMode::MONO};
152 static constexpr int32_t hfp_data_interval_us_[] = {7500};
153
154 // Helpers
155
156 template <typename T>
157 struct identity {
158 typedef T type;
159 };
160
161 template <class T>
contained_in_vector(const std::vector<T> & vector,const typename identity<T>::type & target)162 bool contained_in_vector(const std::vector<T>& vector,
163 const typename identity<T>::type& target) {
164 return std::find(vector.begin(), vector.end(), target) != vector.end();
165 }
166
copy_codec_specific(CodecConfiguration::CodecSpecific & dst,const CodecConfiguration::CodecSpecific & src)167 void copy_codec_specific(CodecConfiguration::CodecSpecific& dst,
168 const CodecConfiguration::CodecSpecific& src) {
169 switch (src.getTag()) {
170 case CodecConfiguration::CodecSpecific::sbcConfig:
171 dst.set<CodecConfiguration::CodecSpecific::sbcConfig>(
172 src.get<CodecConfiguration::CodecSpecific::sbcConfig>());
173 break;
174 case CodecConfiguration::CodecSpecific::aacConfig:
175 dst.set<CodecConfiguration::CodecSpecific::aacConfig>(
176 src.get<CodecConfiguration::CodecSpecific::aacConfig>());
177 break;
178 case CodecConfiguration::CodecSpecific::ldacConfig:
179 dst.set<CodecConfiguration::CodecSpecific::ldacConfig>(
180 src.get<CodecConfiguration::CodecSpecific::ldacConfig>());
181 break;
182 case CodecConfiguration::CodecSpecific::aptxConfig:
183 dst.set<CodecConfiguration::CodecSpecific::aptxConfig>(
184 src.get<CodecConfiguration::CodecSpecific::aptxConfig>());
185 break;
186 case CodecConfiguration::CodecSpecific::opusConfig:
187 dst.set<CodecConfiguration::CodecSpecific::opusConfig>(
188 src.get<CodecConfiguration::CodecSpecific::opusConfig>());
189 break;
190 case CodecConfiguration::CodecSpecific::aptxAdaptiveConfig:
191 dst.set<CodecConfiguration::CodecSpecific::aptxAdaptiveConfig>(
192 src.get<CodecConfiguration::CodecSpecific::aptxAdaptiveConfig>());
193 break;
194 default:
195 break;
196 }
197 }
198
GetConfigurationLtv(const std::vector<CodecSpecificConfigurationLtv> & configurationLtvs,CodecSpecificConfigurationLtv::Tag tag)199 static std::optional<CodecSpecificConfigurationLtv> GetConfigurationLtv(
200 const std::vector<CodecSpecificConfigurationLtv>& configurationLtvs,
201 CodecSpecificConfigurationLtv::Tag tag) {
202 for (const auto ltv : configurationLtvs) {
203 if (ltv.getTag() == tag) {
204 return ltv;
205 }
206 }
207 return std::nullopt;
208 }
209
210 class BluetoothAudioPort : public BnBluetoothAudioPort {
211 public:
BluetoothAudioPort()212 BluetoothAudioPort() {}
213
startStream(bool)214 ndk::ScopedAStatus startStream(bool) { return ScopedAStatus::ok(); }
215
suspendStream()216 ndk::ScopedAStatus suspendStream() { return ScopedAStatus::ok(); }
217
stopStream()218 ndk::ScopedAStatus stopStream() { return ScopedAStatus::ok(); }
219
getPresentationPosition(PresentationPosition *)220 ndk::ScopedAStatus getPresentationPosition(PresentationPosition*) {
221 return ScopedAStatus::ok();
222 }
223
updateSourceMetadata(const SourceMetadata &)224 ndk::ScopedAStatus updateSourceMetadata(const SourceMetadata&) {
225 return ScopedAStatus::ok();
226 }
227
updateSinkMetadata(const SinkMetadata &)228 ndk::ScopedAStatus updateSinkMetadata(const SinkMetadata&) {
229 return ScopedAStatus::ok();
230 }
231
setLatencyMode(const LatencyMode)232 ndk::ScopedAStatus setLatencyMode(const LatencyMode) {
233 return ScopedAStatus::ok();
234 }
235
setCodecType(const CodecType)236 ndk::ScopedAStatus setCodecType(const CodecType) {
237 return ScopedAStatus::ok();
238 }
239
240 protected:
241 virtual ~BluetoothAudioPort() = default;
242 };
243
244 class BluetoothAudioProviderFactoryAidl
245 : public testing::TestWithParam<std::string> {
246 public:
SetUp()247 virtual void SetUp() override {
248 provider_factory_ = IBluetoothAudioProviderFactory::fromBinder(
249 SpAIBinder(AServiceManager_getService(GetParam().c_str())));
250 audio_provider_ = nullptr;
251 ASSERT_NE(provider_factory_, nullptr);
252 }
253
TearDown()254 virtual void TearDown() override { provider_factory_ = nullptr; }
255
GetProviderInfoHelper(const SessionType & session_type)256 void GetProviderInfoHelper(const SessionType& session_type) {
257 temp_provider_info_ = std::nullopt;
258 auto aidl_reval =
259 provider_factory_->getProviderInfo(session_type, &temp_provider_info_);
260 }
261
GetProviderCapabilitiesHelper(const SessionType & session_type)262 void GetProviderCapabilitiesHelper(const SessionType& session_type) {
263 temp_provider_capabilities_.clear();
264 auto aidl_retval = provider_factory_->getProviderCapabilities(
265 session_type, &temp_provider_capabilities_);
266 // AIDL calls should not be failed and callback has to be executed
267 ASSERT_TRUE(aidl_retval.isOk());
268 switch (session_type) {
269 case SessionType::UNKNOWN: {
270 ASSERT_TRUE(temp_provider_capabilities_.empty());
271 } break;
272 case SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH:
273 case SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH:
274 case SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH:
275 case SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH:
276 case SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH:
277 case SessionType::HFP_SOFTWARE_ENCODING_DATAPATH: {
278 // All software paths are mandatory and must have exact 1
279 // "PcmParameters"
280 ASSERT_EQ(temp_provider_capabilities_.size(), 1);
281 ASSERT_EQ(temp_provider_capabilities_[0].getTag(),
282 AudioCapabilities::pcmCapabilities);
283 } break;
284 case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
285 case SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH: {
286 std::unordered_set<CodecType> codec_types;
287 // empty capability means offload is unsupported
288 for (auto& audio_capability : temp_provider_capabilities_) {
289 ASSERT_EQ(audio_capability.getTag(),
290 AudioCapabilities::a2dpCapabilities);
291 const auto& codec_capabilities =
292 audio_capability.get<AudioCapabilities::a2dpCapabilities>();
293 // Every codec can present once at most
294 ASSERT_EQ(codec_types.count(codec_capabilities.codecType), 0);
295 switch (codec_capabilities.codecType) {
296 case CodecType::SBC:
297 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
298 CodecCapabilities::Capabilities::sbcCapabilities);
299 break;
300 case CodecType::AAC:
301 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
302 CodecCapabilities::Capabilities::aacCapabilities);
303 break;
304 case CodecType::APTX:
305 case CodecType::APTX_HD:
306 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
307 CodecCapabilities::Capabilities::aptxCapabilities);
308 break;
309 case CodecType::LDAC:
310 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
311 CodecCapabilities::Capabilities::ldacCapabilities);
312 break;
313 case CodecType::OPUS:
314 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
315 CodecCapabilities::Capabilities::opusCapabilities);
316 break;
317 case CodecType::APTX_ADAPTIVE:
318 case CodecType::APTX_ADAPTIVE_LE:
319 case CodecType::APTX_ADAPTIVE_LEX:
320 case CodecType::LC3:
321 case CodecType::VENDOR:
322 case CodecType::UNKNOWN:
323 break;
324 }
325 codec_types.insert(codec_capabilities.codecType);
326 }
327 } break;
328 case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
329 case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
330 case SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH: {
331 // empty capability means offload is unsupported since capabilities are
332 // not hardcoded
333 for (auto audio_capability : temp_provider_capabilities_) {
334 ASSERT_EQ(audio_capability.getTag(),
335 AudioCapabilities::leAudioCapabilities);
336 }
337 } break;
338 case SessionType::A2DP_SOFTWARE_DECODING_DATAPATH:
339 case SessionType::HFP_SOFTWARE_DECODING_DATAPATH: {
340 if (!temp_provider_capabilities_.empty()) {
341 ASSERT_EQ(temp_provider_capabilities_.size(), 1);
342 ASSERT_EQ(temp_provider_capabilities_[0].getTag(),
343 AudioCapabilities::pcmCapabilities);
344 }
345 } break;
346 default: {
347 ASSERT_TRUE(temp_provider_capabilities_.empty());
348 }
349 }
350 }
351
352 /***
353 * This helps to open the specified provider and check the openProvider()
354 * has corruct return values. BUT, to keep it simple, it does not consider
355 * the capability, and please do so at the SetUp of each session's test.
356 ***/
OpenProviderHelper(const SessionType & session_type)357 void OpenProviderHelper(const SessionType& session_type) {
358 auto aidl_retval =
359 provider_factory_->openProvider(session_type, &audio_provider_);
360 if (aidl_retval.isOk()) {
361 ASSERT_NE(session_type, SessionType::UNKNOWN);
362 ASSERT_NE(audio_provider_, nullptr);
363 audio_port_ = ndk::SharedRefBase::make<BluetoothAudioPort>();
364 } else {
365 // optional session type
366 ASSERT_TRUE(
367 session_type == SessionType::UNKNOWN ||
368 session_type ==
369 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
370 session_type ==
371 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
372 session_type ==
373 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
374 session_type ==
375 SessionType::
376 LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
377 session_type ==
378 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
379 session_type == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH ||
380 session_type == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH ||
381 session_type == SessionType::HFP_SOFTWARE_DECODING_DATAPATH ||
382 session_type == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH);
383 ASSERT_EQ(audio_provider_, nullptr);
384 }
385 }
386
GetA2dpOffloadCapabilityHelper(const CodecType & codec_type)387 void GetA2dpOffloadCapabilityHelper(const CodecType& codec_type) {
388 temp_codec_capabilities_ = nullptr;
389 for (auto& codec_capability : temp_provider_capabilities_) {
390 auto& a2dp_capabilities =
391 codec_capability.get<AudioCapabilities::a2dpCapabilities>();
392 if (a2dp_capabilities.codecType != codec_type) {
393 continue;
394 }
395 temp_codec_capabilities_ = &a2dp_capabilities;
396 }
397 }
398
399 std::vector<CodecConfiguration::CodecSpecific>
GetSbcCodecSpecificSupportedList(bool supported)400 GetSbcCodecSpecificSupportedList(bool supported) {
401 std::vector<CodecConfiguration::CodecSpecific> sbc_codec_specifics;
402 if (!supported) {
403 SbcConfiguration sbc_config{.sampleRateHz = 0, .bitsPerSample = 0};
404 sbc_codec_specifics.push_back(
405 CodecConfiguration::CodecSpecific(sbc_config));
406 return sbc_codec_specifics;
407 }
408 GetA2dpOffloadCapabilityHelper(CodecType::SBC);
409 if (temp_codec_capabilities_ == nullptr ||
410 temp_codec_capabilities_->codecType != CodecType::SBC) {
411 return sbc_codec_specifics;
412 }
413 // parse the capability
414 auto& sbc_capability =
415 temp_codec_capabilities_->capabilities
416 .get<CodecCapabilities::Capabilities::sbcCapabilities>();
417 if (sbc_capability.minBitpool > sbc_capability.maxBitpool) {
418 return sbc_codec_specifics;
419 }
420
421 // combine those parameters into one list of
422 // CodecConfiguration::CodecSpecific
423 for (int32_t sample_rate : sbc_capability.sampleRateHz) {
424 for (int8_t block_length : sbc_capability.blockLength) {
425 for (int8_t num_subbands : sbc_capability.numSubbands) {
426 for (int8_t bits_per_sample : sbc_capability.bitsPerSample) {
427 for (auto channel_mode : sbc_capability.channelMode) {
428 for (auto alloc_method : sbc_capability.allocMethod) {
429 SbcConfiguration sbc_data = {
430 .sampleRateHz = sample_rate,
431 .channelMode = channel_mode,
432 .blockLength = block_length,
433 .numSubbands = num_subbands,
434 .allocMethod = alloc_method,
435 .bitsPerSample = bits_per_sample,
436 .minBitpool = sbc_capability.minBitpool,
437 .maxBitpool = sbc_capability.maxBitpool};
438 sbc_codec_specifics.push_back(
439 CodecConfiguration::CodecSpecific(sbc_data));
440 }
441 }
442 }
443 }
444 }
445 }
446 return sbc_codec_specifics;
447 }
448
449 std::vector<CodecConfiguration::CodecSpecific>
GetAacCodecSpecificSupportedList(bool supported)450 GetAacCodecSpecificSupportedList(bool supported) {
451 std::vector<CodecConfiguration::CodecSpecific> aac_codec_specifics;
452 if (!supported) {
453 AacConfiguration aac_config{.sampleRateHz = 0, .bitsPerSample = 0};
454 aac_codec_specifics.push_back(
455 CodecConfiguration::CodecSpecific(aac_config));
456 return aac_codec_specifics;
457 }
458 GetA2dpOffloadCapabilityHelper(CodecType::AAC);
459 if (temp_codec_capabilities_ == nullptr ||
460 temp_codec_capabilities_->codecType != CodecType::AAC) {
461 return aac_codec_specifics;
462 }
463 // parse the capability
464 auto& aac_capability =
465 temp_codec_capabilities_->capabilities
466 .get<CodecCapabilities::Capabilities::aacCapabilities>();
467
468 std::vector<bool> variable_bit_rate_enableds = {false};
469 if (aac_capability.variableBitRateSupported) {
470 variable_bit_rate_enableds.push_back(true);
471 }
472
473 std::vector<bool> adaptive_bit_rate_supporteds = {false};
474 if (aac_capability.adaptiveBitRateSupported) {
475 adaptive_bit_rate_supporteds.push_back(true);
476 }
477
478 // combine those parameters into one list of
479 // CodecConfiguration::CodecSpecific
480 for (auto object_type : aac_capability.objectType) {
481 for (int32_t sample_rate : aac_capability.sampleRateHz) {
482 for (auto channel_mode : aac_capability.channelMode) {
483 for (int8_t bits_per_sample : aac_capability.bitsPerSample) {
484 for (auto variable_bit_rate_enabled : variable_bit_rate_enableds) {
485 for (auto adaptive_bit_rate_supported :
486 adaptive_bit_rate_supporteds) {
487 AacConfiguration aac_data{
488 .objectType = object_type,
489 .sampleRateHz = sample_rate,
490 .channelMode = channel_mode,
491 .variableBitRateEnabled = variable_bit_rate_enabled,
492 .bitsPerSample = bits_per_sample,
493 .adaptiveBitRateSupported = adaptive_bit_rate_supported};
494 aac_codec_specifics.push_back(
495 CodecConfiguration::CodecSpecific(aac_data));
496 }
497 }
498 }
499 }
500 }
501 }
502 return aac_codec_specifics;
503 }
504
505 std::vector<CodecConfiguration::CodecSpecific>
GetLdacCodecSpecificSupportedList(bool supported)506 GetLdacCodecSpecificSupportedList(bool supported) {
507 std::vector<CodecConfiguration::CodecSpecific> ldac_codec_specifics;
508 if (!supported) {
509 LdacConfiguration ldac_config{.sampleRateHz = 0, .bitsPerSample = 0};
510 ldac_codec_specifics.push_back(
511 CodecConfiguration::CodecSpecific(ldac_config));
512 return ldac_codec_specifics;
513 }
514 GetA2dpOffloadCapabilityHelper(CodecType::LDAC);
515 if (temp_codec_capabilities_ == nullptr ||
516 temp_codec_capabilities_->codecType != CodecType::LDAC) {
517 return ldac_codec_specifics;
518 }
519 // parse the capability
520 auto& ldac_capability =
521 temp_codec_capabilities_->capabilities
522 .get<CodecCapabilities::Capabilities::ldacCapabilities>();
523
524 // combine those parameters into one list of
525 // CodecConfiguration::CodecSpecific
526 for (int32_t sample_rate : ldac_capability.sampleRateHz) {
527 for (int8_t bits_per_sample : ldac_capability.bitsPerSample) {
528 for (auto channel_mode : ldac_capability.channelMode) {
529 for (auto quality_index : ldac_capability.qualityIndex) {
530 LdacConfiguration ldac_data{.sampleRateHz = sample_rate,
531 .channelMode = channel_mode,
532 .qualityIndex = quality_index,
533 .bitsPerSample = bits_per_sample};
534 ldac_codec_specifics.push_back(
535 CodecConfiguration::CodecSpecific(ldac_data));
536 }
537 }
538 }
539 }
540 return ldac_codec_specifics;
541 }
542
543 std::vector<CodecConfiguration::CodecSpecific>
GetAptxCodecSpecificSupportedList(bool is_hd,bool supported)544 GetAptxCodecSpecificSupportedList(bool is_hd, bool supported) {
545 std::vector<CodecConfiguration::CodecSpecific> aptx_codec_specifics;
546 if (!supported) {
547 AptxConfiguration aptx_config{.sampleRateHz = 0, .bitsPerSample = 0};
548 aptx_codec_specifics.push_back(
549 CodecConfiguration::CodecSpecific(aptx_config));
550 return aptx_codec_specifics;
551 }
552 GetA2dpOffloadCapabilityHelper(
553 (is_hd ? CodecType::APTX_HD : CodecType::APTX));
554 if (temp_codec_capabilities_ == nullptr) {
555 return aptx_codec_specifics;
556 }
557 if ((is_hd && temp_codec_capabilities_->codecType != CodecType::APTX_HD) ||
558 (!is_hd && temp_codec_capabilities_->codecType != CodecType::APTX)) {
559 return aptx_codec_specifics;
560 }
561
562 // parse the capability
563 auto& aptx_capability =
564 temp_codec_capabilities_->capabilities
565 .get<CodecCapabilities::Capabilities::aptxCapabilities>();
566
567 // combine those parameters into one list of
568 // CodecConfiguration::CodecSpecific
569 for (int8_t bits_per_sample : aptx_capability.bitsPerSample) {
570 for (int32_t sample_rate : aptx_capability.sampleRateHz) {
571 for (auto channel_mode : aptx_capability.channelMode) {
572 AptxConfiguration aptx_data{.sampleRateHz = sample_rate,
573 .channelMode = channel_mode,
574 .bitsPerSample = bits_per_sample};
575 aptx_codec_specifics.push_back(
576 CodecConfiguration::CodecSpecific(aptx_data));
577 }
578 }
579 }
580 return aptx_codec_specifics;
581 }
582
583 std::vector<CodecConfiguration::CodecSpecific>
GetOpusCodecSpecificSupportedList(bool supported)584 GetOpusCodecSpecificSupportedList(bool supported) {
585 std::vector<CodecConfiguration::CodecSpecific> opus_codec_specifics;
586 if (!supported) {
587 OpusConfiguration opus_config{.samplingFrequencyHz = 0,
588 .frameDurationUs = 0};
589 opus_codec_specifics.push_back(
590 CodecConfiguration::CodecSpecific(opus_config));
591 return opus_codec_specifics;
592 }
593 GetA2dpOffloadCapabilityHelper(CodecType::OPUS);
594 if (temp_codec_capabilities_ == nullptr ||
595 temp_codec_capabilities_->codecType != CodecType::OPUS) {
596 return opus_codec_specifics;
597 }
598 // parse the capability
599 auto& opus_capability =
600 temp_codec_capabilities_->capabilities
601 .get<CodecCapabilities::Capabilities::opusCapabilities>();
602
603 // combine those parameters into one list of
604 // CodecConfiguration::CodecSpecific
605 for (int32_t samplingFrequencyHz : opus_capability->samplingFrequencyHz) {
606 for (int32_t frameDurationUs : opus_capability->frameDurationUs) {
607 for (auto channel_mode : opus_capability->channelMode) {
608 OpusConfiguration opus_data{
609 .samplingFrequencyHz = samplingFrequencyHz,
610 .frameDurationUs = frameDurationUs,
611 .channelMode = channel_mode,
612 };
613 opus_codec_specifics.push_back(
614 CodecConfiguration::CodecSpecific(opus_data));
615 }
616 }
617 }
618 return opus_codec_specifics;
619 }
620
IsPcmConfigSupported(const PcmConfiguration & pcm_config)621 bool IsPcmConfigSupported(const PcmConfiguration& pcm_config) {
622 if (temp_provider_capabilities_.size() != 1 ||
623 temp_provider_capabilities_[0].getTag() !=
624 AudioCapabilities::pcmCapabilities) {
625 return false;
626 }
627 auto pcm_capability = temp_provider_capabilities_[0]
628 .get<AudioCapabilities::pcmCapabilities>();
629 return (contained_in_vector(pcm_capability.channelMode,
630 pcm_config.channelMode) &&
631 contained_in_vector(pcm_capability.sampleRateHz,
632 pcm_config.sampleRateHz) &&
633 contained_in_vector(pcm_capability.bitsPerSample,
634 pcm_config.bitsPerSample));
635 }
636
637 std::shared_ptr<IBluetoothAudioProviderFactory> provider_factory_;
638 std::shared_ptr<IBluetoothAudioProvider> audio_provider_;
639 std::shared_ptr<IBluetoothAudioPort> audio_port_;
640 std::vector<AudioCapabilities> temp_provider_capabilities_;
641 std::optional<IBluetoothAudioProviderFactory::ProviderInfo>
642 temp_provider_info_;
643
644 // temp storage saves the specified codec capability by
645 // GetOffloadCodecCapabilityHelper()
646 CodecCapabilities* temp_codec_capabilities_;
647
648 static constexpr SessionType kSessionTypes[] = {
649 SessionType::UNKNOWN,
650 SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
651 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
652 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
653 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
654 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
655 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
656 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
657 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
658 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
659 SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
660 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
661 };
662
663 static constexpr SessionType kAndroidVSessionType[] = {
664 SessionType::HFP_SOFTWARE_ENCODING_DATAPATH,
665 SessionType::HFP_SOFTWARE_DECODING_DATAPATH,
666 };
667
GetProviderFactoryInterfaceVersion()668 BluetoothAudioHalVersion GetProviderFactoryInterfaceVersion() {
669 int32_t aidl_version = 0;
670 if (provider_factory_ == nullptr) {
671 return BluetoothAudioHalVersion::VERSION_UNAVAILABLE;
672 }
673
674 auto aidl_retval = provider_factory_->getInterfaceVersion(&aidl_version);
675 if (!aidl_retval.isOk()) {
676 return BluetoothAudioHalVersion::VERSION_UNAVAILABLE;
677 }
678 switch (aidl_version) {
679 case 1:
680 return BluetoothAudioHalVersion::VERSION_AIDL_V1;
681 case 2:
682 return BluetoothAudioHalVersion::VERSION_AIDL_V2;
683 case 3:
684 return BluetoothAudioHalVersion::VERSION_AIDL_V3;
685 case 4:
686 return BluetoothAudioHalVersion::VERSION_AIDL_V4;
687 case 5:
688 return BluetoothAudioHalVersion::VERSION_AIDL_V5;
689 default:
690 return BluetoothAudioHalVersion::VERSION_UNAVAILABLE;
691 }
692
693 return BluetoothAudioHalVersion::VERSION_UNAVAILABLE;
694 }
695 };
696
697 /**
698 * Test whether we can get the FactoryService from HIDL
699 */
TEST_P(BluetoothAudioProviderFactoryAidl,GetProviderFactoryService)700 TEST_P(BluetoothAudioProviderFactoryAidl, GetProviderFactoryService) {}
701
702 /**
703 * Test whether we can open a provider for each provider returned by
704 * getProviderCapabilities() with non-empty capabalities
705 */
TEST_P(BluetoothAudioProviderFactoryAidl,OpenProviderAndCheckCapabilitiesBySession)706 TEST_P(BluetoothAudioProviderFactoryAidl,
707 OpenProviderAndCheckCapabilitiesBySession) {
708 for (auto session_type : kSessionTypes) {
709 GetProviderCapabilitiesHelper(session_type);
710 OpenProviderHelper(session_type);
711 // We must be able to open a provider if its getProviderCapabilities()
712 // returns non-empty list.
713 EXPECT_TRUE(temp_provider_capabilities_.empty() ||
714 audio_provider_ != nullptr);
715 }
716 if (GetProviderFactoryInterfaceVersion() >=
717 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
718 for (auto session_type : kAndroidVSessionType) {
719 GetProviderCapabilitiesHelper(session_type);
720 OpenProviderHelper(session_type);
721 EXPECT_TRUE(temp_provider_capabilities_.empty() ||
722 audio_provider_ != nullptr);
723 }
724 }
725 }
726
727 /**
728 * Test that getProviderInfo, when implemented,
729 * returns empty information for session types for
730 * software data paths.
731 */
TEST_P(BluetoothAudioProviderFactoryAidl,getProviderInfo_invalidSessionTypes)732 TEST_P(BluetoothAudioProviderFactoryAidl, getProviderInfo_invalidSessionTypes) {
733 static constexpr SessionType kInvalidSessionTypes[]{
734 SessionType::UNKNOWN,
735 SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
736 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
737 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
738 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
739 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
740 SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
741 };
742
743 for (auto session_type : kInvalidSessionTypes) {
744 std::optional<IBluetoothAudioProviderFactory::ProviderInfo> provider_info =
745 std::nullopt;
746 auto aidl_retval =
747 provider_factory_->getProviderInfo(session_type, &provider_info);
748 if (!aidl_retval.isOk()) {
749 continue;
750 }
751
752 // If getProviderInfo is supported, the provider info
753 // must be empty for software session types.
754 ASSERT_FALSE(provider_info.has_value());
755 }
756 }
757
758 /**
759 * Test that getProviderInfo, when implemented,
760 * returns valid information for session types for
761 * a2dp hardware data paths.
762 */
TEST_P(BluetoothAudioProviderFactoryAidl,getProviderInfo_a2dpSessionTypes)763 TEST_P(BluetoothAudioProviderFactoryAidl, getProviderInfo_a2dpSessionTypes) {
764 static constexpr SessionType kA2dpSessionTypes[]{
765 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
766 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
767 };
768
769 for (auto session_type : kA2dpSessionTypes) {
770 std::optional<IBluetoothAudioProviderFactory::ProviderInfo> provider_info =
771 std::nullopt;
772 auto aidl_retval =
773 provider_factory_->getProviderInfo(session_type, &provider_info);
774 if (!aidl_retval.isOk() || !provider_info.has_value()) {
775 continue;
776 }
777
778 for (auto const& codec_info : provider_info->codecInfos) {
779 // The codec id must not be core.
780 ASSERT_NE(codec_info.id.getTag(), CodecId::core);
781 // The codec info must contain the information
782 // for a2dp transport.
783 ASSERT_EQ(codec_info.transport.getTag(), CodecInfo::Transport::a2dp);
784 }
785 }
786 }
787
788 /**
789 * Test that getProviderInfo, when implemented,
790 * returns valid information for session types for
791 * le audio hardware data paths.
792 */
TEST_P(BluetoothAudioProviderFactoryAidl,getProviderInfo_leAudioSessionTypes)793 TEST_P(BluetoothAudioProviderFactoryAidl, getProviderInfo_leAudioSessionTypes) {
794 static constexpr SessionType kLeAudioSessionTypes[]{
795 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
796 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
797 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
798 };
799
800 for (auto session_type : kLeAudioSessionTypes) {
801 std::optional<IBluetoothAudioProviderFactory::ProviderInfo> provider_info =
802 std::nullopt;
803 auto aidl_retval =
804 provider_factory_->getProviderInfo(session_type, &provider_info);
805 if (!aidl_retval.isOk() || !provider_info.has_value()) {
806 continue;
807 }
808
809 for (auto const& codec_info : provider_info->codecInfos) {
810 // The codec id must not be a2dp.
811 ASSERT_NE(codec_info.id.getTag(), CodecId::a2dp);
812 // The codec info must contain the information
813 // for le audio transport.
814 ASSERT_EQ(codec_info.transport.getTag(), CodecInfo::Transport::leAudio);
815 }
816 }
817 }
818
819 class BluetoothAudioProviderAidl : public BluetoothAudioProviderFactoryAidl {
820 protected:
821 std::optional<IBluetoothAudioProviderFactory::ProviderInfo>
822 a2dp_encoding_provider_info_{};
823 std::optional<IBluetoothAudioProviderFactory::ProviderInfo>
824 a2dp_decoding_provider_info_{};
825 std::shared_ptr<IBluetoothAudioProvider> a2dp_encoding_provider_{nullptr};
826 std::shared_ptr<IBluetoothAudioProvider> a2dp_decoding_provider_{nullptr};
827
828 public:
SetUp()829 void SetUp() override {
830 BluetoothAudioProviderFactoryAidl::SetUp();
831 audio_port_ = ndk::SharedRefBase::make<BluetoothAudioPort>();
832
833 (void)provider_factory_->getProviderInfo(
834 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
835 &a2dp_encoding_provider_info_);
836
837 (void)provider_factory_->getProviderInfo(
838 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
839 &a2dp_decoding_provider_info_);
840
841 (void)provider_factory_->openProvider(
842 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
843 &a2dp_encoding_provider_);
844
845 (void)provider_factory_->openProvider(
846 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
847 &a2dp_decoding_provider_);
848 }
849 };
850
851 /**
852 * Calling parseA2dpConfiguration on a session of a different type than
853 * A2DP_HARDWARE_OFFLOAD_(ENCODING|DECODING)_DATAPATH must fail.
854 */
TEST_P(BluetoothAudioProviderAidl,parseA2dpConfiguration_invalidSessionType)855 TEST_P(BluetoothAudioProviderAidl, parseA2dpConfiguration_invalidSessionType) {
856 static constexpr SessionType kInvalidSessionTypes[] = {
857 SessionType::UNKNOWN,
858 SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
859 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
860 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
861 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
862 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
863 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
864 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
865 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
866 SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
867 };
868
869 for (auto session_type : kInvalidSessionTypes) {
870 // Open a BluetoothAudioProvider instance of the selected session type.
871 // Skip validation if the provider cannot be opened.
872 std::shared_ptr<IBluetoothAudioProvider> provider{nullptr};
873 (void)provider_factory_->openProvider(session_type, &provider);
874 if (provider == nullptr) {
875 continue;
876 }
877
878 // parseA2dpConfiguration must fail without returning an A2dpStatus.
879 CodecId codec_id(CodecId::A2dp::SBC);
880 CodecParameters codec_parameters;
881 A2dpStatus a2dp_status = A2dpStatus::OK;
882 auto aidl_retval = provider->parseA2dpConfiguration(
883 codec_id, std::vector<uint8_t>{}, &codec_parameters, &a2dp_status);
884 EXPECT_FALSE(aidl_retval.isOk());
885 }
886 }
887
888 /**
889 * Calling parseA2dpConfiguration with an unknown codec must fail
890 * with the A2dpStatus code INVALID_CODEC_TYPE or NOT_SUPPORTED_CODEC_TYPE.
891 */
TEST_P(BluetoothAudioProviderAidl,parseA2dpConfiguration_unsupportedCodecType)892 TEST_P(BluetoothAudioProviderAidl,
893 parseA2dpConfiguration_unsupportedCodecType) {
894 CodecId unsupported_core_id(CodecId::Core::CVSD);
895 CodecId unsupported_vendor_id(
896 CodecId::Vendor(0xFCB1, 0x42)); // Google Codec #42
897
898 for (auto& provider : {a2dp_encoding_provider_, a2dp_decoding_provider_}) {
899 if (provider == nullptr) {
900 continue;
901 }
902
903 CodecParameters codec_parameters;
904 A2dpStatus a2dp_status = A2dpStatus::OK;
905 ::ndk::ScopedAStatus aidl_retval;
906
907 // Test with two invalid codec identifiers: vendor or core.
908 aidl_retval = provider->parseA2dpConfiguration(
909 unsupported_core_id, std::vector<uint8_t>{}, &codec_parameters,
910 &a2dp_status);
911 EXPECT_TRUE(!aidl_retval.isOk() ||
912 a2dp_status == A2dpStatus::NOT_SUPPORTED_CODEC_TYPE);
913
914 aidl_retval = provider->parseA2dpConfiguration(
915 unsupported_vendor_id, std::vector<uint8_t>{}, &codec_parameters,
916 &a2dp_status);
917 EXPECT_TRUE(!aidl_retval.isOk() ||
918 a2dp_status == A2dpStatus::NOT_SUPPORTED_CODEC_TYPE);
919 }
920 }
921
922 /**
923 * Calling parseA2dpConfiguration with a known codec and invalid configuration
924 * must fail with an A2dpStatus code different from INVALID_CODEC_TYPE or
925 * NOT_SUPPORTED_CODEC_TYPE.
926 */
TEST_P(BluetoothAudioProviderAidl,parseA2dpConfiguration_invalidConfiguration)927 TEST_P(BluetoothAudioProviderAidl,
928 parseA2dpConfiguration_invalidConfiguration) {
929 for (auto& [provider, provider_info] :
930 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
931 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
932 if (provider == nullptr || !provider_info.has_value() ||
933 provider_info->codecInfos.empty()) {
934 continue;
935 }
936
937 CodecParameters codec_parameters;
938 A2dpStatus a2dp_status = A2dpStatus::OK;
939 ::ndk::ScopedAStatus aidl_retval;
940
941 // Test with the first available codec in the provider info for testing.
942 // The test runs with an empty parameters array, anything more specific
943 // would need understanding the codec.
944 aidl_retval = provider->parseA2dpConfiguration(
945 provider_info->codecInfos[0].id, std::vector<uint8_t>{},
946 &codec_parameters, &a2dp_status);
947 ASSERT_TRUE(aidl_retval.isOk());
948 EXPECT_TRUE(a2dp_status != A2dpStatus::OK &&
949 a2dp_status != A2dpStatus::NOT_SUPPORTED_CODEC_TYPE &&
950 a2dp_status != A2dpStatus::INVALID_CODEC_TYPE);
951 }
952 }
953
954 /**
955 * Calling parseA2dpConfiguration with a known codec and valid parameters
956 * must return with A2dpStatus OK.
957 */
TEST_P(BluetoothAudioProviderAidl,parseA2dpConfiguration_valid)958 TEST_P(BluetoothAudioProviderAidl, parseA2dpConfiguration_valid) {
959 for (auto& [provider, provider_info] :
960 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
961 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
962 if (provider == nullptr || !provider_info.has_value() ||
963 provider_info->codecInfos.empty()) {
964 continue;
965 }
966
967 CodecParameters codec_parameters;
968 A2dpStatus a2dp_status = A2dpStatus::OK;
969 ::ndk::ScopedAStatus aidl_retval;
970
971 // Test with the first available codec in the provider info for testing.
972 // To get a valid configuration (the capabilities array in the provider
973 // info is not a selection), getA2dpConfiguration is used with the
974 // selected codec parameters as input.
975 auto const& codec_info = provider_info->codecInfos[0];
976 auto transport = codec_info.transport.get<CodecInfo::Transport::a2dp>();
977 A2dpRemoteCapabilities remote_capabilities(/*seid*/ 0, codec_info.id,
978 transport.capabilities);
979 std::optional<A2dpConfiguration> configuration;
980 aidl_retval = provider->getA2dpConfiguration(
981 std::vector<A2dpRemoteCapabilities>{remote_capabilities},
982 A2dpConfigurationHint(), &configuration);
983 ASSERT_TRUE(aidl_retval.isOk());
984 ASSERT_TRUE(configuration.has_value());
985
986 aidl_retval = provider->parseA2dpConfiguration(
987 configuration->id, configuration->configuration, &codec_parameters,
988 &a2dp_status);
989 ASSERT_TRUE(aidl_retval.isOk());
990 EXPECT_TRUE(a2dp_status == A2dpStatus::OK);
991 EXPECT_EQ(codec_parameters, configuration->parameters);
992 }
993 }
994
995 /**
996 * Calling getA2dpConfiguration on a session of a different type than
997 * A2DP_HARDWARE_OFFLOAD_(ENCODING|DECODING)_DATAPATH must fail.
998 */
TEST_P(BluetoothAudioProviderAidl,getA2dpConfiguration_invalidSessionType)999 TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_invalidSessionType) {
1000 static constexpr SessionType kInvalidSessionTypes[] = {
1001 SessionType::UNKNOWN,
1002 SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
1003 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
1004 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
1005 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
1006 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
1007 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
1008 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
1009 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
1010 SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
1011 };
1012
1013 for (auto session_type : kInvalidSessionTypes) {
1014 // Open a BluetoothAudioProvider instance of the selected session type.
1015 // Skip validation if the provider cannot be opened.
1016 std::shared_ptr<IBluetoothAudioProvider> provider{nullptr};
1017 auto aidl_retval = provider_factory_->openProvider(session_type, &provider);
1018 if (provider == nullptr) {
1019 continue;
1020 }
1021
1022 // getA2dpConfiguration must fail without returning a configuration.
1023 std::optional<A2dpConfiguration> configuration;
1024 aidl_retval =
1025 provider->getA2dpConfiguration(std::vector<A2dpRemoteCapabilities>{},
1026 A2dpConfigurationHint(), &configuration);
1027 EXPECT_FALSE(aidl_retval.isOk());
1028 }
1029 }
1030
1031 /**
1032 * Calling getA2dpConfiguration with empty or unknown remote capabilities
1033 * must return an empty configuration.
1034 */
TEST_P(BluetoothAudioProviderAidl,getA2dpConfiguration_unknownRemoteCapabilities)1035 TEST_P(BluetoothAudioProviderAidl,
1036 getA2dpConfiguration_unknownRemoteCapabilities) {
1037 for (auto& [provider, provider_info] :
1038 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1039 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1040 if (provider == nullptr || !provider_info.has_value() ||
1041 provider_info->codecInfos.empty()) {
1042 continue;
1043 }
1044
1045 std::optional<A2dpConfiguration> configuration;
1046 ::ndk::ScopedAStatus aidl_retval;
1047
1048 // Test with empty remote capabilities.
1049 aidl_retval =
1050 provider->getA2dpConfiguration(std::vector<A2dpRemoteCapabilities>{},
1051 A2dpConfigurationHint(), &configuration);
1052 ASSERT_TRUE(aidl_retval.isOk());
1053 EXPECT_FALSE(configuration.has_value());
1054
1055 // Test with unknown remote capabilities.
1056 A2dpRemoteCapabilities unknown_core_remote_capabilities(
1057 /*seid*/ 0, CodecId::Core::CVSD, std::vector<uint8_t>{1, 2, 3});
1058 A2dpRemoteCapabilities unknown_vendor_remote_capabilities(
1059 /*seid*/ 1,
1060 /* Google Codec #42 */ CodecId::Vendor(0xFCB1, 0x42),
1061 std::vector<uint8_t>{1, 2, 3});
1062 aidl_retval = provider->getA2dpConfiguration(
1063 std::vector<A2dpRemoteCapabilities>{
1064 unknown_core_remote_capabilities,
1065 unknown_vendor_remote_capabilities,
1066 },
1067 A2dpConfigurationHint(), &configuration);
1068 ASSERT_TRUE(aidl_retval.isOk());
1069 EXPECT_FALSE(configuration.has_value());
1070 }
1071 }
1072
1073 /**
1074 * Calling getA2dpConfiguration with invalid remote capabilities
1075 * must return an empty configuration.
1076 */
TEST_P(BluetoothAudioProviderAidl,getA2dpConfiguration_invalidRemoteCapabilities)1077 TEST_P(BluetoothAudioProviderAidl,
1078 getA2dpConfiguration_invalidRemoteCapabilities) {
1079 for (auto& [provider, provider_info] :
1080 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1081 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1082 if (provider == nullptr || !provider_info.has_value() ||
1083 provider_info->codecInfos.empty()) {
1084 continue;
1085 }
1086
1087 std::optional<A2dpConfiguration> configuration;
1088 ::ndk::ScopedAStatus aidl_retval;
1089
1090 // Use the first available codec in the provider info for testing.
1091 // The capabilities are modified to make them invalid.
1092 auto const& codec_info = provider_info->codecInfos[0];
1093 auto transport = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1094 std::vector<uint8_t> invalid_capabilities = transport.capabilities;
1095 invalid_capabilities.push_back(0x42); // adding bytes should be invalid.
1096 aidl_retval = provider->getA2dpConfiguration(
1097 std::vector<A2dpRemoteCapabilities>{
1098 A2dpRemoteCapabilities(/*seid*/ 0, codec_info.id,
1099 std::vector<uint8_t>()),
1100 A2dpRemoteCapabilities(/*seid*/ 1, codec_info.id,
1101 invalid_capabilities),
1102 },
1103 A2dpConfigurationHint(), &configuration);
1104 ASSERT_TRUE(aidl_retval.isOk());
1105 EXPECT_FALSE(configuration.has_value());
1106 }
1107 }
1108
1109 /**
1110 * Calling getA2dpConfiguration with valid remote capabilities
1111 * must return a valid configuration. The selected parameters must
1112 * be contained in the original capabilities. The returned configuration
1113 * must match the returned parameters. The returned SEID must match the
1114 * input SEID.
1115 */
TEST_P(BluetoothAudioProviderAidl,getA2dpConfiguration_validRemoteCapabilities)1116 TEST_P(BluetoothAudioProviderAidl,
1117 getA2dpConfiguration_validRemoteCapabilities) {
1118 for (auto& [provider, provider_info] :
1119 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1120 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1121 if (provider == nullptr || !provider_info.has_value() ||
1122 provider_info->codecInfos.empty()) {
1123 continue;
1124 }
1125
1126 // Test with all available codecs in the provider info.
1127 for (auto const& codec_info : provider_info->codecInfos) {
1128 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1129 std::optional<A2dpConfiguration> configuration{};
1130 ::ndk::ScopedAStatus aidl_retval;
1131
1132 aidl_retval = provider->getA2dpConfiguration(
1133 std::vector<A2dpRemoteCapabilities>{
1134 A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
1135 a2dp_info.capabilities),
1136 },
1137 A2dpConfigurationHint(), &configuration);
1138
1139 ASSERT_TRUE(aidl_retval.isOk());
1140 ASSERT_TRUE(configuration.has_value());
1141
1142 // Returned configuration must have the same codec id
1143 // as the remote capability.
1144 EXPECT_EQ(configuration->id, codec_info.id);
1145
1146 // Returned configuration must have the same SEID
1147 // as the remote capability.
1148 EXPECT_EQ(configuration->remoteSeid, 42);
1149
1150 // Returned codec parameters must be in the range of input
1151 // parameters.
1152 EXPECT_NE(
1153 std::find(a2dp_info.channelMode.begin(), a2dp_info.channelMode.end(),
1154 configuration->parameters.channelMode),
1155 a2dp_info.channelMode.end());
1156 EXPECT_NE(std::find(a2dp_info.samplingFrequencyHz.begin(),
1157 a2dp_info.samplingFrequencyHz.end(),
1158 configuration->parameters.samplingFrequencyHz),
1159 a2dp_info.samplingFrequencyHz.end());
1160 EXPECT_NE(std::find(a2dp_info.bitdepth.begin(), a2dp_info.bitdepth.end(),
1161 configuration->parameters.bitdepth),
1162 a2dp_info.bitdepth.end());
1163 EXPECT_EQ(a2dp_info.lossless, configuration->parameters.lossless);
1164 EXPECT_TRUE(configuration->parameters.minBitrate <=
1165 configuration->parameters.maxBitrate);
1166
1167 // Returned configuration must be parsable by parseA2dpParameters
1168 // and match the codec parameters.
1169 CodecParameters codec_parameters;
1170 A2dpStatus a2dp_status = A2dpStatus::OK;
1171 aidl_retval = provider->parseA2dpConfiguration(
1172 configuration->id, configuration->configuration, &codec_parameters,
1173 &a2dp_status);
1174 ASSERT_TRUE(aidl_retval.isOk());
1175 EXPECT_TRUE(a2dp_status == A2dpStatus::OK);
1176 EXPECT_EQ(codec_parameters, configuration->parameters);
1177 }
1178 }
1179 }
1180
1181 /**
1182 * Calling getA2dpConfiguration with valid remote capabilities
1183 * with various hinted codec ids.
1184 */
TEST_P(BluetoothAudioProviderAidl,getA2dpConfiguration_hintCodecId)1185 TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_hintCodecId) {
1186 for (auto& [provider, provider_info] :
1187 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1188 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1189 if (provider == nullptr || !provider_info.has_value() ||
1190 provider_info->codecInfos.empty()) {
1191 continue;
1192 }
1193
1194 // Build the remote capabilities with all supported codecs.
1195 std::vector<A2dpRemoteCapabilities> remote_capabilities;
1196 for (size_t n = 0; n < provider_info->codecInfos.size(); n++) {
1197 auto const& codec_info = provider_info->codecInfos[n];
1198 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1199 remote_capabilities.push_back(A2dpRemoteCapabilities(
1200 /*seid*/ n, codec_info.id, a2dp_info.capabilities));
1201 }
1202
1203 // Test with all supported codec identifiers,
1204 for (auto const& codec_info : provider_info->codecInfos) {
1205 std::optional<A2dpConfiguration> configuration{};
1206 ::ndk::ScopedAStatus aidl_retval;
1207
1208 A2dpConfigurationHint hint;
1209 hint.codecId = codec_info.id;
1210
1211 aidl_retval = provider->getA2dpConfiguration(remote_capabilities, hint,
1212 &configuration);
1213
1214 ASSERT_TRUE(aidl_retval.isOk());
1215 ASSERT_TRUE(configuration.has_value());
1216 EXPECT_EQ(configuration->id, codec_info.id);
1217 }
1218
1219 // Test with unknown codec identifiers: either core or vendor.
1220 for (auto& codec_id :
1221 {CodecId(CodecId::Core::CVSD),
1222 CodecId(CodecId::Vendor(0xFCB1, 0x42)) /*Google Codec #42*/}) {
1223 std::optional<A2dpConfiguration> configuration{};
1224 ::ndk::ScopedAStatus aidl_retval;
1225
1226 A2dpConfigurationHint hint;
1227 hint.codecId = codec_id;
1228
1229 aidl_retval = provider->getA2dpConfiguration(remote_capabilities, hint,
1230 &configuration);
1231
1232 ASSERT_TRUE(aidl_retval.isOk());
1233 ASSERT_TRUE(configuration.has_value());
1234 EXPECT_NE(configuration->id, codec_id);
1235 }
1236 }
1237 }
1238
1239 /**
1240 * Calling getA2dpConfiguration with valid remote capabilities
1241 * with various hinted channel modes.
1242 */
TEST_P(BluetoothAudioProviderAidl,getA2dpConfiguration_hintChannelMode)1243 TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_hintChannelMode) {
1244 for (auto& [provider, provider_info] :
1245 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1246 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1247 if (provider == nullptr || !provider_info.has_value() ||
1248 provider_info->codecInfos.empty()) {
1249 continue;
1250 }
1251
1252 // Test with all available codecs in the provider info.
1253 for (auto const& codec_info : provider_info->codecInfos) {
1254 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1255 std::optional<A2dpConfiguration> configuration{};
1256 ::ndk::ScopedAStatus aidl_retval;
1257
1258 for (auto& channel_mode :
1259 {ChannelMode::STEREO, ChannelMode::MONO, ChannelMode::DUALMONO}) {
1260 // Add the hint for the channel mode.
1261 A2dpConfigurationHint hint;
1262 auto& codec_parameters = hint.codecParameters.emplace();
1263 codec_parameters.channelMode = channel_mode;
1264
1265 aidl_retval = provider->getA2dpConfiguration(
1266 std::vector<A2dpRemoteCapabilities>{
1267 A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
1268 a2dp_info.capabilities),
1269 },
1270 hint, &configuration);
1271
1272 ASSERT_TRUE(aidl_retval.isOk());
1273 ASSERT_TRUE(configuration.has_value());
1274
1275 // The hint must be ignored if the channel mode is not supported
1276 // by the codec, and applied otherwise.
1277 ASSERT_EQ(configuration->parameters.channelMode == channel_mode,
1278 std::find(a2dp_info.channelMode.begin(),
1279 a2dp_info.channelMode.end(),
1280 channel_mode) != a2dp_info.channelMode.end());
1281 }
1282 }
1283 }
1284 }
1285
1286 /**
1287 * Calling getA2dpConfiguration with valid remote capabilities
1288 * with various hinted sampling frequencies.
1289 */
TEST_P(BluetoothAudioProviderAidl,getA2dpConfiguration_hintSamplingFrequencyHz)1290 TEST_P(BluetoothAudioProviderAidl,
1291 getA2dpConfiguration_hintSamplingFrequencyHz) {
1292 for (auto& [provider, provider_info] :
1293 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1294 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1295 if (provider == nullptr || !provider_info.has_value() ||
1296 provider_info->codecInfos.empty()) {
1297 continue;
1298 }
1299
1300 // Test with all available codecs in the provider info.
1301 for (auto const& codec_info : provider_info->codecInfos) {
1302 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1303 std::optional<A2dpConfiguration> configuration{};
1304 ::ndk::ScopedAStatus aidl_retval;
1305
1306 for (auto& sampling_frequency_hz : {
1307 0,
1308 1,
1309 8000,
1310 16000,
1311 24000,
1312 32000,
1313 44100,
1314 48000,
1315 88200,
1316 96000,
1317 176400,
1318 192000,
1319 }) {
1320 // Add the hint for the sampling frequency.
1321 A2dpConfigurationHint hint;
1322 auto& codec_parameters = hint.codecParameters.emplace();
1323 codec_parameters.samplingFrequencyHz = sampling_frequency_hz;
1324
1325 aidl_retval = provider->getA2dpConfiguration(
1326 std::vector<A2dpRemoteCapabilities>{
1327 A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
1328 a2dp_info.capabilities),
1329 },
1330 hint, &configuration);
1331
1332 ASSERT_TRUE(aidl_retval.isOk());
1333 ASSERT_TRUE(configuration.has_value());
1334
1335 // The hint must be ignored if the sampling frequency is not supported
1336 // by the codec, and applied otherwise.
1337 ASSERT_EQ(configuration->parameters.samplingFrequencyHz ==
1338 sampling_frequency_hz,
1339 std::find(a2dp_info.samplingFrequencyHz.begin(),
1340 a2dp_info.samplingFrequencyHz.end(),
1341 sampling_frequency_hz) !=
1342 a2dp_info.samplingFrequencyHz.end());
1343 }
1344 }
1345 }
1346 }
1347
1348 /**
1349 * Calling getA2dpConfiguration with valid remote capabilities
1350 * with various hinted sampling bit-depths.
1351 */
TEST_P(BluetoothAudioProviderAidl,getA2dpConfiguration_hintBitdepth)1352 TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_hintBitdepth) {
1353 for (auto& [provider, provider_info] :
1354 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1355 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1356 if (provider == nullptr || !provider_info.has_value() ||
1357 provider_info->codecInfos.empty()) {
1358 continue;
1359 }
1360
1361 // Test with all available codecs in the provider info.
1362 for (auto const& codec_info : provider_info->codecInfos) {
1363 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1364 std::optional<A2dpConfiguration> configuration{};
1365 ::ndk::ScopedAStatus aidl_retval;
1366
1367 for (auto& bitdepth : {0, 1, 16, 24, 32}) {
1368 // Add the hint for the bit depth.
1369 A2dpConfigurationHint hint;
1370 auto& codec_parameters = hint.codecParameters.emplace();
1371 codec_parameters.bitdepth = bitdepth;
1372
1373 aidl_retval = provider->getA2dpConfiguration(
1374 std::vector<A2dpRemoteCapabilities>{
1375 A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
1376 a2dp_info.capabilities),
1377 },
1378 hint, &configuration);
1379
1380 ASSERT_TRUE(aidl_retval.isOk());
1381 ASSERT_TRUE(configuration.has_value());
1382
1383 // The hint must be ignored if the bitdepth is not supported
1384 // by the codec, and applied otherwise.
1385 ASSERT_EQ(
1386 configuration->parameters.bitdepth == bitdepth,
1387 std::find(a2dp_info.bitdepth.begin(), a2dp_info.bitdepth.end(),
1388 bitdepth) != a2dp_info.bitdepth.end());
1389 }
1390 }
1391 }
1392 }
1393
1394 /**
1395 * Calling startSession with an unknown codec id must fail.
1396 */
TEST_P(BluetoothAudioProviderAidl,startSession_unknownCodecId)1397 TEST_P(BluetoothAudioProviderAidl, startSession_unknownCodecId) {
1398 for (auto& [provider, provider_info] :
1399 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1400 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1401 if (provider == nullptr || !provider_info.has_value() ||
1402 provider_info->codecInfos.empty()) {
1403 continue;
1404 }
1405
1406 for (auto& codec_id :
1407 {CodecId(CodecId::Core::CVSD),
1408 CodecId(CodecId::Vendor(0xFCB1, 0x42) /*Google Codec #42*/)}) {
1409 A2dpStreamConfiguration a2dp_config;
1410 DataMQDesc data_mq_desc;
1411
1412 a2dp_config.codecId = codec_id;
1413 a2dp_config.configuration = std::vector<uint8_t>{1, 2, 3};
1414
1415 auto aidl_retval =
1416 provider->startSession(audio_port_, AudioConfiguration(a2dp_config),
1417 std::vector<LatencyMode>{}, &data_mq_desc);
1418
1419 EXPECT_FALSE(aidl_retval.isOk());
1420 }
1421 }
1422 }
1423
1424 /**
1425 * Calling startSession with a known codec and a valid configuration
1426 * must succeed.
1427 */
TEST_P(BluetoothAudioProviderAidl,startSession_valid)1428 TEST_P(BluetoothAudioProviderAidl, startSession_valid) {
1429 for (auto& [provider, provider_info] :
1430 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1431 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1432 if (provider == nullptr || !provider_info.has_value() ||
1433 provider_info->codecInfos.empty()) {
1434 continue;
1435 }
1436
1437 // Use the first available codec in the provider info for testing.
1438 // To get a valid configuration (the capabilities array in the provider
1439 // info is not a selection), getA2dpConfiguration is used with the
1440 // selected codec parameters as input.
1441 auto const& codec_info = provider_info->codecInfos[0];
1442 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1443 ::ndk::ScopedAStatus aidl_retval;
1444 A2dpRemoteCapabilities remote_capabilities(/*seid*/ 0, codec_info.id,
1445 a2dp_info.capabilities);
1446 std::optional<A2dpConfiguration> configuration;
1447 aidl_retval = provider->getA2dpConfiguration(
1448 std::vector<A2dpRemoteCapabilities>{remote_capabilities},
1449 A2dpConfigurationHint(), &configuration);
1450 ASSERT_TRUE(aidl_retval.isOk());
1451 ASSERT_TRUE(configuration.has_value());
1452
1453 // Build the stream configuration.
1454 A2dpStreamConfiguration a2dp_config;
1455 DataMQDesc data_mq_desc;
1456
1457 a2dp_config.codecId = codec_info.id;
1458 a2dp_config.configuration = configuration->configuration;
1459
1460 aidl_retval =
1461 provider->startSession(audio_port_, AudioConfiguration(a2dp_config),
1462 std::vector<LatencyMode>{}, &data_mq_desc);
1463
1464 EXPECT_TRUE(aidl_retval.isOk());
1465 }
1466 }
1467
1468 /**
1469 * Calling startSession with a known codec but an invalid configuration
1470 * must fail.
1471 */
TEST_P(BluetoothAudioProviderAidl,startSession_invalidConfiguration)1472 TEST_P(BluetoothAudioProviderAidl, startSession_invalidConfiguration) {
1473 for (auto& [provider, provider_info] :
1474 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1475 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1476 if (provider == nullptr || !provider_info.has_value() ||
1477 provider_info->codecInfos.empty()) {
1478 continue;
1479 }
1480
1481 // Use the first available codec in the provider info for testing.
1482 // To get a valid configuration (the capabilities array in the provider
1483 // info is not a selection), getA2dpConfiguration is used with the
1484 // selected codec parameters as input.
1485 ::ndk::ScopedAStatus aidl_retval;
1486 auto const& codec_info = provider_info->codecInfos[0];
1487 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1488 A2dpRemoteCapabilities remote_capabilities(/*seid*/ 0, codec_info.id,
1489 a2dp_info.capabilities);
1490 std::optional<A2dpConfiguration> configuration;
1491 aidl_retval = provider->getA2dpConfiguration(
1492 std::vector<A2dpRemoteCapabilities>{remote_capabilities},
1493 A2dpConfigurationHint(), &configuration);
1494 ASSERT_TRUE(aidl_retval.isOk());
1495 ASSERT_TRUE(configuration.has_value());
1496
1497 // Build the stream configuration but edit the configuration bytes
1498 // to make it invalid.
1499 A2dpStreamConfiguration a2dp_config;
1500 DataMQDesc data_mq_desc;
1501
1502 a2dp_config.codecId = codec_info.id;
1503 a2dp_config.configuration = configuration->configuration;
1504 a2dp_config.configuration.push_back(42);
1505
1506 aidl_retval =
1507 provider->startSession(audio_port_, AudioConfiguration(a2dp_config),
1508 std::vector<LatencyMode>{}, &data_mq_desc);
1509
1510 EXPECT_FALSE(aidl_retval.isOk());
1511 }
1512 }
1513
1514 /**
1515 * openProvider A2DP_SOFTWARE_ENCODING_DATAPATH
1516 */
1517 class BluetoothAudioProviderA2dpEncodingSoftwareAidl
1518 : public BluetoothAudioProviderFactoryAidl {
1519 public:
SetUp()1520 virtual void SetUp() override {
1521 BluetoothAudioProviderFactoryAidl::SetUp();
1522 GetProviderCapabilitiesHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
1523 OpenProviderHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
1524 ASSERT_NE(audio_provider_, nullptr);
1525 }
1526
TearDown()1527 virtual void TearDown() override {
1528 audio_port_ = nullptr;
1529 audio_provider_ = nullptr;
1530 BluetoothAudioProviderFactoryAidl::TearDown();
1531 }
1532 };
1533
1534 /**
1535 * Test whether we can open a provider of type
1536 */
TEST_P(BluetoothAudioProviderA2dpEncodingSoftwareAidl,OpenA2dpEncodingSoftwareProvider)1537 TEST_P(BluetoothAudioProviderA2dpEncodingSoftwareAidl,
1538 OpenA2dpEncodingSoftwareProvider) {}
1539
1540 /**
1541 * Test whether each provider of type
1542 * SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH can be started and stopped
1543 * with different PCM config
1544 */
TEST_P(BluetoothAudioProviderA2dpEncodingSoftwareAidl,StartAndEndA2dpEncodingSoftwareSessionWithPossiblePcmConfig)1545 TEST_P(BluetoothAudioProviderA2dpEncodingSoftwareAidl,
1546 StartAndEndA2dpEncodingSoftwareSessionWithPossiblePcmConfig) {
1547 for (auto sample_rate : a2dp_sample_rates) {
1548 for (auto bits_per_sample : a2dp_bits_per_samples) {
1549 for (auto channel_mode : a2dp_channel_modes) {
1550 PcmConfiguration pcm_config{
1551 .sampleRateHz = sample_rate,
1552 .channelMode = channel_mode,
1553 .bitsPerSample = bits_per_sample,
1554 };
1555 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
1556 DataMQDesc mq_desc;
1557 auto aidl_retval = audio_provider_->startSession(
1558 audio_port_, AudioConfiguration(pcm_config), latency_modes,
1559 &mq_desc);
1560 DataMQ data_mq(mq_desc);
1561
1562 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
1563 if (is_codec_config_valid) {
1564 EXPECT_TRUE(data_mq.isValid());
1565 }
1566 EXPECT_TRUE(audio_provider_->endSession().isOk());
1567 }
1568 }
1569 }
1570 }
1571
1572 /**
1573 * openProvider HFP_SOFTWARE_ENCODING_DATAPATH
1574 */
1575 class BluetoothAudioProviderHfpSoftwareEncodingAidl
1576 : public BluetoothAudioProviderFactoryAidl {
1577 public:
SetUp()1578 virtual void SetUp() override {
1579 BluetoothAudioProviderFactoryAidl::SetUp();
1580 if (GetProviderFactoryInterfaceVersion() <
1581 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
1582 GTEST_SKIP();
1583 }
1584 GetProviderCapabilitiesHelper(SessionType::HFP_SOFTWARE_ENCODING_DATAPATH);
1585 OpenProviderHelper(SessionType::HFP_SOFTWARE_ENCODING_DATAPATH);
1586 ASSERT_NE(audio_provider_, nullptr);
1587 }
1588
TearDown()1589 virtual void TearDown() override {
1590 audio_port_ = nullptr;
1591 audio_provider_ = nullptr;
1592 BluetoothAudioProviderFactoryAidl::TearDown();
1593 }
1594
OpenSession(int32_t sample_rate,int8_t bits_per_sample,ChannelMode channel_mode,int32_t data_interval_us)1595 bool OpenSession(int32_t sample_rate, int8_t bits_per_sample,
1596 ChannelMode channel_mode, int32_t data_interval_us) {
1597 PcmConfiguration pcm_config{
1598 .sampleRateHz = sample_rate,
1599 .channelMode = channel_mode,
1600 .bitsPerSample = bits_per_sample,
1601 .dataIntervalUs = data_interval_us,
1602 };
1603 // Checking against provider capability from getProviderCapabilities
1604 // For HFP software, it's
1605 // BluetoothAudioCodecs::GetSoftwarePcmCapabilities();
1606 DataMQDesc mq_desc;
1607 auto aidl_retval = audio_provider_->startSession(
1608 audio_port_, AudioConfiguration(pcm_config), latency_modes, &mq_desc);
1609 DataMQ data_mq(mq_desc);
1610
1611 if (!aidl_retval.isOk()) return false;
1612 if (!data_mq.isValid()) return false;
1613 return true;
1614 }
1615 };
1616
1617 /**
1618 * Test whether we can open a provider of type
1619 */
TEST_P(BluetoothAudioProviderHfpSoftwareEncodingAidl,OpenHfpSoftwareEncodingProvider)1620 TEST_P(BluetoothAudioProviderHfpSoftwareEncodingAidl,
1621 OpenHfpSoftwareEncodingProvider) {}
1622
1623 /**
1624 * Test whether each provider of type
1625 * SessionType::HFP_SOFTWARE_ENCODING_DATAPATH can be started and stopped with
1626 * different PCM config
1627 */
TEST_P(BluetoothAudioProviderHfpSoftwareEncodingAidl,StartAndEndHfpEncodingSoftwareSessionWithPossiblePcmConfig)1628 TEST_P(BluetoothAudioProviderHfpSoftwareEncodingAidl,
1629 StartAndEndHfpEncodingSoftwareSessionWithPossiblePcmConfig) {
1630 for (auto sample_rate : hfp_sample_rates_) {
1631 for (auto bits_per_sample : hfp_bits_per_samples_) {
1632 for (auto channel_mode : hfp_channel_modes_) {
1633 for (auto data_interval_us : hfp_data_interval_us_) {
1634 EXPECT_TRUE(OpenSession(sample_rate, bits_per_sample, channel_mode,
1635 data_interval_us));
1636 EXPECT_TRUE(audio_provider_->endSession().isOk());
1637 }
1638 }
1639 }
1640 }
1641 }
1642
1643 /**
1644 * openProvider HFP_SOFTWARE_DECODING_DATAPATH
1645 */
1646 class BluetoothAudioProviderHfpSoftwareDecodingAidl
1647 : public BluetoothAudioProviderFactoryAidl {
1648 public:
SetUp()1649 virtual void SetUp() override {
1650 BluetoothAudioProviderFactoryAidl::SetUp();
1651 if (GetProviderFactoryInterfaceVersion() <
1652 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
1653 GTEST_SKIP();
1654 }
1655 GetProviderCapabilitiesHelper(SessionType::HFP_SOFTWARE_DECODING_DATAPATH);
1656 OpenProviderHelper(SessionType::HFP_SOFTWARE_DECODING_DATAPATH);
1657 ASSERT_NE(audio_provider_, nullptr);
1658 }
1659
TearDown()1660 virtual void TearDown() override {
1661 audio_port_ = nullptr;
1662 audio_provider_ = nullptr;
1663 BluetoothAudioProviderFactoryAidl::TearDown();
1664 }
1665
OpenSession(int32_t sample_rate,int8_t bits_per_sample,ChannelMode channel_mode,int32_t data_interval_us)1666 bool OpenSession(int32_t sample_rate, int8_t bits_per_sample,
1667 ChannelMode channel_mode, int32_t data_interval_us) {
1668 PcmConfiguration pcm_config{
1669 .sampleRateHz = sample_rate,
1670 .channelMode = channel_mode,
1671 .bitsPerSample = bits_per_sample,
1672 .dataIntervalUs = data_interval_us,
1673 };
1674 DataMQDesc mq_desc;
1675 auto aidl_retval = audio_provider_->startSession(
1676 audio_port_, AudioConfiguration(pcm_config), latency_modes, &mq_desc);
1677 DataMQ data_mq(mq_desc);
1678
1679 if (!aidl_retval.isOk()) return false;
1680 if (!data_mq.isValid()) return false;
1681 return true;
1682 }
1683 };
1684
1685 /**
1686 * Test whether we can open a provider of type
1687 */
TEST_P(BluetoothAudioProviderHfpSoftwareDecodingAidl,OpenHfpSoftwareDecodingProvider)1688 TEST_P(BluetoothAudioProviderHfpSoftwareDecodingAidl,
1689 OpenHfpSoftwareDecodingProvider) {}
1690
1691 /**
1692 * Test whether each provider of type
1693 * SessionType::HFP_SOFTWARE_DECODING_DATAPATH can be started and stopped with
1694 * different PCM config
1695 */
TEST_P(BluetoothAudioProviderHfpSoftwareDecodingAidl,StartAndEndHfpDecodingSoftwareSessionWithPossiblePcmConfig)1696 TEST_P(BluetoothAudioProviderHfpSoftwareDecodingAidl,
1697 StartAndEndHfpDecodingSoftwareSessionWithPossiblePcmConfig) {
1698 for (auto sample_rate : hfp_sample_rates_) {
1699 for (auto bits_per_sample : hfp_bits_per_samples_) {
1700 for (auto channel_mode : hfp_channel_modes_) {
1701 for (auto data_interval_us : hfp_data_interval_us_) {
1702 EXPECT_TRUE(OpenSession(sample_rate, bits_per_sample, channel_mode,
1703 data_interval_us));
1704 EXPECT_TRUE(audio_provider_->endSession().isOk());
1705 }
1706 }
1707 }
1708 }
1709 }
1710
1711 /**
1712 * openProvider A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH
1713 */
1714 class BluetoothAudioProviderA2dpEncodingHardwareAidl
1715 : public BluetoothAudioProviderFactoryAidl {
1716 public:
SetUp()1717 virtual void SetUp() override {
1718 BluetoothAudioProviderFactoryAidl::SetUp();
1719 GetProviderCapabilitiesHelper(
1720 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
1721 OpenProviderHelper(SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
1722 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
1723 audio_provider_ != nullptr);
1724 }
1725
TearDown()1726 virtual void TearDown() override {
1727 audio_port_ = nullptr;
1728 audio_provider_ = nullptr;
1729 BluetoothAudioProviderFactoryAidl::TearDown();
1730 }
1731
IsOffloadSupported()1732 bool IsOffloadSupported() { return (temp_provider_capabilities_.size() > 0); }
1733 };
1734
1735 /**
1736 * Test whether we can open a provider of type
1737 */
TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,OpenA2dpEncodingHardwareProvider)1738 TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1739 OpenA2dpEncodingHardwareProvider) {}
1740
1741 /**
1742 * Test whether each provider of type
1743 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped
1744 * with SBC hardware encoding config
1745 */
TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,StartAndEndA2dpSbcEncodingHardwareSession)1746 TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1747 StartAndEndA2dpSbcEncodingHardwareSession) {
1748 if (!IsOffloadSupported()) {
1749 GTEST_SKIP();
1750 }
1751
1752 CodecConfiguration codec_config = {
1753 .codecType = CodecType::SBC,
1754 .encodedAudioBitrate = 328000,
1755 .peerMtu = 1005,
1756 .isScmstEnabled = false,
1757 };
1758 auto sbc_codec_specifics = GetSbcCodecSpecificSupportedList(true);
1759
1760 for (auto& codec_specific : sbc_codec_specifics) {
1761 copy_codec_specific(codec_config.config, codec_specific);
1762 DataMQDesc mq_desc;
1763 auto aidl_retval = audio_provider_->startSession(
1764 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
1765
1766 ASSERT_TRUE(aidl_retval.isOk());
1767 EXPECT_TRUE(audio_provider_->endSession().isOk());
1768 }
1769 }
1770
1771 /**
1772 * Test whether each provider of type
1773 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped
1774 * with AAC hardware encoding config
1775 */
TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,StartAndEndA2dpAacEncodingHardwareSession)1776 TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1777 StartAndEndA2dpAacEncodingHardwareSession) {
1778 if (!IsOffloadSupported()) {
1779 GTEST_SKIP();
1780 }
1781
1782 CodecConfiguration codec_config = {
1783 .codecType = CodecType::AAC,
1784 .encodedAudioBitrate = 320000,
1785 .peerMtu = 1005,
1786 .isScmstEnabled = false,
1787 };
1788 auto aac_codec_specifics = GetAacCodecSpecificSupportedList(true);
1789
1790 for (auto& codec_specific : aac_codec_specifics) {
1791 copy_codec_specific(codec_config.config, codec_specific);
1792 DataMQDesc mq_desc;
1793 auto aidl_retval = audio_provider_->startSession(
1794 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
1795
1796 ASSERT_TRUE(aidl_retval.isOk());
1797 EXPECT_TRUE(audio_provider_->endSession().isOk());
1798 }
1799 }
1800
1801 /**
1802 * Test whether each provider of type
1803 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped
1804 * with LDAC hardware encoding config
1805 */
TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,StartAndEndA2dpLdacEncodingHardwareSession)1806 TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1807 StartAndEndA2dpLdacEncodingHardwareSession) {
1808 if (!IsOffloadSupported()) {
1809 GTEST_SKIP();
1810 }
1811
1812 CodecConfiguration codec_config = {
1813 .codecType = CodecType::LDAC,
1814 .encodedAudioBitrate = 990000,
1815 .peerMtu = 1005,
1816 .isScmstEnabled = false,
1817 };
1818 auto ldac_codec_specifics = GetLdacCodecSpecificSupportedList(true);
1819
1820 for (auto& codec_specific : ldac_codec_specifics) {
1821 copy_codec_specific(codec_config.config, codec_specific);
1822 DataMQDesc mq_desc;
1823 auto aidl_retval = audio_provider_->startSession(
1824 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
1825
1826 ASSERT_TRUE(aidl_retval.isOk());
1827 EXPECT_TRUE(audio_provider_->endSession().isOk());
1828 }
1829 }
1830
1831 /**
1832 * Test whether each provider of type
1833 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped
1834 * with Opus hardware encoding config
1835 */
TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,StartAndEndA2dpOpusEncodingHardwareSession)1836 TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1837 StartAndEndA2dpOpusEncodingHardwareSession) {
1838 if (!IsOffloadSupported()) {
1839 GTEST_SKIP();
1840 }
1841
1842 CodecConfiguration codec_config = {
1843 .codecType = CodecType::OPUS,
1844 .encodedAudioBitrate = 990000,
1845 .peerMtu = 1005,
1846 .isScmstEnabled = false,
1847 };
1848 auto opus_codec_specifics = GetOpusCodecSpecificSupportedList(true);
1849
1850 for (auto& codec_specific : opus_codec_specifics) {
1851 copy_codec_specific(codec_config.config, codec_specific);
1852 DataMQDesc mq_desc;
1853 auto aidl_retval = audio_provider_->startSession(
1854 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
1855
1856 ASSERT_TRUE(aidl_retval.isOk());
1857 EXPECT_TRUE(audio_provider_->endSession().isOk());
1858 }
1859 }
1860
1861 /**
1862 * Test whether each provider of type
1863 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped
1864 * with AptX hardware encoding config
1865 */
TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,StartAndEndA2dpAptxEncodingHardwareSession)1866 TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1867 StartAndEndA2dpAptxEncodingHardwareSession) {
1868 if (!IsOffloadSupported()) {
1869 GTEST_SKIP();
1870 }
1871
1872 for (auto codec_type : {CodecType::APTX, CodecType::APTX_HD}) {
1873 CodecConfiguration codec_config = {
1874 .codecType = codec_type,
1875 .encodedAudioBitrate =
1876 (codec_type == CodecType::APTX ? 352000 : 576000),
1877 .peerMtu = 1005,
1878 .isScmstEnabled = false,
1879 };
1880
1881 auto aptx_codec_specifics = GetAptxCodecSpecificSupportedList(
1882 (codec_type == CodecType::APTX_HD ? true : false), true);
1883
1884 for (auto& codec_specific : aptx_codec_specifics) {
1885 copy_codec_specific(codec_config.config, codec_specific);
1886 DataMQDesc mq_desc;
1887 auto aidl_retval = audio_provider_->startSession(
1888 audio_port_, AudioConfiguration(codec_config), latency_modes,
1889 &mq_desc);
1890
1891 ASSERT_TRUE(aidl_retval.isOk());
1892 EXPECT_TRUE(audio_provider_->endSession().isOk());
1893 }
1894 }
1895 }
1896
1897 /**
1898 * Test whether each provider of type
1899 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped
1900 * with an invalid codec config
1901 */
TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,StartAndEndA2dpEncodingHardwareSessionInvalidCodecConfig)1902 TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1903 StartAndEndA2dpEncodingHardwareSessionInvalidCodecConfig) {
1904 if (!IsOffloadSupported()) {
1905 GTEST_SKIP();
1906 }
1907 ASSERT_NE(audio_provider_, nullptr);
1908
1909 std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
1910 for (auto codec_type : ndk::enum_range<CodecType>()) {
1911 switch (codec_type) {
1912 case CodecType::SBC:
1913 codec_specifics = GetSbcCodecSpecificSupportedList(false);
1914 break;
1915 case CodecType::AAC:
1916 codec_specifics = GetAacCodecSpecificSupportedList(false);
1917 break;
1918 case CodecType::LDAC:
1919 codec_specifics = GetLdacCodecSpecificSupportedList(false);
1920 break;
1921 case CodecType::APTX:
1922 codec_specifics = GetAptxCodecSpecificSupportedList(false, false);
1923 break;
1924 case CodecType::APTX_HD:
1925 codec_specifics = GetAptxCodecSpecificSupportedList(true, false);
1926 break;
1927 case CodecType::OPUS:
1928 codec_specifics = GetOpusCodecSpecificSupportedList(false);
1929 continue;
1930 case CodecType::APTX_ADAPTIVE:
1931 case CodecType::APTX_ADAPTIVE_LE:
1932 case CodecType::APTX_ADAPTIVE_LEX:
1933 case CodecType::LC3:
1934 case CodecType::VENDOR:
1935 case CodecType::UNKNOWN:
1936 codec_specifics.clear();
1937 break;
1938 }
1939 if (codec_specifics.empty()) {
1940 continue;
1941 }
1942
1943 CodecConfiguration codec_config = {
1944 .codecType = codec_type,
1945 .encodedAudioBitrate = 328000,
1946 .peerMtu = 1005,
1947 .isScmstEnabled = false,
1948 };
1949 for (auto codec_specific : codec_specifics) {
1950 copy_codec_specific(codec_config.config, codec_specific);
1951 DataMQDesc mq_desc;
1952 auto aidl_retval = audio_provider_->startSession(
1953 audio_port_, AudioConfiguration(codec_config), latency_modes,
1954 &mq_desc);
1955
1956 // AIDL call should fail on invalid codec
1957 ASSERT_FALSE(aidl_retval.isOk());
1958 EXPECT_TRUE(audio_provider_->endSession().isOk());
1959 }
1960 }
1961 }
1962
1963 /**
1964 * openProvider HFP_HARDWARE_OFFLOAD_DATAPATH
1965 */
1966 class BluetoothAudioProviderHfpHardwareAidl
1967 : public BluetoothAudioProviderFactoryAidl {
1968 public:
SetUp()1969 virtual void SetUp() override {
1970 BluetoothAudioProviderFactoryAidl::SetUp();
1971 if (GetProviderFactoryInterfaceVersion() <
1972 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
1973 GTEST_SKIP();
1974 }
1975 GetProviderInfoHelper(SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH);
1976 OpenProviderHelper(SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH);
1977 // Can open or empty capability
1978 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
1979 audio_provider_ != nullptr);
1980 }
1981
TearDown()1982 virtual void TearDown() override {
1983 audio_port_ = nullptr;
1984 audio_provider_ = nullptr;
1985 BluetoothAudioProviderFactoryAidl::TearDown();
1986 }
1987
OpenSession(CodecId codec_id,int connection_handle,bool nrec,bool controller_codec)1988 bool OpenSession(CodecId codec_id, int connection_handle, bool nrec,
1989 bool controller_codec) {
1990 // Check if can open session with a Hfp configuration
1991 HfpConfiguration hfp_configuration{
1992 .codecId = codec_id,
1993 .connectionHandle = connection_handle,
1994 .nrec = nrec,
1995 .controllerCodec = controller_codec,
1996 };
1997 DataMQDesc mq_desc;
1998 auto aidl_retval = audio_provider_->startSession(
1999 audio_port_, AudioConfiguration(hfp_configuration), latency_modes,
2000 &mq_desc);
2001
2002 // Only check if aidl is ok to start session.
2003 return aidl_retval.isOk();
2004 }
2005 };
2006
2007 /**
2008 * Test whether we can open a provider of type
2009 */
TEST_P(BluetoothAudioProviderHfpHardwareAidl,OpenHfpHardwareProvider)2010 TEST_P(BluetoothAudioProviderHfpHardwareAidl, OpenHfpHardwareProvider) {}
2011
2012 /**
2013 * Test whether each provider of type
2014 * SessionType::HFP_SOFTWARE_DECODING_DATAPATH can be started and stopped with
2015 * different HFP config
2016 */
TEST_P(BluetoothAudioProviderHfpHardwareAidl,StartAndEndHfpHardwareSessionWithPossiblePcmConfig)2017 TEST_P(BluetoothAudioProviderHfpHardwareAidl,
2018 StartAndEndHfpHardwareSessionWithPossiblePcmConfig) {
2019 // Try to open with a sample configuration
2020 EXPECT_TRUE(OpenSession(CodecId::Core::CVSD, 6, false, true));
2021 EXPECT_TRUE(audio_provider_->endSession().isOk());
2022 }
2023
2024 /**
2025 * openProvider HEARING_AID_SOFTWARE_ENCODING_DATAPATH
2026 */
2027 class BluetoothAudioProviderHearingAidSoftwareAidl
2028 : public BluetoothAudioProviderFactoryAidl {
2029 public:
SetUp()2030 virtual void SetUp() override {
2031 BluetoothAudioProviderFactoryAidl::SetUp();
2032 GetProviderCapabilitiesHelper(
2033 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
2034 OpenProviderHelper(SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
2035 ASSERT_NE(audio_provider_, nullptr);
2036 }
2037
TearDown()2038 virtual void TearDown() override {
2039 audio_port_ = nullptr;
2040 audio_provider_ = nullptr;
2041 BluetoothAudioProviderFactoryAidl::TearDown();
2042 }
2043
2044 static constexpr int32_t hearing_aid_sample_rates_[] = {0, 16000, 24000};
2045 static constexpr int8_t hearing_aid_bits_per_samples_[] = {0, 16, 24};
2046 static constexpr ChannelMode hearing_aid_channel_modes_[] = {
2047 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
2048 };
2049
2050 /**
2051 * Test whether we can open a provider of type
2052 */
TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl,OpenHearingAidSoftwareProvider)2053 TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl,
2054 OpenHearingAidSoftwareProvider) {}
2055
2056 /**
2057 * Test whether each provider of type
2058 * SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH can be started and
2059 * stopped with different PCM config
2060 */
TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl,StartAndEndHearingAidSessionWithPossiblePcmConfig)2061 TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl,
2062 StartAndEndHearingAidSessionWithPossiblePcmConfig) {
2063 for (int32_t sample_rate : hearing_aid_sample_rates_) {
2064 for (int8_t bits_per_sample : hearing_aid_bits_per_samples_) {
2065 for (auto channel_mode : hearing_aid_channel_modes_) {
2066 PcmConfiguration pcm_config{
2067 .sampleRateHz = sample_rate,
2068 .channelMode = channel_mode,
2069 .bitsPerSample = bits_per_sample,
2070 };
2071 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
2072 DataMQDesc mq_desc;
2073 auto aidl_retval = audio_provider_->startSession(
2074 audio_port_, AudioConfiguration(pcm_config), latency_modes,
2075 &mq_desc);
2076 DataMQ data_mq(mq_desc);
2077
2078 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
2079 if (is_codec_config_valid) {
2080 EXPECT_TRUE(data_mq.isValid());
2081 }
2082 EXPECT_TRUE(audio_provider_->endSession().isOk());
2083 }
2084 }
2085 }
2086 }
2087
2088 /**
2089 * openProvider LE_AUDIO_SOFTWARE_ENCODING_DATAPATH
2090 */
2091 class BluetoothAudioProviderLeAudioOutputSoftwareAidl
2092 : public BluetoothAudioProviderFactoryAidl {
2093 public:
SetUp()2094 virtual void SetUp() override {
2095 BluetoothAudioProviderFactoryAidl::SetUp();
2096 GetProviderCapabilitiesHelper(
2097 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
2098 OpenProviderHelper(SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
2099 ASSERT_NE(audio_provider_, nullptr);
2100 }
2101
TearDown()2102 virtual void TearDown() override {
2103 audio_port_ = nullptr;
2104 audio_provider_ = nullptr;
2105 BluetoothAudioProviderFactoryAidl::TearDown();
2106 }
2107
2108 static constexpr int32_t le_audio_output_sample_rates_[] = {
2109 0, 8000, 16000, 24000, 32000, 44100, 48000,
2110 };
2111 static constexpr int8_t le_audio_output_bits_per_samples_[] = {0, 16, 24};
2112 static constexpr ChannelMode le_audio_output_channel_modes_[] = {
2113 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
2114 static constexpr int32_t le_audio_output_data_interval_us_[] = {
2115 0 /* Invalid */, 10000 /* Valid 10ms */};
2116 };
2117
2118 /**
2119 * Test whether each provider of type
2120 * SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH can be started and
2121 * stopped
2122 */
TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl,OpenLeAudioOutputSoftwareProvider)2123 TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl,
2124 OpenLeAudioOutputSoftwareProvider) {}
2125
2126 /**
2127 * Test whether each provider of type
2128 * SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH can be started and
2129 * stopped with different PCM config
2130 */
TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl,StartAndEndLeAudioOutputSessionWithPossiblePcmConfig)2131 TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl,
2132 StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
2133 for (auto sample_rate : le_audio_output_sample_rates_) {
2134 for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
2135 for (auto channel_mode : le_audio_output_channel_modes_) {
2136 for (auto data_interval_us : le_audio_output_data_interval_us_) {
2137 PcmConfiguration pcm_config{
2138 .sampleRateHz = sample_rate,
2139 .channelMode = channel_mode,
2140 .bitsPerSample = bits_per_sample,
2141 .dataIntervalUs = data_interval_us,
2142 };
2143 bool is_codec_config_valid =
2144 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
2145 DataMQDesc mq_desc;
2146 auto aidl_retval = audio_provider_->startSession(
2147 audio_port_, AudioConfiguration(pcm_config), latency_modes,
2148 &mq_desc);
2149 DataMQ data_mq(mq_desc);
2150
2151 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
2152 if (is_codec_config_valid) {
2153 EXPECT_TRUE(data_mq.isValid());
2154 }
2155 EXPECT_TRUE(audio_provider_->endSession().isOk());
2156 }
2157 }
2158 }
2159 }
2160 }
2161
2162 /**
2163 * openProvider LE_AUDIO_SOFTWARE_DECODING_DATAPATH
2164 */
2165 class BluetoothAudioProviderLeAudioInputSoftwareAidl
2166 : public BluetoothAudioProviderFactoryAidl {
2167 public:
SetUp()2168 virtual void SetUp() override {
2169 BluetoothAudioProviderFactoryAidl::SetUp();
2170 GetProviderCapabilitiesHelper(
2171 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH);
2172 OpenProviderHelper(SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH);
2173 ASSERT_NE(audio_provider_, nullptr);
2174 }
2175
TearDown()2176 virtual void TearDown() override {
2177 audio_port_ = nullptr;
2178 audio_provider_ = nullptr;
2179 BluetoothAudioProviderFactoryAidl::TearDown();
2180 }
2181
2182 static constexpr int32_t le_audio_input_sample_rates_[] = {
2183 0, 8000, 16000, 24000, 32000, 44100, 48000};
2184 static constexpr int8_t le_audio_input_bits_per_samples_[] = {0, 16, 24};
2185 static constexpr ChannelMode le_audio_input_channel_modes_[] = {
2186 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
2187 static constexpr int32_t le_audio_input_data_interval_us_[] = {
2188 0 /* Invalid */, 10000 /* Valid 10ms */};
2189 };
2190
2191 /**
2192 * Test whether each provider of type
2193 * SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH can be started and
2194 * stopped
2195 */
TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl,OpenLeAudioInputSoftwareProvider)2196 TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl,
2197 OpenLeAudioInputSoftwareProvider) {}
2198
2199 /**
2200 * Test whether each provider of type
2201 * SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH can be started and
2202 * stopped with different PCM config
2203 */
TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl,StartAndEndLeAudioInputSessionWithPossiblePcmConfig)2204 TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl,
2205 StartAndEndLeAudioInputSessionWithPossiblePcmConfig) {
2206 for (auto sample_rate : le_audio_input_sample_rates_) {
2207 for (auto bits_per_sample : le_audio_input_bits_per_samples_) {
2208 for (auto channel_mode : le_audio_input_channel_modes_) {
2209 for (auto data_interval_us : le_audio_input_data_interval_us_) {
2210 PcmConfiguration pcm_config{
2211 .sampleRateHz = sample_rate,
2212 .channelMode = channel_mode,
2213 .bitsPerSample = bits_per_sample,
2214 .dataIntervalUs = data_interval_us,
2215 };
2216 bool is_codec_config_valid =
2217 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
2218 DataMQDesc mq_desc;
2219 auto aidl_retval = audio_provider_->startSession(
2220 audio_port_, AudioConfiguration(pcm_config), latency_modes,
2221 &mq_desc);
2222 DataMQ data_mq(mq_desc);
2223
2224 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
2225 if (is_codec_config_valid) {
2226 EXPECT_TRUE(data_mq.isValid());
2227 }
2228 EXPECT_TRUE(audio_provider_->endSession().isOk());
2229 }
2230 }
2231 }
2232 }
2233 }
2234
2235 /**
2236 * openProvider LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH
2237 */
2238 class BluetoothAudioProviderLeAudioOutputHardwareAidl
2239 : public BluetoothAudioProviderFactoryAidl {
2240 public:
SetUp()2241 virtual void SetUp() override {
2242 BluetoothAudioProviderFactoryAidl::SetUp();
2243 GetProviderCapabilitiesHelper(
2244 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
2245 GetProviderInfoHelper(
2246 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
2247 OpenProviderHelper(
2248 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
2249 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
2250 audio_provider_ != nullptr);
2251 }
2252
TearDown()2253 virtual void TearDown() override {
2254 audio_port_ = nullptr;
2255 audio_provider_ = nullptr;
2256 BluetoothAudioProviderFactoryAidl::TearDown();
2257 }
2258
IsMultidirectionalCapabilitiesEnabled()2259 bool IsMultidirectionalCapabilitiesEnabled() {
2260 if (!temp_provider_info_.has_value()) return false;
2261
2262 return temp_provider_info_.value().supportsMultidirectionalCapabilities;
2263 }
2264
IsAsymmetricConfigurationAllowed()2265 bool IsAsymmetricConfigurationAllowed() {
2266 if (!temp_provider_info_.has_value()) return false;
2267 if (temp_provider_info_.value().codecInfos.empty()) return false;
2268
2269 for (auto& codec_info : temp_provider_info_.value().codecInfos) {
2270 if (codec_info.transport.getTag() != CodecInfo::Transport::leAudio) {
2271 return false;
2272 }
2273
2274 auto flags =
2275 codec_info.transport.get<CodecInfo::Transport::leAudio>().flags;
2276
2277 if (!flags) {
2278 continue;
2279 }
2280
2281 if (flags->bitmask &
2282 ConfigurationFlags::ALLOW_ASYMMETRIC_CONFIGURATIONS) {
2283 return true;
2284 }
2285 }
2286
2287 return false;
2288 }
2289
IsOffloadOutputSupported()2290 bool IsOffloadOutputSupported() {
2291 for (auto& capability : temp_provider_capabilities_) {
2292 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2293 continue;
2294 }
2295 auto& le_audio_capability =
2296 capability.get<AudioCapabilities::leAudioCapabilities>();
2297 if (le_audio_capability.unicastEncodeCapability.codecType !=
2298 CodecType::UNKNOWN)
2299 return true;
2300 }
2301 return false;
2302 }
2303
IsOffloadOutputProviderInfoSupported()2304 bool IsOffloadOutputProviderInfoSupported() {
2305 if (!temp_provider_info_.has_value()) return false;
2306 if (temp_provider_info_.value().codecInfos.empty()) return false;
2307 // Check if all codec info is of LeAudio type
2308 for (auto& codec_info : temp_provider_info_.value().codecInfos) {
2309 if (codec_info.transport.getTag() != CodecInfo::Transport::leAudio)
2310 return false;
2311 }
2312 return true;
2313 }
2314
GetUnicastLc3SupportedListFromProviderInfo()2315 std::vector<Lc3Configuration> GetUnicastLc3SupportedListFromProviderInfo() {
2316 std::vector<Lc3Configuration> le_audio_codec_configs;
2317 for (auto& codec_info : temp_provider_info_.value().codecInfos) {
2318 // Only gets LC3 codec information
2319 if (codec_info.id != CodecId::Core::LC3) continue;
2320 // Combine those parameters into one list of Lc3Configuration
2321 auto& transport =
2322 codec_info.transport.get<CodecInfo::Transport::Tag::leAudio>();
2323 for (int32_t samplingFrequencyHz : transport.samplingFrequencyHz) {
2324 for (int32_t frameDurationUs : transport.frameDurationUs) {
2325 for (int32_t octetsPerFrame : transport.bitdepth) {
2326 Lc3Configuration lc3_config = {
2327 .samplingFrequencyHz = samplingFrequencyHz,
2328 .frameDurationUs = frameDurationUs,
2329 .octetsPerFrame = octetsPerFrame,
2330 };
2331 le_audio_codec_configs.push_back(lc3_config);
2332 }
2333 }
2334 }
2335 }
2336
2337 return le_audio_codec_configs;
2338 }
2339
GetAudioContext(int32_t bitmask)2340 AudioContext GetAudioContext(int32_t bitmask) {
2341 AudioContext media_audio_context;
2342 media_audio_context.bitmask = bitmask;
2343 return media_audio_context;
2344 }
2345
GetDefaultRemoteSinkCapability()2346 LeAudioDeviceCapabilities GetDefaultRemoteSinkCapability() {
2347 // Create a capability
2348 LeAudioDeviceCapabilities capability;
2349
2350 capability.codecId = CodecId::Core::LC3;
2351
2352 auto pref_context_metadata = MetadataLtv::PreferredAudioContexts();
2353 pref_context_metadata.values =
2354 GetAudioContext(AudioContext::MEDIA | AudioContext::CONVERSATIONAL |
2355 AudioContext::GAME);
2356 capability.metadata = {pref_context_metadata};
2357
2358 auto sampling_rate =
2359 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies();
2360 sampling_rate.bitmask =
2361 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ16000 |
2362 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ8000;
2363 auto frame_duration =
2364 CodecSpecificCapabilitiesLtv::SupportedFrameDurations();
2365 frame_duration.bitmask =
2366 CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US7500 |
2367 CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US10000;
2368 auto octets = CodecSpecificCapabilitiesLtv::SupportedOctetsPerCodecFrame();
2369 octets.min = 0;
2370 octets.max = 120;
2371 auto frames = CodecSpecificCapabilitiesLtv::SupportedMaxCodecFramesPerSDU();
2372 frames.value = 2;
2373 capability.codecSpecificCapabilities = {sampling_rate, frame_duration,
2374 octets, frames};
2375 return capability;
2376 }
2377
GetOpusRemoteSinkCapability()2378 LeAudioDeviceCapabilities GetOpusRemoteSinkCapability() {
2379 // Create a capability specifically for vendor OPUS
2380 LeAudioDeviceCapabilities capability;
2381
2382 auto vendor_codec = CodecId::Vendor();
2383 vendor_codec.codecId = 255;
2384 vendor_codec.id = 224;
2385 capability.codecId = vendor_codec;
2386
2387 auto pref_context_metadata = MetadataLtv::PreferredAudioContexts();
2388 pref_context_metadata.values =
2389 GetAudioContext(AudioContext::MEDIA | AudioContext::CONVERSATIONAL |
2390 AudioContext::GAME);
2391 capability.metadata = {pref_context_metadata};
2392
2393 auto sampling_rate =
2394 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies();
2395 sampling_rate.bitmask =
2396 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ16000 |
2397 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ8000 |
2398 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ48000;
2399 auto frame_duration =
2400 CodecSpecificCapabilitiesLtv::SupportedFrameDurations();
2401 frame_duration.bitmask =
2402 CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US7500 |
2403 CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US10000 |
2404 CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US20000;
2405 auto octets = CodecSpecificCapabilitiesLtv::SupportedOctetsPerCodecFrame();
2406 octets.min = 0;
2407 octets.max = 240;
2408 auto frames = CodecSpecificCapabilitiesLtv::SupportedMaxCodecFramesPerSDU();
2409 frames.value = 2;
2410 capability.codecSpecificCapabilities = {sampling_rate, frame_duration,
2411 octets, frames};
2412 return capability;
2413 }
2414
GetDefaultRemoteSourceCapability()2415 LeAudioDeviceCapabilities GetDefaultRemoteSourceCapability() {
2416 // Create a capability
2417 LeAudioDeviceCapabilities capability;
2418
2419 capability.codecId = CodecId::Core::LC3;
2420
2421 auto pref_context_metadata = MetadataLtv::PreferredAudioContexts();
2422 pref_context_metadata.values =
2423 GetAudioContext(AudioContext::LIVE_AUDIO |
2424 AudioContext::CONVERSATIONAL | AudioContext::GAME);
2425 capability.metadata = {pref_context_metadata};
2426
2427 auto sampling_rate =
2428 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies();
2429 sampling_rate.bitmask =
2430 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ16000 |
2431 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ8000;
2432 auto frame_duration =
2433 CodecSpecificCapabilitiesLtv::SupportedFrameDurations();
2434 frame_duration.bitmask =
2435 CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US7500 |
2436 CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US10000;
2437 auto octets = CodecSpecificCapabilitiesLtv::SupportedOctetsPerCodecFrame();
2438 octets.min = 0;
2439 octets.max = 120;
2440 auto frames = CodecSpecificCapabilitiesLtv::SupportedMaxCodecFramesPerSDU();
2441 frames.value = 2;
2442 capability.codecSpecificCapabilities = {sampling_rate, frame_duration,
2443 octets, frames};
2444 return capability;
2445 }
2446
IsAseRequirementSatisfiedWithUnknownChannelCount(const std::vector<std::optional<AseDirectionRequirement>> & ase_requirements,const std::vector<std::optional<AseDirectionConfiguration>> & ase_configurations)2447 bool IsAseRequirementSatisfiedWithUnknownChannelCount(
2448 const std::vector<std::optional<AseDirectionRequirement>>&
2449 ase_requirements,
2450 const std::vector<std::optional<AseDirectionConfiguration>>&
2451 ase_configurations) {
2452 /* This is mandatory to match sample freq, allocation however, when in the
2453 * device group there is only one device which supports left and right
2454 * allocation, and channel count is hidden from the BT stack, the BT stack
2455 * will send single requirement but it can receive two configurations if the
2456 * channel count is 1.
2457 */
2458
2459 int num_of_ase_requirements = 0;
2460 for (const auto& ase_req : ase_requirements) {
2461 auto required_allocation_ltv = GetConfigurationLtv(
2462 ase_req->aseConfiguration.codecConfiguration,
2463 CodecSpecificConfigurationLtv::Tag::audioChannelAllocation);
2464 if (required_allocation_ltv == std::nullopt) {
2465 continue;
2466 }
2467 int required_allocation =
2468 required_allocation_ltv
2469 ->get<
2470 CodecSpecificConfigurationLtv::Tag::audioChannelAllocation>()
2471 .bitmask;
2472 num_of_ase_requirements += std::bitset<32>(required_allocation).count();
2473 }
2474
2475 int num_of_satisfied_ase_requirements = 0;
2476 for (const auto& ase_req : ase_requirements) {
2477 if (!ase_req) {
2478 continue;
2479 }
2480 auto required_sample_freq_ltv = GetConfigurationLtv(
2481 ase_req->aseConfiguration.codecConfiguration,
2482 CodecSpecificConfigurationLtv::Tag::samplingFrequency);
2483 auto required_allocation_ltv = GetConfigurationLtv(
2484 ase_req->aseConfiguration.codecConfiguration,
2485 CodecSpecificConfigurationLtv::Tag::audioChannelAllocation);
2486
2487 /* Allocation and sample freq shall be always in the requirement */
2488 if (!required_sample_freq_ltv || !required_allocation_ltv) {
2489 return false;
2490 }
2491
2492 int required_allocation =
2493 required_allocation_ltv
2494 ->get<
2495 CodecSpecificConfigurationLtv::Tag::audioChannelAllocation>()
2496 .bitmask;
2497
2498 for (const auto& ase_conf : ase_configurations) {
2499 if (!ase_conf) {
2500 continue;
2501 }
2502 auto config_sample_freq_ltv = GetConfigurationLtv(
2503 ase_conf->aseConfiguration.codecConfiguration,
2504 CodecSpecificConfigurationLtv::Tag::samplingFrequency);
2505 auto config_allocation_ltv = GetConfigurationLtv(
2506 ase_conf->aseConfiguration.codecConfiguration,
2507 CodecSpecificConfigurationLtv::Tag::audioChannelAllocation);
2508 if (config_sample_freq_ltv == std::nullopt ||
2509 config_allocation_ltv == std::nullopt) {
2510 return false;
2511 }
2512
2513 int configured_allocation = config_allocation_ltv
2514 ->get<CodecSpecificConfigurationLtv::
2515 Tag::audioChannelAllocation>()
2516 .bitmask;
2517
2518 if (config_sample_freq_ltv == required_sample_freq_ltv &&
2519 (required_allocation & configured_allocation)) {
2520 num_of_satisfied_ase_requirements +=
2521 std::bitset<32>(configured_allocation).count();
2522 }
2523 }
2524 }
2525
2526 return (num_of_satisfied_ase_requirements == num_of_ase_requirements);
2527 }
2528
IsAseRequirementSatisfied(const std::vector<std::optional<AseDirectionRequirement>> & ase_requirements,const std::vector<std::optional<AseDirectionConfiguration>> & ase_configurations)2529 bool IsAseRequirementSatisfied(
2530 const std::vector<std::optional<AseDirectionRequirement>>&
2531 ase_requirements,
2532 const std::vector<std::optional<AseDirectionConfiguration>>&
2533 ase_configurations) {
2534 // This is mandatory to match sample freq, allocation
2535 int num_of_satisfied_ase_requirements = 0;
2536
2537 int required_allocations = 0;
2538 for (const auto& ase_req : ase_requirements) {
2539 auto required_allocation_ltv = GetConfigurationLtv(
2540 ase_req->aseConfiguration.codecConfiguration,
2541 CodecSpecificConfigurationLtv::Tag::audioChannelAllocation);
2542 if (required_allocation_ltv == std::nullopt) {
2543 continue;
2544 }
2545
2546 int allocations =
2547 required_allocation_ltv
2548 ->get<
2549 CodecSpecificConfigurationLtv::Tag::audioChannelAllocation>()
2550 .bitmask;
2551 required_allocations += std::bitset<32>(allocations).count();
2552 }
2553
2554 if (ase_requirements.size() != required_allocations) {
2555 /* If more than one allication is requested in the requirement, then use
2556 * different verifier */
2557 return IsAseRequirementSatisfiedWithUnknownChannelCount(
2558 ase_requirements, ase_configurations);
2559 }
2560
2561 for (const auto& ase_req : ase_requirements) {
2562 if (!ase_req) {
2563 continue;
2564 }
2565 auto required_sample_freq_ltv = GetConfigurationLtv(
2566 ase_req->aseConfiguration.codecConfiguration,
2567 CodecSpecificConfigurationLtv::Tag::samplingFrequency);
2568 auto required_allocation_ltv = GetConfigurationLtv(
2569 ase_req->aseConfiguration.codecConfiguration,
2570 CodecSpecificConfigurationLtv::Tag::audioChannelAllocation);
2571
2572 /* Allocation and sample freq shall be always in the requirement */
2573 if (!required_sample_freq_ltv || !required_allocation_ltv) {
2574 return false;
2575 }
2576
2577 for (const auto& ase_conf : ase_configurations) {
2578 if (!ase_conf) {
2579 continue;
2580 }
2581 auto config_sample_freq_ltv = GetConfigurationLtv(
2582 ase_conf->aseConfiguration.codecConfiguration,
2583 CodecSpecificConfigurationLtv::Tag::samplingFrequency);
2584 auto config_allocation_ltv = GetConfigurationLtv(
2585 ase_conf->aseConfiguration.codecConfiguration,
2586 CodecSpecificConfigurationLtv::Tag::audioChannelAllocation);
2587 if (config_sample_freq_ltv == std::nullopt ||
2588 config_allocation_ltv == std::nullopt) {
2589 return false;
2590 }
2591
2592 if (config_sample_freq_ltv == required_sample_freq_ltv &&
2593 config_allocation_ltv == required_allocation_ltv) {
2594 num_of_satisfied_ase_requirements++;
2595 break;
2596 }
2597 }
2598 }
2599
2600 return (num_of_satisfied_ase_requirements == ase_requirements.size());
2601 }
2602
VerifyCodecParameters(::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::LeAudioAseConfigurationSetting::AseDirectionConfiguration config)2603 static void VerifyCodecParameters(
2604 ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
2605 LeAudioAseConfigurationSetting::AseDirectionConfiguration config) {
2606 ASSERT_NE(config.aseConfiguration.codecConfiguration.size(), 0lu);
2607 ASSERT_TRUE(config.qosConfiguration.has_value());
2608
2609 int32_t frame_blocks = 1; // by default 1 if not set
2610 int8_t frame_duration = 0;
2611 int32_t octets_per_frame = 0;
2612 std::bitset<32> allocation_bitmask = 0;
2613
2614 for (auto const& param : config.aseConfiguration.codecConfiguration) {
2615 if (param.getTag() ==
2616 ::aidl::android::hardware::bluetooth::audio::
2617 CodecSpecificConfigurationLtv::Tag::codecFrameBlocksPerSDU) {
2618 frame_blocks = param
2619 .get<::aidl::android::hardware::bluetooth::audio::
2620 CodecSpecificConfigurationLtv::Tag::
2621 codecFrameBlocksPerSDU>()
2622 .value;
2623 } else if (param.getTag() ==
2624 ::aidl::android::hardware::bluetooth::audio::
2625 CodecSpecificConfigurationLtv::Tag::frameDuration) {
2626 frame_duration = static_cast<int8_t>(
2627 param.get<::aidl::android::hardware::bluetooth::audio::
2628 CodecSpecificConfigurationLtv::Tag::frameDuration>());
2629 } else if (param.getTag() ==
2630 ::aidl::android::hardware::bluetooth::audio::
2631 CodecSpecificConfigurationLtv::Tag::octetsPerCodecFrame) {
2632 octets_per_frame = static_cast<int32_t>(
2633 param
2634 .get<::aidl::android::hardware::bluetooth::audio::
2635 CodecSpecificConfigurationLtv::Tag::
2636 octetsPerCodecFrame>()
2637 .value);
2638 } else if (param.getTag() == ::aidl::android::hardware::bluetooth::audio::
2639 CodecSpecificConfigurationLtv::Tag::
2640 audioChannelAllocation) {
2641 allocation_bitmask = static_cast<int32_t>(
2642 param
2643 .get<::aidl::android::hardware::bluetooth::audio::
2644 CodecSpecificConfigurationLtv::Tag::
2645 audioChannelAllocation>()
2646 .bitmask);
2647 }
2648 }
2649
2650 ASSERT_NE(frame_blocks, 0);
2651 ASSERT_NE(frame_duration, 0);
2652 ASSERT_NE(octets_per_frame, 0);
2653
2654 auto const num_channels_per_cis = allocation_bitmask.count();
2655 ASSERT_NE(num_channels_per_cis, 0);
2656
2657 // Verify if QoS takes the codec frame blocks per SDU into the account
2658 ASSERT_TRUE(config.qosConfiguration->sduIntervalUs >=
2659 frame_blocks * frame_duration);
2660 ASSERT_TRUE(config.qosConfiguration->maxSdu >=
2661 (frame_blocks * num_channels_per_cis * octets_per_frame));
2662 }
2663
VerifyIfRequirementsSatisfied(const std::vector<LeAudioConfigurationRequirement> & requirements,const std::vector<LeAudioAseConfigurationSetting> & configurations)2664 void VerifyIfRequirementsSatisfied(
2665 const std::vector<LeAudioConfigurationRequirement>& requirements,
2666 const std::vector<LeAudioAseConfigurationSetting>& configurations) {
2667 if (requirements.empty() && configurations.empty()) {
2668 return;
2669 }
2670
2671 /* It might happen that vendor lib will provide same configuration for
2672 * multiple contexts and it should be accepted
2673 */
2674
2675 int num_of_requirements = 0;
2676 for (const auto& req : requirements) {
2677 num_of_requirements += std::bitset<32>(req.audioContext.bitmask).count();
2678 }
2679
2680 int num_of_configurations = 0;
2681 for (const auto& conf : configurations) {
2682 num_of_configurations +=
2683 std::bitset<32>(conf.audioContext.bitmask).count();
2684 }
2685
2686 ASSERT_EQ(num_of_requirements, num_of_configurations);
2687
2688 int num_of_satisfied_requirements = 0;
2689 for (const auto& req : requirements) {
2690 for (const auto& conf : configurations) {
2691 if ((req.audioContext.bitmask & conf.audioContext.bitmask) !=
2692 req.audioContext.bitmask) {
2693 continue;
2694 }
2695
2696 bool sink_req_satisfied = false;
2697 if (req.sinkAseRequirement) {
2698 ASSERT_TRUE(conf.sinkAseConfiguration.has_value());
2699 sink_req_satisfied = IsAseRequirementSatisfied(
2700 *req.sinkAseRequirement, *conf.sinkAseConfiguration);
2701
2702 ASSERT_NE(conf.sinkAseConfiguration->size(), 0lu);
2703 for (auto const& cfg : conf.sinkAseConfiguration.value()) {
2704 ASSERT_TRUE(cfg.has_value());
2705 VerifyCodecParameters(cfg.value());
2706 }
2707 }
2708
2709 bool source_req_satisfied = false;
2710 if (req.sourceAseRequirement) {
2711 ASSERT_TRUE(conf.sourceAseConfiguration.has_value());
2712 source_req_satisfied = IsAseRequirementSatisfied(
2713 *req.sourceAseRequirement, *conf.sourceAseConfiguration);
2714
2715 ASSERT_NE(conf.sourceAseConfiguration->size(), 0lu);
2716 for (auto const& cfg : conf.sourceAseConfiguration.value()) {
2717 ASSERT_TRUE(cfg.has_value());
2718 VerifyCodecParameters(cfg.value());
2719 }
2720 }
2721
2722 if (req.sinkAseRequirement && req.sourceAseRequirement) {
2723 if (!conf.sinkAseConfiguration || !conf.sourceAseConfiguration) {
2724 continue;
2725 }
2726
2727 if (!sink_req_satisfied || !source_req_satisfied) {
2728 continue;
2729 }
2730 num_of_satisfied_requirements +=
2731 std::bitset<32>(req.audioContext.bitmask).count();
2732 break;
2733 } else if (req.sinkAseRequirement) {
2734 if (!sink_req_satisfied) {
2735 continue;
2736 }
2737 num_of_satisfied_requirements +=
2738 std::bitset<32>(req.audioContext.bitmask).count();
2739 break;
2740 } else if (req.sourceAseRequirement) {
2741 if (!source_req_satisfied) {
2742 continue;
2743 }
2744 num_of_satisfied_requirements +=
2745 std::bitset<32>(req.audioContext.bitmask).count();
2746 break;
2747 }
2748 }
2749 }
2750 ASSERT_EQ(num_of_satisfied_requirements, num_of_requirements);
2751 }
2752
GetUnicastDefaultRequirement(int32_t context_bits,bool is_sink_requirement,bool is_source_requriement,CodecSpecificConfigurationLtv::SamplingFrequency freq=CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000)2753 LeAudioConfigurationRequirement GetUnicastDefaultRequirement(
2754 int32_t context_bits, bool is_sink_requirement,
2755 bool is_source_requriement,
2756 CodecSpecificConfigurationLtv::SamplingFrequency freq =
2757 CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000) {
2758 // Create a requirements
2759 LeAudioConfigurationRequirement requirement;
2760 requirement.audioContext = GetAudioContext(context_bits);
2761
2762 auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
2763 allocation.bitmask =
2764 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
2765 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
2766
2767 auto direction_ase_requriement = AseDirectionRequirement();
2768 direction_ase_requriement.aseConfiguration.codecId = CodecId::Core::LC3;
2769 direction_ase_requriement.aseConfiguration.targetLatency =
2770 LeAudioAseConfiguration::TargetLatency::BALANCED_LATENCY_RELIABILITY;
2771
2772 direction_ase_requriement.aseConfiguration.codecConfiguration = {
2773 freq, CodecSpecificConfigurationLtv::FrameDuration::US10000, allocation
2774
2775 };
2776 if (is_sink_requirement)
2777 requirement.sinkAseRequirement = {direction_ase_requriement};
2778
2779 if (is_source_requriement)
2780 requirement.sourceAseRequirement = {direction_ase_requriement};
2781
2782 return requirement;
2783 }
2784
GetOpusUnicastRequirement(int32_t context_bits,bool is_sink_requirement,bool is_source_requriement,CodecSpecificConfigurationLtv::SamplingFrequency freq=CodecSpecificConfigurationLtv::SamplingFrequency::HZ48000)2785 LeAudioConfigurationRequirement GetOpusUnicastRequirement(
2786 int32_t context_bits, bool is_sink_requirement,
2787 bool is_source_requriement,
2788 CodecSpecificConfigurationLtv::SamplingFrequency freq =
2789 CodecSpecificConfigurationLtv::SamplingFrequency::HZ48000) {
2790 // Create a requirements
2791 LeAudioConfigurationRequirement requirement;
2792 requirement.audioContext = GetAudioContext(context_bits);
2793
2794 auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
2795 allocation.bitmask =
2796 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
2797 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
2798
2799 auto direction_ase_requriement = AseDirectionRequirement();
2800 auto vendor_codec = CodecId::Vendor();
2801 vendor_codec.codecId = 255;
2802 vendor_codec.id = 224;
2803 direction_ase_requriement.aseConfiguration.codecId = vendor_codec;
2804 direction_ase_requriement.aseConfiguration.targetLatency =
2805 LeAudioAseConfiguration::TargetLatency::HIGHER_RELIABILITY;
2806
2807 direction_ase_requriement.aseConfiguration.codecConfiguration = {
2808 freq, CodecSpecificConfigurationLtv::FrameDuration::US20000, allocation
2809
2810 };
2811 if (is_sink_requirement)
2812 requirement.sinkAseRequirement = {direction_ase_requriement};
2813
2814 if (is_source_requriement)
2815 requirement.sourceAseRequirement = {direction_ase_requriement};
2816
2817 return requirement;
2818 }
2819
GetUnicastGameRequirement(bool asymmetric)2820 LeAudioConfigurationRequirement GetUnicastGameRequirement(bool asymmetric) {
2821 // Create a requirements
2822 LeAudioConfigurationRequirement requirement;
2823 requirement.audioContext = GetAudioContext(AudioContext::GAME);
2824
2825 auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
2826 allocation.bitmask =
2827 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
2828 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
2829
2830 auto sink_ase_requriement = AseDirectionRequirement();
2831 sink_ase_requriement.aseConfiguration.codecId = CodecId::Core::LC3;
2832 sink_ase_requriement.aseConfiguration.targetLatency =
2833 LeAudioAseConfiguration::TargetLatency::BALANCED_LATENCY_RELIABILITY;
2834
2835 sink_ase_requriement.aseConfiguration.codecConfiguration = {
2836 CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000,
2837 CodecSpecificConfigurationLtv::FrameDuration::US10000, allocation};
2838
2839 auto source_ase_requriement = AseDirectionRequirement();
2840 source_ase_requriement.aseConfiguration.codecId = CodecId::Core::LC3;
2841 source_ase_requriement.aseConfiguration.targetLatency =
2842 LeAudioAseConfiguration::TargetLatency::BALANCED_LATENCY_RELIABILITY;
2843
2844 if (asymmetric) {
2845 source_ase_requriement.aseConfiguration.codecConfiguration = {
2846 CodecSpecificConfigurationLtv::SamplingFrequency::HZ8000,
2847 CodecSpecificConfigurationLtv::FrameDuration::US10000, allocation};
2848 } else {
2849 source_ase_requriement.aseConfiguration.codecConfiguration = {
2850 CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000,
2851 CodecSpecificConfigurationLtv::FrameDuration::US10000, allocation};
2852 }
2853
2854 requirement.sinkAseRequirement = {sink_ase_requriement};
2855 requirement.sourceAseRequirement = {source_ase_requriement};
2856
2857 return requirement;
2858 }
2859
GetQosRequirements(bool is_sink_requirement,bool is_source_requriement,bool valid=true)2860 LeAudioAseQosConfigurationRequirement GetQosRequirements(
2861 bool is_sink_requirement, bool is_source_requriement, bool valid = true) {
2862 LeAudioAseQosConfigurationRequirement qosRequirement;
2863
2864 auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
2865 allocation.bitmask =
2866 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
2867 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
2868
2869 AseQosDirectionRequirement directionalRequirement = {
2870 .framing = IBluetoothAudioProvider::Framing::UNFRAMED,
2871 .preferredRetransmissionNum = 2,
2872 .maxTransportLatencyMs = 10,
2873 .presentationDelayMinUs = 40000,
2874 .presentationDelayMaxUs = 40000,
2875 .aseConfiguration =
2876 {
2877 .targetLatency = LeAudioAseConfiguration::TargetLatency::
2878 BALANCED_LATENCY_RELIABILITY,
2879 .codecId = CodecId::Core::LC3,
2880 .codecConfiguration =
2881 {CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000,
2882 CodecSpecificConfigurationLtv::FrameDuration::US10000,
2883 allocation},
2884 },
2885 };
2886
2887 if (!valid) {
2888 // clear some required values;
2889 directionalRequirement.maxTransportLatencyMs = 0;
2890 directionalRequirement.presentationDelayMaxUs = 0;
2891 }
2892
2893 qosRequirement.sinkAseQosRequirement = directionalRequirement;
2894 if (is_source_requriement && is_sink_requirement) {
2895 qosRequirement.sourceAseQosRequirement = directionalRequirement;
2896 qosRequirement.sinkAseQosRequirement = directionalRequirement;
2897 } else if (is_source_requriement) {
2898 qosRequirement.sourceAseQosRequirement = directionalRequirement;
2899 qosRequirement.sinkAseQosRequirement = std::nullopt;
2900 } else if (is_sink_requirement) {
2901 qosRequirement.sourceAseQosRequirement = std::nullopt;
2902 qosRequirement.sinkAseQosRequirement = directionalRequirement;
2903 }
2904
2905 return qosRequirement;
2906 }
2907
GetUnicastLc3SupportedList(bool decoding,bool supported)2908 std::vector<Lc3Configuration> GetUnicastLc3SupportedList(bool decoding,
2909 bool supported) {
2910 std::vector<Lc3Configuration> le_audio_codec_configs;
2911 if (!supported) {
2912 Lc3Configuration lc3_config{.pcmBitDepth = 0, .samplingFrequencyHz = 0};
2913 le_audio_codec_configs.push_back(lc3_config);
2914 return le_audio_codec_configs;
2915 }
2916
2917 // There might be more than one LeAudioCodecCapabilitiesSetting
2918 std::vector<Lc3Capabilities> lc3_capabilities;
2919 for (auto& capability : temp_provider_capabilities_) {
2920 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2921 continue;
2922 }
2923 auto& le_audio_capability =
2924 capability.get<AudioCapabilities::leAudioCapabilities>();
2925 auto& unicast_capability =
2926 decoding ? le_audio_capability.unicastDecodeCapability
2927 : le_audio_capability.unicastEncodeCapability;
2928 if (unicast_capability.codecType != CodecType::LC3) {
2929 continue;
2930 }
2931 auto& lc3_capability = unicast_capability.leAudioCodecCapabilities.get<
2932 UnicastCapability::LeAudioCodecCapabilities::lc3Capabilities>();
2933 lc3_capabilities.push_back(lc3_capability);
2934 }
2935
2936 // Combine those parameters into one list of LeAudioCodecConfiguration
2937 // This seems horrible, but usually each Lc3Capability only contains a
2938 // single Lc3Configuration, which means every array has a length of 1.
2939 for (auto& lc3_capability : lc3_capabilities) {
2940 for (int32_t samplingFrequencyHz : lc3_capability.samplingFrequencyHz) {
2941 for (int32_t frameDurationUs : lc3_capability.frameDurationUs) {
2942 for (int32_t octetsPerFrame : lc3_capability.octetsPerFrame) {
2943 Lc3Configuration lc3_config = {
2944 .samplingFrequencyHz = samplingFrequencyHz,
2945 .frameDurationUs = frameDurationUs,
2946 .octetsPerFrame = octetsPerFrame,
2947 };
2948 le_audio_codec_configs.push_back(lc3_config);
2949 }
2950 }
2951 }
2952 }
2953
2954 return le_audio_codec_configs;
2955 }
2956
2957 static constexpr int32_t apx_adaptive_le_config_codec_modes[] = {0, 1, 2, 3};
2958
2959 std::vector<AptxAdaptiveLeConfiguration>
GetUnicastAptxAdaptiveLeSupportedList(bool decoding,bool supported,bool is_le_extended)2960 GetUnicastAptxAdaptiveLeSupportedList(bool decoding, bool supported,
2961 bool is_le_extended) {
2962 std::vector<AptxAdaptiveLeConfiguration> le_audio_codec_configs;
2963 if (!supported) {
2964 AptxAdaptiveLeConfiguration aptx_adaptive_le_config{
2965 .pcmBitDepth = 0, .samplingFrequencyHz = 0};
2966 le_audio_codec_configs.push_back(aptx_adaptive_le_config);
2967 return le_audio_codec_configs;
2968 }
2969
2970 // There might be more than one LeAudioCodecCapabilitiesSetting
2971 std::vector<AptxAdaptiveLeCapabilities> aptx_adaptive_le_capabilities;
2972 for (auto& capability : temp_provider_capabilities_) {
2973 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2974 continue;
2975 }
2976 auto& le_audio_capability =
2977 capability.get<AudioCapabilities::leAudioCapabilities>();
2978 auto& unicast_capability =
2979 decoding ? le_audio_capability.unicastDecodeCapability
2980 : le_audio_capability.unicastEncodeCapability;
2981 if ((!is_le_extended &&
2982 unicast_capability.codecType != CodecType::APTX_ADAPTIVE_LE) ||
2983 (is_le_extended &&
2984 unicast_capability.codecType != CodecType::APTX_ADAPTIVE_LEX)) {
2985 continue;
2986 }
2987
2988 auto& aptx_adaptive_le_capability =
2989 unicast_capability.leAudioCodecCapabilities
2990 .get<UnicastCapability::LeAudioCodecCapabilities::
2991 aptxAdaptiveLeCapabilities>();
2992
2993 aptx_adaptive_le_capabilities.push_back(aptx_adaptive_le_capability);
2994 }
2995
2996 for (auto& aptx_adaptive_le_capability : aptx_adaptive_le_capabilities) {
2997 for (int32_t samplingFrequencyHz :
2998 aptx_adaptive_le_capability.samplingFrequencyHz) {
2999 for (int32_t frameDurationUs :
3000 aptx_adaptive_le_capability.frameDurationUs) {
3001 for (int32_t octetsPerFrame :
3002 aptx_adaptive_le_capability.octetsPerFrame) {
3003 for (int8_t blocksPerSdu :
3004 aptx_adaptive_le_capability.blocksPerSdu) {
3005 for (int32_t codecMode : apx_adaptive_le_config_codec_modes) {
3006 AptxAdaptiveLeConfiguration aptx_adaptive_le_config = {
3007 .samplingFrequencyHz = samplingFrequencyHz,
3008 .frameDurationUs = frameDurationUs,
3009 .octetsPerFrame = octetsPerFrame,
3010 .blocksPerSdu = blocksPerSdu,
3011 .codecMode = codecMode,
3012 };
3013 le_audio_codec_configs.push_back(aptx_adaptive_le_config);
3014 }
3015 }
3016 }
3017 }
3018 }
3019 }
3020
3021 return le_audio_codec_configs;
3022 }
3023
3024 LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
3025 std::vector<int32_t> all_context_bitmasks = {
3026 AudioContext::UNSPECIFIED, AudioContext::CONVERSATIONAL,
3027 AudioContext::MEDIA, AudioContext::GAME,
3028 AudioContext::INSTRUCTIONAL, AudioContext::VOICE_ASSISTANTS,
3029 AudioContext::LIVE_AUDIO, AudioContext::SOUND_EFFECTS,
3030 AudioContext::NOTIFICATIONS, AudioContext::RINGTONE_ALERTS,
3031 AudioContext::ALERTS, AudioContext::EMERGENCY_ALARM,
3032 };
3033
3034 AudioContext bidirectional_contexts = {
3035 .bitmask = AudioContext::CONVERSATIONAL | AudioContext::GAME |
3036 AudioContext::VOICE_ASSISTANTS | AudioContext::LIVE_AUDIO,
3037 };
3038 };
3039
3040 /**
3041 * Test whether each provider of type
3042 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
3043 * stopped
3044 */
TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,OpenLeAudioOutputHardwareProvider)3045 TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
3046 OpenLeAudioOutputHardwareProvider) {}
3047
3048 /**
3049 * Test whether each provider of type
3050 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
3051 * stopped with Unicast hardware encoding config taken from provider info
3052 */
TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,StartAndEndLeAudioOutputSessionWithPossibleUnicastConfigFromProviderInfo)3053 TEST_P(
3054 BluetoothAudioProviderLeAudioOutputHardwareAidl,
3055 StartAndEndLeAudioOutputSessionWithPossibleUnicastConfigFromProviderInfo) {
3056 if (GetProviderFactoryInterfaceVersion() <
3057 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3058 GTEST_SKIP();
3059 }
3060 if (!IsOffloadOutputProviderInfoSupported()) {
3061 GTEST_SKIP();
3062 }
3063
3064 auto lc3_codec_configs = GetUnicastLc3SupportedListFromProviderInfo();
3065 LeAudioConfiguration le_audio_config = {
3066 .codecType = CodecType::LC3,
3067 .peerDelayUs = 0,
3068 };
3069
3070 for (auto& lc3_config : lc3_codec_configs) {
3071 le_audio_config.leAudioCodecConfig
3072 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
3073 DataMQDesc mq_desc;
3074 auto aidl_retval = audio_provider_->startSession(
3075 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
3076 &mq_desc);
3077
3078 ASSERT_TRUE(aidl_retval.isOk());
3079 EXPECT_TRUE(audio_provider_->endSession().isOk());
3080 }
3081 }
3082
TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,GetEmptyAseConfigurationEmptyCapability)3083 TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
3084 GetEmptyAseConfigurationEmptyCapability) {
3085 if (GetProviderFactoryInterfaceVersion() <
3086 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3087 GTEST_SKIP();
3088 }
3089
3090 if (IsMultidirectionalCapabilitiesEnabled()) {
3091 GTEST_SKIP();
3092 }
3093
3094 std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
3095 std::vector<LeAudioConfigurationRequirement> empty_requirement;
3096 std::vector<LeAudioAseConfigurationSetting> configurations;
3097
3098 // Check empty capability for source direction
3099 auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3100 std::nullopt, empty_capability, empty_requirement, &configurations);
3101
3102 ASSERT_FALSE(aidl_retval.isOk());
3103
3104 // Check empty capability for sink direction
3105 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3106 empty_capability, std::nullopt, empty_requirement, &configurations);
3107
3108 ASSERT_TRUE(aidl_retval.isOk());
3109 ASSERT_TRUE(configurations.empty());
3110 }
3111
TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,GetEmptyAseConfigurationEmptyCapability_Multidirectiona)3112 TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
3113 GetEmptyAseConfigurationEmptyCapability_Multidirectiona) {
3114 if (GetProviderFactoryInterfaceVersion() <
3115 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3116 GTEST_SKIP();
3117 }
3118
3119 if (!IsMultidirectionalCapabilitiesEnabled()) {
3120 GTEST_SKIP();
3121 }
3122
3123 std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
3124 std::vector<LeAudioConfigurationRequirement> empty_requirement;
3125 std::vector<LeAudioAseConfigurationSetting> configurations;
3126
3127 // Check empty capability for source direction
3128 auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3129 std::nullopt, empty_capability, empty_requirement, &configurations);
3130
3131 ASSERT_TRUE(aidl_retval.isOk());
3132 ASSERT_TRUE(configurations.empty());
3133
3134 // Check empty capability for sink direction
3135 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3136 empty_capability, std::nullopt, empty_requirement, &configurations);
3137
3138 ASSERT_TRUE(aidl_retval.isOk());
3139 ASSERT_TRUE(configurations.empty());
3140 }
3141
TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,GetEmptyAseConfigurationMismatchedRequirement)3142 TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
3143 GetEmptyAseConfigurationMismatchedRequirement) {
3144 if (GetProviderFactoryInterfaceVersion() <
3145 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3146 GTEST_SKIP();
3147 }
3148 std::vector<std::optional<LeAudioDeviceCapabilities>> sink_capabilities = {
3149 GetDefaultRemoteSinkCapability()};
3150 std::vector<std::optional<LeAudioDeviceCapabilities>> source_capabilities = {
3151 GetDefaultRemoteSourceCapability()};
3152
3153 auto not_supported_sampling_rate_by_remote =
3154 CodecSpecificConfigurationLtv::SamplingFrequency::HZ11025;
3155
3156 // Check empty capability for source direction
3157 std::vector<LeAudioAseConfigurationSetting> configurations;
3158 std::vector<LeAudioConfigurationRequirement> source_requirements = {
3159 GetUnicastDefaultRequirement(AudioContext::LIVE_AUDIO, false /*sink */,
3160 true /* source */,
3161 not_supported_sampling_rate_by_remote)};
3162 auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3163 std::nullopt, source_capabilities, source_requirements, &configurations);
3164
3165 ASSERT_TRUE(aidl_retval.isOk());
3166 ASSERT_TRUE(configurations.empty());
3167
3168 // Check empty capability for sink direction
3169 std::vector<LeAudioConfigurationRequirement> sink_requirements = {
3170 GetUnicastDefaultRequirement(AudioContext::MEDIA, true /*sink */,
3171 false /* source */,
3172 not_supported_sampling_rate_by_remote)};
3173 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3174 sink_capabilities, std::nullopt, sink_requirements, &configurations);
3175
3176 ASSERT_TRUE(aidl_retval.isOk());
3177 ASSERT_TRUE(configurations.empty());
3178 }
3179
TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,GetAseConfiguration)3180 TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl, GetAseConfiguration) {
3181 if (GetProviderFactoryInterfaceVersion() <
3182 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3183 GTEST_SKIP();
3184 }
3185
3186 if (IsMultidirectionalCapabilitiesEnabled()) {
3187 GTEST_SKIP();
3188 }
3189
3190 std::vector<std::optional<LeAudioDeviceCapabilities>> sink_capabilities = {
3191 GetDefaultRemoteSinkCapability()};
3192 std::vector<std::optional<LeAudioDeviceCapabilities>> source_capabilities = {
3193 GetDefaultRemoteSourceCapability()};
3194
3195 // Should not ask for Source on ENCODING session if Multidiretional not
3196 // supported
3197 std::vector<LeAudioAseConfigurationSetting> configurations;
3198 std::vector<LeAudioConfigurationRequirement> source_requirements = {
3199 GetUnicastDefaultRequirement(AudioContext::LIVE_AUDIO, false /* sink */,
3200 true /* source */)};
3201 auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3202 std::nullopt, source_capabilities, source_requirements, &configurations);
3203
3204 ASSERT_FALSE(aidl_retval.isOk());
3205 ASSERT_TRUE(configurations.empty());
3206
3207 // Check capability for remote sink direction
3208 std::vector<LeAudioConfigurationRequirement> sink_requirements = {
3209 GetUnicastDefaultRequirement(AudioContext::MEDIA, true /* sink */,
3210 false /* source */)};
3211 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3212 sink_capabilities, std::nullopt, sink_requirements, &configurations);
3213
3214 ASSERT_TRUE(aidl_retval.isOk());
3215 ASSERT_FALSE(configurations.empty());
3216 VerifyIfRequirementsSatisfied(sink_requirements, configurations);
3217
3218 // Check multiple capability for remote sink direction
3219 std::vector<LeAudioConfigurationRequirement> multi_sink_requirements = {
3220 GetUnicastDefaultRequirement(AudioContext::MEDIA, true /* sink */,
3221 false /* source */),
3222 GetUnicastDefaultRequirement(AudioContext::CONVERSATIONAL,
3223 true /* sink */, false /* source */)};
3224 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3225 sink_capabilities, std::nullopt, multi_sink_requirements,
3226 &configurations);
3227
3228 ASSERT_TRUE(aidl_retval.isOk());
3229 ASSERT_FALSE(configurations.empty());
3230 VerifyIfRequirementsSatisfied(multi_sink_requirements, configurations);
3231
3232 // Check multiple context types in a single requirement.
3233 std::vector<LeAudioConfigurationRequirement> multi_context_sink_requirements =
3234 {GetUnicastDefaultRequirement(
3235 AudioContext::MEDIA | AudioContext::SOUND_EFFECTS, true /* sink */,
3236 false /* source */)};
3237 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3238 sink_capabilities, std::nullopt, multi_context_sink_requirements,
3239 &configurations);
3240
3241 ASSERT_TRUE(aidl_retval.isOk());
3242 ASSERT_FALSE(configurations.empty());
3243 VerifyIfRequirementsSatisfied(multi_sink_requirements, configurations);
3244 }
3245
TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,GetOpusAseConfiguration)3246 TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
3247 GetOpusAseConfiguration) {
3248 if (GetProviderFactoryInterfaceVersion() <
3249 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3250 GTEST_SKIP();
3251 }
3252
3253 std::vector<std::optional<LeAudioDeviceCapabilities>> sink_capabilities = {
3254 GetOpusRemoteSinkCapability()};
3255 std::vector<std::optional<LeAudioDeviceCapabilities>> source_capabilities = {
3256 GetDefaultRemoteSourceCapability()};
3257
3258 std::vector<LeAudioAseConfigurationSetting> configurations;
3259 std::vector<LeAudioConfigurationRequirement> sink_requirements = {
3260 GetOpusUnicastRequirement(AudioContext::MEDIA, true /* sink */,
3261 false /* source */)};
3262 auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3263 sink_capabilities, std::nullopt, sink_requirements, &configurations);
3264
3265 ASSERT_TRUE(aidl_retval.isOk());
3266 if (!configurations.empty()) {
3267 VerifyIfRequirementsSatisfied(sink_requirements, configurations);
3268 }
3269 }
3270
TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,GetAseConfiguration_Multidirectional)3271 TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
3272 GetAseConfiguration_Multidirectional) {
3273 if (GetProviderFactoryInterfaceVersion() <
3274 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3275 GTEST_SKIP();
3276 }
3277
3278 if (!IsMultidirectionalCapabilitiesEnabled()) {
3279 GTEST_SKIP();
3280 }
3281
3282 std::vector<std::optional<LeAudioDeviceCapabilities>> sink_capabilities = {
3283 GetDefaultRemoteSinkCapability()};
3284 std::vector<std::optional<LeAudioDeviceCapabilities>> source_capabilities = {
3285 GetDefaultRemoteSourceCapability()};
3286
3287 // Verify source configuration is received
3288 std::vector<LeAudioAseConfigurationSetting> configurations;
3289 std::vector<LeAudioConfigurationRequirement> source_requirements = {
3290 GetUnicastDefaultRequirement(AudioContext::LIVE_AUDIO, false /* sink */,
3291 true /* source */)};
3292 auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3293 std::nullopt, source_capabilities, source_requirements, &configurations);
3294
3295 ASSERT_TRUE(aidl_retval.isOk());
3296 ASSERT_FALSE(configurations.empty());
3297 VerifyIfRequirementsSatisfied(source_requirements, configurations);
3298
3299 // Verify sink configuration is received
3300 std::vector<LeAudioConfigurationRequirement> sink_requirements = {
3301 GetUnicastDefaultRequirement(AudioContext::MEDIA, true /* sink */,
3302 false /* source */)};
3303 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3304 sink_capabilities, std::nullopt, sink_requirements, &configurations);
3305
3306 ASSERT_TRUE(aidl_retval.isOk());
3307 ASSERT_FALSE(configurations.empty());
3308 VerifyIfRequirementsSatisfied(sink_requirements, configurations);
3309
3310 std::vector<LeAudioConfigurationRequirement> combined_requirements = {
3311 GetUnicastDefaultRequirement(AudioContext::LIVE_AUDIO, false /* sink */,
3312 true /* source */),
3313 GetUnicastDefaultRequirement(AudioContext::CONVERSATIONAL,
3314 true /* sink */, true /* source */),
3315 GetUnicastDefaultRequirement(AudioContext::MEDIA, true /* sink */,
3316 false /* source */)};
3317
3318 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3319 sink_capabilities, source_capabilities, combined_requirements,
3320 &configurations);
3321
3322 ASSERT_TRUE(aidl_retval.isOk());
3323 ASSERT_FALSE(configurations.empty());
3324 VerifyIfRequirementsSatisfied(combined_requirements, configurations);
3325 }
3326
TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,GetAsymmetricAseConfiguration_Multidirectional)3327 TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
3328 GetAsymmetricAseConfiguration_Multidirectional) {
3329 if (GetProviderFactoryInterfaceVersion() <
3330 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3331 GTEST_SKIP();
3332 }
3333
3334 if (!IsMultidirectionalCapabilitiesEnabled()) {
3335 GTEST_SKIP();
3336 }
3337
3338 if (!IsAsymmetricConfigurationAllowed()) {
3339 GTEST_SKIP();
3340 }
3341
3342 std::vector<LeAudioAseConfigurationSetting> configurations;
3343 std::vector<std::optional<LeAudioDeviceCapabilities>> sink_capabilities = {
3344 GetDefaultRemoteSinkCapability()};
3345 std::vector<std::optional<LeAudioDeviceCapabilities>> source_capabilities = {
3346 GetDefaultRemoteSourceCapability()};
3347
3348 std::vector<LeAudioConfigurationRequirement> asymmetric_requirements = {
3349 GetUnicastGameRequirement(true /* Asymmetric */)};
3350
3351 auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3352 sink_capabilities, source_capabilities, asymmetric_requirements,
3353 &configurations);
3354
3355 ASSERT_TRUE(aidl_retval.isOk());
3356 ASSERT_FALSE(configurations.empty());
3357 VerifyIfRequirementsSatisfied(asymmetric_requirements, configurations);
3358 }
3359
TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,GetQoSConfiguration_Multidirectional)3360 TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
3361 GetQoSConfiguration_Multidirectional) {
3362 if (GetProviderFactoryInterfaceVersion() <
3363 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3364 GTEST_SKIP();
3365 }
3366
3367 if (!IsMultidirectionalCapabilitiesEnabled()) {
3368 GTEST_SKIP();
3369 }
3370
3371 auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
3372 allocation.bitmask =
3373 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
3374 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
3375
3376 LeAudioAseQosConfigurationRequirement requirement =
3377 GetQosRequirements(true, true);
3378
3379 std::vector<IBluetoothAudioProvider::LeAudioAseQosConfiguration>
3380 QoSConfigurations;
3381 bool is_supported = false;
3382 for (auto bitmask : all_context_bitmasks) {
3383 requirement.audioContext = GetAudioContext(bitmask);
3384 bool is_bidirectional = bidirectional_contexts.bitmask & bitmask;
3385
3386 if (is_bidirectional) {
3387 requirement.sourceAseQosRequirement = requirement.sinkAseQosRequirement;
3388 } else {
3389 requirement.sourceAseQosRequirement = std::nullopt;
3390 }
3391
3392 IBluetoothAudioProvider::LeAudioAseQosConfigurationPair result;
3393 auto aidl_retval =
3394 audio_provider_->getLeAudioAseQosConfiguration(requirement, &result);
3395 if (!aidl_retval.isOk()) {
3396 // If not OK, then it could be not supported, as it is an optional
3397 // feature
3398 ASSERT_EQ(aidl_retval.getExceptionCode(), EX_UNSUPPORTED_OPERATION);
3399 }
3400
3401 is_supported = true;
3402 if (result.sinkQosConfiguration.has_value()) {
3403 if (is_bidirectional) {
3404 ASSERT_TRUE(result.sourceQosConfiguration.has_value());
3405 } else {
3406 ASSERT_FALSE(result.sourceQosConfiguration.has_value());
3407 }
3408 QoSConfigurations.push_back(result.sinkQosConfiguration.value());
3409 }
3410 }
3411 if (is_supported) {
3412 // QoS Configurations should not be empty, as we searched for all contexts
3413 ASSERT_FALSE(QoSConfigurations.empty());
3414 }
3415 }
3416
TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,GetQoSConfiguration_InvalidRequirements)3417 TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
3418 GetQoSConfiguration_InvalidRequirements) {
3419 if (GetProviderFactoryInterfaceVersion() <
3420 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3421 GTEST_SKIP();
3422 }
3423 auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
3424 allocation.bitmask =
3425 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
3426 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
3427
3428 LeAudioAseQosConfigurationRequirement invalid_requirement =
3429 GetQosRequirements(true /* sink */, false /* source */,
3430 false /* valid */);
3431
3432 std::vector<IBluetoothAudioProvider::LeAudioAseQosConfiguration>
3433 QoSConfigurations;
3434 for (auto bitmask : all_context_bitmasks) {
3435 invalid_requirement.audioContext = GetAudioContext(bitmask);
3436 IBluetoothAudioProvider::LeAudioAseQosConfigurationPair result;
3437 auto aidl_retval = audio_provider_->getLeAudioAseQosConfiguration(
3438 invalid_requirement, &result);
3439 ASSERT_FALSE(aidl_retval.isOk());
3440 }
3441 }
3442
TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,GetQoSConfiguration)3443 TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl, GetQoSConfiguration) {
3444 if (GetProviderFactoryInterfaceVersion() <
3445 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3446 GTEST_SKIP();
3447 }
3448 auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
3449 allocation.bitmask =
3450 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
3451 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
3452
3453 IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement requirement;
3454 requirement = GetQosRequirements(true /* sink */, false /* source */);
3455
3456 std::vector<IBluetoothAudioProvider::LeAudioAseQosConfiguration>
3457 QoSConfigurations;
3458 bool is_supported = false;
3459 for (auto bitmask : all_context_bitmasks) {
3460 requirement.audioContext = GetAudioContext(bitmask);
3461 IBluetoothAudioProvider::LeAudioAseQosConfigurationPair result;
3462 auto aidl_retval =
3463 audio_provider_->getLeAudioAseQosConfiguration(requirement, &result);
3464 if (!aidl_retval.isOk()) {
3465 // If not OK, then it could be not supported, as it is an optional
3466 // feature
3467 ASSERT_EQ(aidl_retval.getExceptionCode(), EX_UNSUPPORTED_OPERATION);
3468 } else {
3469 is_supported = true;
3470 if (result.sinkQosConfiguration.has_value()) {
3471 QoSConfigurations.push_back(result.sinkQosConfiguration.value());
3472 }
3473 }
3474 }
3475
3476 if (is_supported) {
3477 // QoS Configurations should not be empty, as we searched for all contexts
3478 ASSERT_FALSE(QoSConfigurations.empty());
3479 }
3480 }
3481
TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,GetDataPathConfiguration_Multidirectional)3482 TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
3483 GetDataPathConfiguration_Multidirectional) {
3484 IBluetoothAudioProvider::StreamConfig sink_requirement;
3485 IBluetoothAudioProvider::StreamConfig source_requirement;
3486 std::vector<IBluetoothAudioProvider::LeAudioDataPathConfiguration>
3487 DataPathConfigurations;
3488
3489 if (!IsMultidirectionalCapabilitiesEnabled()) {
3490 GTEST_SKIP();
3491 }
3492
3493 bool is_supported = false;
3494 auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
3495 allocation.bitmask =
3496 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
3497 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
3498
3499 auto streamMap = LeAudioConfiguration::StreamMap();
3500
3501 // Use some mandatory configuration
3502 streamMap.streamHandle = 0x0001;
3503 streamMap.audioChannelAllocation = 0x03;
3504 streamMap.aseConfiguration = {
3505 .targetLatency =
3506 LeAudioAseConfiguration::TargetLatency::BALANCED_LATENCY_RELIABILITY,
3507 .codecId = CodecId::Core::LC3,
3508 .codecConfiguration =
3509 {CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000,
3510 CodecSpecificConfigurationLtv::FrameDuration::US10000, allocation},
3511 };
3512
3513 // Bidirectional
3514 sink_requirement.streamMap = {streamMap};
3515 source_requirement.streamMap = {streamMap};
3516
3517 for (auto bitmask : all_context_bitmasks) {
3518 sink_requirement.audioContext = GetAudioContext(bitmask);
3519 source_requirement.audioContext = sink_requirement.audioContext;
3520
3521 IBluetoothAudioProvider::LeAudioDataPathConfigurationPair result;
3522 ::ndk::ScopedAStatus aidl_retval;
3523
3524 bool is_bidirectional = bidirectional_contexts.bitmask & bitmask;
3525 if (is_bidirectional) {
3526 aidl_retval = audio_provider_->getLeAudioAseDatapathConfiguration(
3527 sink_requirement, source_requirement, &result);
3528 } else {
3529 aidl_retval = audio_provider_->getLeAudioAseDatapathConfiguration(
3530 sink_requirement, std::nullopt, &result);
3531 }
3532
3533 if (!aidl_retval.isOk()) {
3534 // If not OK, then it could be not supported, as it is an optional
3535 // feature
3536 ASSERT_EQ(aidl_retval.getExceptionCode(), EX_UNSUPPORTED_OPERATION);
3537 } else {
3538 is_supported = true;
3539 if (result.outputConfig.has_value()) {
3540 if (is_bidirectional) {
3541 ASSERT_TRUE(result.inputConfig.has_value());
3542 } else {
3543 ASSERT_TRUE(!result.inputConfig.has_value());
3544 }
3545 DataPathConfigurations.push_back(result.outputConfig.value());
3546 }
3547 }
3548 }
3549
3550 if (is_supported) {
3551 // Datapath Configurations should not be empty, as we searched for all
3552 // contexts
3553 ASSERT_FALSE(DataPathConfigurations.empty());
3554 }
3555 }
3556
TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,GetDataPathConfiguration)3557 TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
3558 GetDataPathConfiguration) {
3559 if (GetProviderFactoryInterfaceVersion() <
3560 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3561 GTEST_SKIP();
3562 }
3563 IBluetoothAudioProvider::StreamConfig sink_requirement;
3564 std::vector<IBluetoothAudioProvider::LeAudioDataPathConfiguration>
3565 DataPathConfigurations;
3566 bool is_supported = false;
3567 auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
3568 allocation.bitmask =
3569 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
3570 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
3571
3572 auto streamMap = LeAudioConfiguration::StreamMap();
3573
3574 // Use some mandatory configuration
3575 streamMap.streamHandle = 0x0001;
3576 streamMap.audioChannelAllocation = 0x03;
3577 streamMap.aseConfiguration = {
3578 .targetLatency =
3579 LeAudioAseConfiguration::TargetLatency::BALANCED_LATENCY_RELIABILITY,
3580 .codecId = CodecId::Core::LC3,
3581 .codecConfiguration =
3582 {CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000,
3583 CodecSpecificConfigurationLtv::FrameDuration::US10000, allocation},
3584 };
3585
3586 sink_requirement.streamMap = {streamMap};
3587
3588 for (auto bitmask : all_context_bitmasks) {
3589 sink_requirement.audioContext = GetAudioContext(bitmask);
3590 IBluetoothAudioProvider::LeAudioDataPathConfigurationPair result;
3591 auto aidl_retval = audio_provider_->getLeAudioAseDatapathConfiguration(
3592 sink_requirement, std::nullopt, &result);
3593
3594 if (!aidl_retval.isOk()) {
3595 // If not OK, then it could be not supported, as it is an optional
3596 // feature
3597 ASSERT_EQ(aidl_retval.getExceptionCode(), EX_UNSUPPORTED_OPERATION);
3598 } else {
3599 is_supported = true;
3600 if (result.outputConfig.has_value()) {
3601 DataPathConfigurations.push_back(result.outputConfig.value());
3602 }
3603 }
3604 }
3605
3606 if (is_supported) {
3607 // Datapath Configurations should not be empty, as we searched for all
3608 // contexts
3609 ASSERT_FALSE(DataPathConfigurations.empty());
3610 }
3611 }
3612
3613 /**
3614 * Test whether each provider of type
3615 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
3616 * stopped with Unicast hardware encoding config
3617 */
TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,StartAndEndLeAudioOutputSessionWithPossibleUnicastConfig)3618 TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
3619 StartAndEndLeAudioOutputSessionWithPossibleUnicastConfig) {
3620 if (!IsOffloadOutputSupported()) {
3621 GTEST_SKIP();
3622 }
3623
3624 auto lc3_codec_configs =
3625 GetUnicastLc3SupportedList(false /* decoding */, true /* supported */);
3626 LeAudioConfiguration le_audio_config = {
3627 .codecType = CodecType::LC3,
3628 .peerDelayUs = 0,
3629 };
3630
3631 for (auto& lc3_config : lc3_codec_configs) {
3632 le_audio_config.leAudioCodecConfig
3633 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
3634 DataMQDesc mq_desc;
3635 auto aidl_retval = audio_provider_->startSession(
3636 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
3637 &mq_desc);
3638
3639 ASSERT_TRUE(aidl_retval.isOk());
3640 EXPECT_TRUE(audio_provider_->endSession().isOk());
3641 }
3642 }
3643
3644 /**
3645 * Test whether each provider of type
3646 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
3647 * stopped with Unicast hardware encoding config
3648 *
3649 */
TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,StartAndEndLeAudioOutputSessionWithInvalidAudioConfiguration)3650 TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
3651 StartAndEndLeAudioOutputSessionWithInvalidAudioConfiguration) {
3652 if (!IsOffloadOutputSupported()) {
3653 GTEST_SKIP();
3654 }
3655
3656 auto lc3_codec_configs =
3657 GetUnicastLc3SupportedList(false /* decoding */, false /* supported */);
3658 LeAudioConfiguration le_audio_config = {
3659 .codecType = CodecType::LC3,
3660 .peerDelayUs = 0,
3661 };
3662
3663 for (auto& lc3_config : lc3_codec_configs) {
3664 le_audio_config.leAudioCodecConfig
3665 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
3666 DataMQDesc mq_desc;
3667 auto aidl_retval = audio_provider_->startSession(
3668 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
3669 &mq_desc);
3670
3671 // It is OK to start session with invalid configuration
3672 ASSERT_TRUE(aidl_retval.isOk());
3673 EXPECT_TRUE(audio_provider_->endSession().isOk());
3674 }
3675 }
3676
3677 static std::vector<uint8_t> vendorMetadata = {0x0B, // Length
3678 0xFF, // Type: Vendor-specific
3679 0x0A, 0x00, // Company_ID
3680 0x01, 0x02, 0x03, 0x04, // Data
3681 0x05, 0x06, 0x07, 0x08};
3682
3683 /**
3684 * Test whether each provider of type
3685 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
3686 * stopped with Unicast hardware encoding config
3687 */
TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,StartAndEndLeAudioOutputSessionWithAptxAdaptiveLeUnicastConfig)3688 TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
3689 StartAndEndLeAudioOutputSessionWithAptxAdaptiveLeUnicastConfig) {
3690 if (!IsOffloadOutputSupported()) {
3691 GTEST_SKIP();
3692 }
3693 for (auto codec_type :
3694 {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
3695 bool is_le_extended = (codec_type == CodecType::APTX_ADAPTIVE_LEX);
3696 auto aptx_adaptive_le_codec_configs =
3697 GetUnicastAptxAdaptiveLeSupportedList(false, true, is_le_extended);
3698 LeAudioConfiguration le_audio_config = {
3699 .codecType = codec_type,
3700 .peerDelayUs = 0,
3701 .vendorSpecificMetadata = vendorMetadata,
3702 };
3703
3704 for (auto& aptx_adaptive_le_config : aptx_adaptive_le_codec_configs) {
3705 le_audio_config.leAudioCodecConfig
3706 .set<LeAudioCodecConfiguration::aptxAdaptiveLeConfig>(
3707 aptx_adaptive_le_config);
3708 DataMQDesc mq_desc;
3709 auto aidl_retval = audio_provider_->startSession(
3710 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
3711 &mq_desc);
3712
3713 ASSERT_TRUE(aidl_retval.isOk());
3714 EXPECT_TRUE(audio_provider_->endSession().isOk());
3715 }
3716 }
3717 }
3718
3719 /**
3720 * Test whether each provider of type
3721 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
3722 * stopped with Unicast hardware encoding config
3723 */
TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,BluetoothAudioProviderLeAudioOutputHardwareAidl_StartAndEndLeAudioOutputSessionWithInvalidAptxAdaptiveLeAudioConfiguration)3724 TEST_P(
3725 BluetoothAudioProviderLeAudioOutputHardwareAidl,
3726 BluetoothAudioProviderLeAudioOutputHardwareAidl_StartAndEndLeAudioOutputSessionWithInvalidAptxAdaptiveLeAudioConfiguration) {
3727 if (!IsOffloadOutputSupported()) {
3728 GTEST_SKIP();
3729 }
3730
3731 for (auto codec_type :
3732 {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
3733 bool is_le_extended = (codec_type == CodecType::APTX_ADAPTIVE_LEX);
3734 auto aptx_adaptive_le_codec_configs =
3735 GetUnicastAptxAdaptiveLeSupportedList(false, true, is_le_extended);
3736 LeAudioConfiguration le_audio_config = {
3737 .codecType = codec_type,
3738 .peerDelayUs = 0,
3739 .vendorSpecificMetadata = vendorMetadata,
3740 };
3741
3742 for (auto& aptx_adaptive_le_config : aptx_adaptive_le_codec_configs) {
3743 le_audio_config.leAudioCodecConfig
3744 .set<LeAudioCodecConfiguration::aptxAdaptiveLeConfig>(
3745 aptx_adaptive_le_config);
3746 DataMQDesc mq_desc;
3747 auto aidl_retval = audio_provider_->startSession(
3748 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
3749 &mq_desc);
3750
3751 // It is OK to start session with invalid configuration
3752 ASSERT_TRUE(aidl_retval.isOk());
3753 EXPECT_TRUE(audio_provider_->endSession().isOk());
3754 }
3755 }
3756 }
3757
3758 /**
3759 * openProvider LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH
3760 */
3761 class BluetoothAudioProviderLeAudioInputHardwareAidl
3762 : public BluetoothAudioProviderLeAudioOutputHardwareAidl {
3763 public:
SetUp()3764 virtual void SetUp() override {
3765 BluetoothAudioProviderFactoryAidl::SetUp();
3766 GetProviderCapabilitiesHelper(
3767 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
3768 GetProviderInfoHelper(
3769 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
3770 OpenProviderHelper(
3771 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
3772 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
3773 audio_provider_ != nullptr);
3774 }
3775
IsOffloadInputSupported()3776 bool IsOffloadInputSupported() {
3777 for (auto& capability : temp_provider_capabilities_) {
3778 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
3779 continue;
3780 }
3781 auto& le_audio_capability =
3782 capability.get<AudioCapabilities::leAudioCapabilities>();
3783 if (le_audio_capability.unicastDecodeCapability.codecType !=
3784 CodecType::UNKNOWN)
3785 return true;
3786 }
3787 return false;
3788 }
3789
TearDown()3790 virtual void TearDown() override {
3791 audio_port_ = nullptr;
3792 audio_provider_ = nullptr;
3793 BluetoothAudioProviderFactoryAidl::TearDown();
3794 }
3795 };
3796
3797 /**
3798 * Test whether each provider of type
3799 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
3800 * stopped
3801 */
TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,OpenLeAudioInputHardwareProvider)3802 TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
3803 OpenLeAudioInputHardwareProvider) {}
3804
3805 /**
3806 * Test whether each provider of type
3807 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
3808 * stopped with Unicast hardware encoding config taken from provider info
3809 */
TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,StartAndEndLeAudioInputSessionWithPossibleUnicastConfigFromProviderInfo)3810 TEST_P(
3811 BluetoothAudioProviderLeAudioInputHardwareAidl,
3812 StartAndEndLeAudioInputSessionWithPossibleUnicastConfigFromProviderInfo) {
3813 if (!IsOffloadOutputProviderInfoSupported()) {
3814 GTEST_SKIP();
3815 }
3816
3817 auto lc3_codec_configs = GetUnicastLc3SupportedListFromProviderInfo();
3818 LeAudioConfiguration le_audio_config = {
3819 .codecType = CodecType::LC3,
3820 .peerDelayUs = 0,
3821 };
3822
3823 for (auto& lc3_config : lc3_codec_configs) {
3824 le_audio_config.leAudioCodecConfig
3825 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
3826 DataMQDesc mq_desc;
3827 auto aidl_retval = audio_provider_->startSession(
3828 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
3829 &mq_desc);
3830
3831 ASSERT_TRUE(aidl_retval.isOk());
3832 EXPECT_TRUE(audio_provider_->endSession().isOk());
3833 }
3834 }
3835
3836 /**
3837 * Test whether each provider of type
3838 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
3839 * stopped with Unicast hardware encoding config
3840 */
TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,StartAndEndLeAudioInputSessionWithPossibleUnicastConfig)3841 TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
3842 StartAndEndLeAudioInputSessionWithPossibleUnicastConfig) {
3843 if (!IsOffloadInputSupported()) {
3844 GTEST_SKIP();
3845 }
3846
3847 auto lc3_codec_configs =
3848 GetUnicastLc3SupportedList(true /* decoding */, true /* supported */);
3849 LeAudioConfiguration le_audio_config = {
3850 .codecType = CodecType::LC3,
3851 .peerDelayUs = 0,
3852 };
3853
3854 for (auto& lc3_config : lc3_codec_configs) {
3855 le_audio_config.leAudioCodecConfig
3856 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
3857 DataMQDesc mq_desc;
3858 auto aidl_retval = audio_provider_->startSession(
3859 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
3860 &mq_desc);
3861
3862 ASSERT_TRUE(aidl_retval.isOk());
3863 EXPECT_TRUE(audio_provider_->endSession().isOk());
3864 }
3865 }
3866
3867 /**
3868 * Test whether each provider of type
3869 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
3870 * stopped with Unicast hardware encoding config
3871 *
3872 */
TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,StartAndEndLeAudioInputSessionWithInvalidAudioConfiguration)3873 TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
3874 StartAndEndLeAudioInputSessionWithInvalidAudioConfiguration) {
3875 if (!IsOffloadInputSupported()) {
3876 GTEST_SKIP();
3877 }
3878
3879 auto lc3_codec_configs =
3880 GetUnicastLc3SupportedList(true /* decoding */, false /* supported */);
3881 LeAudioConfiguration le_audio_config = {
3882 .codecType = CodecType::LC3,
3883 .peerDelayUs = 0,
3884 };
3885
3886 for (auto& lc3_config : lc3_codec_configs) {
3887 le_audio_config.leAudioCodecConfig
3888 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
3889
3890 DataMQDesc mq_desc;
3891 auto aidl_retval = audio_provider_->startSession(
3892 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
3893 &mq_desc);
3894
3895 // It is OK to start with invalid configuration as it might be unknown on
3896 // start
3897 ASSERT_TRUE(aidl_retval.isOk());
3898 EXPECT_TRUE(audio_provider_->endSession().isOk());
3899 }
3900 }
3901
TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,GetEmptyAseConfigurationEmptyCapability)3902 TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
3903 GetEmptyAseConfigurationEmptyCapability) {
3904 if (GetProviderFactoryInterfaceVersion() <
3905 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3906 GTEST_SKIP();
3907 }
3908
3909 if (IsMultidirectionalCapabilitiesEnabled()) {
3910 GTEST_SKIP();
3911 }
3912
3913 std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
3914 std::vector<LeAudioConfigurationRequirement> empty_requirement;
3915 std::vector<LeAudioAseConfigurationSetting> configurations;
3916
3917 // Check success for source direction (Input == DecodingSession == remote
3918 // source)
3919 auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3920 std::nullopt, empty_capability, empty_requirement, &configurations);
3921
3922 ASSERT_TRUE(aidl_retval.isOk());
3923 ASSERT_TRUE(configurations.empty());
3924
3925 // Check failure for sink direction
3926 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3927 empty_capability, std::nullopt, empty_requirement, &configurations);
3928
3929 ASSERT_FALSE(aidl_retval.isOk());
3930 }
3931
TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,GetEmptyAseConfigurationEmptyCapability_Multidirectional)3932 TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
3933 GetEmptyAseConfigurationEmptyCapability_Multidirectional) {
3934 if (GetProviderFactoryInterfaceVersion() <
3935 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3936 GTEST_SKIP();
3937 }
3938
3939 if (!IsMultidirectionalCapabilitiesEnabled()) {
3940 GTEST_SKIP();
3941 }
3942
3943 std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
3944 std::vector<LeAudioConfigurationRequirement> empty_requirement;
3945 std::vector<LeAudioAseConfigurationSetting> configurations;
3946
3947 // Check empty capability for source direction
3948 auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3949 std::nullopt, empty_capability, empty_requirement, &configurations);
3950
3951 ASSERT_TRUE(aidl_retval.isOk());
3952 ASSERT_TRUE(configurations.empty());
3953
3954 // Check empty capability for sink direction
3955 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3956 empty_capability, std::nullopt, empty_requirement, &configurations);
3957
3958 ASSERT_TRUE(aidl_retval.isOk());
3959 ASSERT_TRUE(configurations.empty());
3960 }
3961
TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,GetAseConfiguration)3962 TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl, GetAseConfiguration) {
3963 if (GetProviderFactoryInterfaceVersion() <
3964 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3965 GTEST_SKIP();
3966 }
3967
3968 if (IsMultidirectionalCapabilitiesEnabled()) {
3969 GTEST_SKIP();
3970 }
3971
3972 std::vector<std::optional<LeAudioDeviceCapabilities>> sink_capabilities = {
3973 GetDefaultRemoteSinkCapability()};
3974 std::vector<std::optional<LeAudioDeviceCapabilities>> source_capabilities = {
3975 GetDefaultRemoteSourceCapability()};
3976
3977 // Check source configuration is received
3978 std::vector<LeAudioAseConfigurationSetting> configurations;
3979 std::vector<LeAudioConfigurationRequirement> source_requirements = {
3980 GetUnicastDefaultRequirement(AudioContext::LIVE_AUDIO, false /* sink */,
3981 true /* source */)};
3982 auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3983 std::nullopt, source_capabilities, source_requirements, &configurations);
3984
3985 ASSERT_TRUE(aidl_retval.isOk());
3986 ASSERT_FALSE(configurations.empty());
3987
3988 // Check error result when requesting sink on DECODING session
3989 std::vector<LeAudioConfigurationRequirement> sink_requirements = {
3990 GetUnicastDefaultRequirement(AudioContext::MEDIA, true /* sink */,
3991 false /* source */)};
3992 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3993 sink_capabilities, std::nullopt, sink_requirements, &configurations);
3994
3995 ASSERT_FALSE(aidl_retval.isOk());
3996 }
3997
TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,GetAseConfiguration_Multidirectional)3998 TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
3999 GetAseConfiguration_Multidirectional) {
4000 if (GetProviderFactoryInterfaceVersion() <
4001 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
4002 GTEST_SKIP();
4003 }
4004
4005 if (!IsMultidirectionalCapabilitiesEnabled()) {
4006 GTEST_SKIP();
4007 }
4008
4009 std::vector<std::optional<LeAudioDeviceCapabilities>> sink_capabilities = {
4010 GetDefaultRemoteSinkCapability()};
4011 std::vector<std::optional<LeAudioDeviceCapabilities>> source_capabilities = {
4012 GetDefaultRemoteSourceCapability()};
4013
4014 // Check source configuration is received
4015 std::vector<LeAudioAseConfigurationSetting> configurations;
4016 std::vector<LeAudioConfigurationRequirement> source_requirements = {
4017 GetUnicastDefaultRequirement(AudioContext::LIVE_AUDIO, false /* sink */,
4018 true /* source */)};
4019 auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
4020 std::nullopt, source_capabilities, source_requirements, &configurations);
4021
4022 ASSERT_TRUE(aidl_retval.isOk());
4023 ASSERT_FALSE(configurations.empty());
4024 VerifyIfRequirementsSatisfied(source_requirements, configurations);
4025
4026 // Check empty capability for sink direction
4027 std::vector<LeAudioConfigurationRequirement> sink_requirements = {
4028 GetUnicastDefaultRequirement(AudioContext::MEDIA, true /* sink */,
4029 false /* source */)};
4030 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
4031 sink_capabilities, std::nullopt, sink_requirements, &configurations);
4032
4033 ASSERT_TRUE(aidl_retval.isOk());
4034 ASSERT_FALSE(configurations.empty());
4035 VerifyIfRequirementsSatisfied(sink_requirements, configurations);
4036
4037 std::vector<LeAudioConfigurationRequirement> combined_requirements = {
4038 GetUnicastDefaultRequirement(AudioContext::LIVE_AUDIO, false /* sink */,
4039 true /* source */),
4040 GetUnicastDefaultRequirement(AudioContext::CONVERSATIONAL,
4041 true /* sink */, true /* source */),
4042 GetUnicastDefaultRequirement(AudioContext::MEDIA, true /* sink */,
4043 false /* source */)};
4044
4045 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
4046 sink_capabilities, source_capabilities, combined_requirements,
4047 &configurations);
4048
4049 ASSERT_TRUE(aidl_retval.isOk());
4050 ASSERT_FALSE(configurations.empty());
4051 VerifyIfRequirementsSatisfied(combined_requirements, configurations);
4052 }
4053
TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,GetQoSConfiguration_InvalidRequirements)4054 TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
4055 GetQoSConfiguration_InvalidRequirements) {
4056 if (GetProviderFactoryInterfaceVersion() <
4057 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
4058 GTEST_SKIP();
4059 }
4060 auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
4061 allocation.bitmask =
4062 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
4063 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
4064
4065 LeAudioAseQosConfigurationRequirement invalid_requirement =
4066 GetQosRequirements(false /* sink */, true /* source */,
4067 false /* valid */);
4068
4069 std::vector<IBluetoothAudioProvider::LeAudioAseQosConfiguration>
4070 QoSConfigurations;
4071 for (auto bitmask : all_context_bitmasks) {
4072 invalid_requirement.audioContext = GetAudioContext(bitmask);
4073 IBluetoothAudioProvider::LeAudioAseQosConfigurationPair result;
4074 auto aidl_retval = audio_provider_->getLeAudioAseQosConfiguration(
4075 invalid_requirement, &result);
4076 ASSERT_FALSE(aidl_retval.isOk());
4077 }
4078 }
4079
TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,GetQoSConfiguration)4080 TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl, GetQoSConfiguration) {
4081 if (GetProviderFactoryInterfaceVersion() <
4082 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
4083 GTEST_SKIP();
4084 }
4085 auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
4086 allocation.bitmask =
4087 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
4088 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
4089
4090 IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement requirement;
4091 requirement = GetQosRequirements(false /* sink */, true /* source */);
4092
4093 std::vector<IBluetoothAudioProvider::LeAudioAseQosConfiguration>
4094 QoSConfigurations;
4095 bool is_supported = false;
4096 for (auto bitmask : all_context_bitmasks) {
4097 requirement.audioContext = GetAudioContext(bitmask);
4098 IBluetoothAudioProvider::LeAudioAseQosConfigurationPair result;
4099 auto aidl_retval =
4100 audio_provider_->getLeAudioAseQosConfiguration(requirement, &result);
4101 if (!aidl_retval.isOk()) {
4102 // If not OK, then it could be not supported, as it is an optional
4103 // feature
4104 ASSERT_EQ(aidl_retval.getExceptionCode(), EX_UNSUPPORTED_OPERATION);
4105 } else {
4106 is_supported = true;
4107 if (result.sourceQosConfiguration.has_value()) {
4108 QoSConfigurations.push_back(result.sourceQosConfiguration.value());
4109 }
4110 }
4111 }
4112
4113 if (is_supported) {
4114 // QoS Configurations should not be empty, as we searched for all contexts
4115 ASSERT_FALSE(QoSConfigurations.empty());
4116 }
4117 }
4118 /**
4119 * openProvider LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH
4120 */
4121 class BluetoothAudioProviderLeAudioBroadcastSoftwareAidl
4122 : public BluetoothAudioProviderFactoryAidl {
4123 public:
SetUp()4124 virtual void SetUp() override {
4125 BluetoothAudioProviderFactoryAidl::SetUp();
4126 GetProviderCapabilitiesHelper(
4127 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
4128 OpenProviderHelper(
4129 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
4130 ASSERT_NE(audio_provider_, nullptr);
4131 }
4132
TearDown()4133 virtual void TearDown() override {
4134 audio_port_ = nullptr;
4135 audio_provider_ = nullptr;
4136 BluetoothAudioProviderFactoryAidl::TearDown();
4137 }
4138
4139 static constexpr int32_t le_audio_output_sample_rates_[] = {
4140 0, 8000, 16000, 24000, 32000, 44100, 48000,
4141 };
4142 static constexpr int8_t le_audio_output_bits_per_samples_[] = {0, 16, 24};
4143 static constexpr ChannelMode le_audio_output_channel_modes_[] = {
4144 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
4145 static constexpr int32_t le_audio_output_data_interval_us_[] = {
4146 0 /* Invalid */, 10000 /* Valid 10ms */};
4147 };
4148
4149 /**
4150 * Test whether each provider of type
4151 * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started
4152 * and stopped
4153 */
TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,OpenLeAudioOutputSoftwareProvider)4154 TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
4155 OpenLeAudioOutputSoftwareProvider) {}
4156
4157 /**
4158 * Test whether each provider of type
4159 * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started
4160 * and stopped with different PCM config
4161 */
TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,StartAndEndLeAudioOutputSessionWithPossiblePcmConfig)4162 TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
4163 StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
4164 for (auto sample_rate : le_audio_output_sample_rates_) {
4165 for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
4166 for (auto channel_mode : le_audio_output_channel_modes_) {
4167 for (auto data_interval_us : le_audio_output_data_interval_us_) {
4168 PcmConfiguration pcm_config{
4169 .sampleRateHz = sample_rate,
4170 .channelMode = channel_mode,
4171 .bitsPerSample = bits_per_sample,
4172 .dataIntervalUs = data_interval_us,
4173 };
4174 bool is_codec_config_valid =
4175 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
4176 DataMQDesc mq_desc;
4177 auto aidl_retval = audio_provider_->startSession(
4178 audio_port_, AudioConfiguration(pcm_config), latency_modes,
4179 &mq_desc);
4180 DataMQ data_mq(mq_desc);
4181
4182 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
4183 if (is_codec_config_valid) {
4184 EXPECT_TRUE(data_mq.isValid());
4185 }
4186 EXPECT_TRUE(audio_provider_->endSession().isOk());
4187 }
4188 }
4189 }
4190 }
4191 }
4192
4193 /**
4194 * openProvider LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH
4195 */
4196 class BluetoothAudioProviderLeAudioBroadcastHardwareAidl
4197 : public BluetoothAudioProviderFactoryAidl {
4198 public:
SetUp()4199 virtual void SetUp() override {
4200 BluetoothAudioProviderFactoryAidl::SetUp();
4201 GetProviderCapabilitiesHelper(
4202 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
4203 GetProviderInfoHelper(
4204 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
4205 OpenProviderHelper(
4206 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
4207 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
4208 audio_provider_ != nullptr);
4209 }
4210
TearDown()4211 virtual void TearDown() override {
4212 audio_port_ = nullptr;
4213 audio_provider_ = nullptr;
4214 BluetoothAudioProviderFactoryAidl::TearDown();
4215 }
4216
IsBroadcastOffloadSupported()4217 bool IsBroadcastOffloadSupported() {
4218 for (auto& capability : temp_provider_capabilities_) {
4219 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
4220 continue;
4221 }
4222 auto& le_audio_capability =
4223 capability.get<AudioCapabilities::leAudioCapabilities>();
4224 if (le_audio_capability.broadcastCapability.codecType !=
4225 CodecType::UNKNOWN)
4226 return true;
4227 }
4228 return false;
4229 }
4230
IsBroadcastOffloadProviderInfoSupported()4231 bool IsBroadcastOffloadProviderInfoSupported() {
4232 if (!temp_provider_info_.has_value()) return false;
4233 if (temp_provider_info_.value().codecInfos.empty()) return false;
4234 // Check if all codec info is of LeAudio type
4235 for (auto& codec_info : temp_provider_info_.value().codecInfos) {
4236 if (codec_info.transport.getTag() != CodecInfo::Transport::leAudio)
4237 return false;
4238 }
4239 return true;
4240 }
4241
GetBroadcastLc3SupportedListFromProviderInfo()4242 std::vector<Lc3Configuration> GetBroadcastLc3SupportedListFromProviderInfo() {
4243 std::vector<Lc3Configuration> le_audio_codec_configs;
4244 for (auto& codec_info : temp_provider_info_.value().codecInfos) {
4245 // Only gets LC3 codec information
4246 if (codec_info.id != CodecId::Core::LC3) continue;
4247 // Combine those parameters into one list of Lc3Configuration
4248 auto& transport =
4249 codec_info.transport.get<CodecInfo::Transport::Tag::leAudio>();
4250 for (int32_t samplingFrequencyHz : transport.samplingFrequencyHz) {
4251 for (int32_t frameDurationUs : transport.frameDurationUs) {
4252 for (int32_t octetsPerFrame : transport.bitdepth) {
4253 Lc3Configuration lc3_config = {
4254 .samplingFrequencyHz = samplingFrequencyHz,
4255 .frameDurationUs = frameDurationUs,
4256 .octetsPerFrame = octetsPerFrame,
4257 };
4258 le_audio_codec_configs.push_back(lc3_config);
4259 }
4260 }
4261 }
4262 }
4263
4264 return le_audio_codec_configs;
4265 }
4266
GetAudioContext(int32_t bitmask)4267 AudioContext GetAudioContext(int32_t bitmask) {
4268 AudioContext media_audio_context;
4269 media_audio_context.bitmask = bitmask;
4270 return media_audio_context;
4271 }
4272
4273 std::optional<CodecSpecificConfigurationLtv::SamplingFrequency>
GetBisSampleFreq(const LeAudioBisConfiguration & bis_conf)4274 GetBisSampleFreq(const LeAudioBisConfiguration& bis_conf) {
4275 auto sample_freq_ltv = GetConfigurationLtv(
4276 bis_conf.codecConfiguration,
4277 CodecSpecificConfigurationLtv::Tag::samplingFrequency);
4278 if (!sample_freq_ltv) {
4279 return std::nullopt;
4280 }
4281 return (*sample_freq_ltv)
4282 .get<CodecSpecificConfigurationLtv::samplingFrequency>();
4283 }
4284
4285 std::vector<CodecSpecificConfigurationLtv::SamplingFrequency>
GetSubgroupSampleFreqs(const LeAudioBroadcastSubgroupConfiguration & subgroup_conf)4286 GetSubgroupSampleFreqs(
4287 const LeAudioBroadcastSubgroupConfiguration& subgroup_conf) {
4288 std::vector<CodecSpecificConfigurationLtv::SamplingFrequency> result = {};
4289
4290 for (const auto& bis_conf : subgroup_conf.bisConfigurations) {
4291 auto sample_freq = GetBisSampleFreq(bis_conf.bisConfiguration);
4292 if (sample_freq) {
4293 result.push_back(*sample_freq);
4294 }
4295 }
4296 return result;
4297 }
4298
VerifyBroadcastConfiguration(const LeAudioBroadcastConfigurationRequirement & requirements,const LeAudioBroadcastConfigurationSetting & configuration,std::vector<CodecSpecificConfigurationLtv::SamplingFrequency> expectedSampleFreqs={})4299 void VerifyBroadcastConfiguration(
4300 const LeAudioBroadcastConfigurationRequirement& requirements,
4301 const LeAudioBroadcastConfigurationSetting& configuration,
4302 std::vector<CodecSpecificConfigurationLtv::SamplingFrequency>
4303 expectedSampleFreqs = {}) {
4304 std::vector<CodecSpecificConfigurationLtv::SamplingFrequency> sampleFreqs =
4305 {};
4306
4307 int number_of_requested_bises = 0;
4308 for (const auto& subgroup_req :
4309 requirements.subgroupConfigurationRequirements) {
4310 number_of_requested_bises += subgroup_req.bisNumPerSubgroup;
4311 }
4312
4313 if (!expectedSampleFreqs.empty()) {
4314 for (const auto& subgroup_conf : configuration.subgroupsConfigurations) {
4315 auto result = GetSubgroupSampleFreqs(subgroup_conf);
4316 sampleFreqs.insert(sampleFreqs.end(), result.begin(), result.end());
4317 }
4318 }
4319
4320 ASSERT_EQ(number_of_requested_bises, configuration.numBis);
4321 ASSERT_EQ(requirements.subgroupConfigurationRequirements.size(),
4322 configuration.subgroupsConfigurations.size());
4323
4324 if (expectedSampleFreqs.empty()) {
4325 return;
4326 }
4327
4328 std::sort(sampleFreqs.begin(), sampleFreqs.end());
4329 std::sort(expectedSampleFreqs.begin(), expectedSampleFreqs.end());
4330
4331 ASSERT_EQ(sampleFreqs, expectedSampleFreqs);
4332 }
4333
GetDefaultBroadcastSinkCapability()4334 LeAudioDeviceCapabilities GetDefaultBroadcastSinkCapability() {
4335 // Create a capability
4336 LeAudioDeviceCapabilities capability;
4337
4338 capability.codecId = CodecId::Core::LC3;
4339
4340 auto pref_context_metadata = MetadataLtv::PreferredAudioContexts();
4341 pref_context_metadata.values =
4342 GetAudioContext(AudioContext::MEDIA | AudioContext::CONVERSATIONAL |
4343 AudioContext::GAME);
4344 capability.metadata = {pref_context_metadata};
4345
4346 auto sampling_rate =
4347 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies();
4348 sampling_rate.bitmask =
4349 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ48000 |
4350 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ24000 |
4351 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ16000;
4352 auto frame_duration =
4353 CodecSpecificCapabilitiesLtv::SupportedFrameDurations();
4354 frame_duration.bitmask =
4355 CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US7500 |
4356 CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US10000;
4357 auto octets = CodecSpecificCapabilitiesLtv::SupportedOctetsPerCodecFrame();
4358 octets.min = 0;
4359 octets.max = 120;
4360 auto frames = CodecSpecificCapabilitiesLtv::SupportedMaxCodecFramesPerSDU();
4361 frames.value = 2;
4362 capability.codecSpecificCapabilities = {sampling_rate, frame_duration,
4363 octets, frames};
4364 return capability;
4365 }
4366
GetBroadcastRequirement(bool standard_quality,bool high_quality)4367 LeAudioBroadcastConfigurationRequirement GetBroadcastRequirement(
4368 bool standard_quality, bool high_quality) {
4369 LeAudioBroadcastConfigurationRequirement requirement;
4370
4371 AudioContext media_audio_context;
4372 media_audio_context.bitmask = AudioContext::MEDIA;
4373
4374 LeAudioBroadcastSubgroupConfigurationRequirement
4375 standard_quality_requirement = {
4376 .audioContext = media_audio_context,
4377 .quality = IBluetoothAudioProvider::BroadcastQuality::STANDARD,
4378 .bisNumPerSubgroup = 2};
4379
4380 LeAudioBroadcastSubgroupConfigurationRequirement high_quality_requirement =
4381 {.audioContext = media_audio_context,
4382 .quality = IBluetoothAudioProvider::BroadcastQuality::HIGH,
4383 .bisNumPerSubgroup = 2};
4384
4385 if (standard_quality) {
4386 requirement.subgroupConfigurationRequirements.push_back(
4387 standard_quality_requirement);
4388 }
4389
4390 if (high_quality) {
4391 requirement.subgroupConfigurationRequirements.push_back(
4392 high_quality_requirement);
4393 }
4394 return requirement;
4395 }
4396
GetBroadcastLc3SupportedList(bool supported)4397 std::vector<Lc3Configuration> GetBroadcastLc3SupportedList(bool supported) {
4398 std::vector<Lc3Configuration> le_audio_codec_configs;
4399 if (!supported) {
4400 Lc3Configuration lc3_config{.pcmBitDepth = 0, .samplingFrequencyHz = 0};
4401 le_audio_codec_configs.push_back(lc3_config);
4402 return le_audio_codec_configs;
4403 }
4404
4405 // There might be more than one LeAudioCodecCapabilitiesSetting
4406 std::vector<Lc3Capabilities> lc3_capabilities;
4407 for (auto& capability : temp_provider_capabilities_) {
4408 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
4409 continue;
4410 }
4411 auto& le_audio_capability =
4412 capability.get<AudioCapabilities::leAudioCapabilities>();
4413 auto& broadcast_capability = le_audio_capability.broadcastCapability;
4414 if (broadcast_capability.codecType != CodecType::LC3) {
4415 continue;
4416 }
4417 auto& lc3_capability = broadcast_capability.leAudioCodecCapabilities.get<
4418 BroadcastCapability::LeAudioCodecCapabilities::lc3Capabilities>();
4419 for (int idx = 0; idx < lc3_capability->size(); idx++)
4420 lc3_capabilities.push_back(*lc3_capability->at(idx));
4421 }
4422
4423 // Combine those parameters into one list of LeAudioCodecConfiguration
4424 // This seems horrible, but usually each Lc3Capability only contains a
4425 // single Lc3Configuration, which means every array has a length of 1.
4426 for (auto& lc3_capability : lc3_capabilities) {
4427 for (int32_t samplingFrequencyHz : lc3_capability.samplingFrequencyHz) {
4428 for (int32_t frameDurationUs : lc3_capability.frameDurationUs) {
4429 for (int32_t octetsPerFrame : lc3_capability.octetsPerFrame) {
4430 Lc3Configuration lc3_config = {
4431 .samplingFrequencyHz = samplingFrequencyHz,
4432 .frameDurationUs = frameDurationUs,
4433 .octetsPerFrame = octetsPerFrame,
4434 };
4435 le_audio_codec_configs.push_back(lc3_config);
4436 }
4437 }
4438 }
4439 }
4440
4441 return le_audio_codec_configs;
4442 }
4443
4444 LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
4445 };
4446
4447 /**
4448 * Test whether each provider of type
4449 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
4450 * started and stopped
4451 */
TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,OpenLeAudioOutputHardwareProvider)4452 TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
4453 OpenLeAudioOutputHardwareProvider) {}
4454
4455 /**
4456 * Test whether each provider of type
4457 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
4458 * started and stopped with broadcast hardware encoding config taken from
4459 * provider info
4460 */
TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,StartAndEndLeAudioBroadcastSessionWithPossibleUnicastConfigFromProviderInfo)4461 TEST_P(
4462 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
4463 StartAndEndLeAudioBroadcastSessionWithPossibleUnicastConfigFromProviderInfo) {
4464 if (GetProviderFactoryInterfaceVersion() <
4465 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
4466 GTEST_SKIP();
4467 }
4468 if (!IsBroadcastOffloadProviderInfoSupported()) {
4469 return;
4470 }
4471
4472 auto lc3_codec_configs = GetBroadcastLc3SupportedListFromProviderInfo();
4473 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
4474 .codecType = CodecType::LC3,
4475 .streamMap = {},
4476 };
4477
4478 for (auto& lc3_config : lc3_codec_configs) {
4479 le_audio_broadcast_config.streamMap.resize(1);
4480 le_audio_broadcast_config.streamMap[0]
4481 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
4482 lc3_config);
4483 le_audio_broadcast_config.streamMap[0].streamHandle = 0x0;
4484 le_audio_broadcast_config.streamMap[0].pcmStreamId = 0x0;
4485 le_audio_broadcast_config.streamMap[0].audioChannelAllocation = 0x1 << 0;
4486
4487 DataMQDesc mq_desc;
4488 auto aidl_retval = audio_provider_->startSession(
4489 audio_port_, AudioConfiguration(le_audio_broadcast_config),
4490 latency_modes, &mq_desc);
4491
4492 ASSERT_TRUE(aidl_retval.isOk());
4493 EXPECT_TRUE(audio_provider_->endSession().isOk());
4494 }
4495 }
4496
TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,GetEmptyBroadcastConfigurationEmptyCapability)4497 TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
4498 GetEmptyBroadcastConfigurationEmptyCapability) {
4499 if (GetProviderFactoryInterfaceVersion() <
4500 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
4501 GTEST_SKIP();
4502 }
4503
4504 if (!IsBroadcastOffloadSupported()) {
4505 GTEST_SKIP();
4506 }
4507
4508 std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
4509 IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement
4510 empty_requirement;
4511
4512 IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting configuration;
4513
4514 // Check empty capability for source direction
4515 auto aidl_retval = audio_provider_->getLeAudioBroadcastConfiguration(
4516 empty_capability, empty_requirement, &configuration);
4517
4518 ASSERT_FALSE(aidl_retval.isOk());
4519 }
4520
TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,GetBroadcastConfigurationEmptyCapability)4521 TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
4522 GetBroadcastConfigurationEmptyCapability) {
4523 if (GetProviderFactoryInterfaceVersion() <
4524 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
4525 GTEST_SKIP();
4526 }
4527
4528 if (!IsBroadcastOffloadSupported()) {
4529 GTEST_SKIP();
4530 }
4531
4532 std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
4533 IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting configuration;
4534
4535 IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement
4536 one_subgroup_requirement =
4537 GetBroadcastRequirement(true /* standard*/, false /* high */);
4538
4539 // Check empty capability for source direction
4540 auto aidl_retval = audio_provider_->getLeAudioBroadcastConfiguration(
4541 empty_capability, one_subgroup_requirement, &configuration);
4542
4543 ASSERT_TRUE(aidl_retval.isOk());
4544 ASSERT_NE(configuration.numBis, 0);
4545 ASSERT_FALSE(configuration.subgroupsConfigurations.empty());
4546 VerifyBroadcastConfiguration(one_subgroup_requirement, configuration);
4547 }
4548
TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,GetBroadcastConfigurationNonEmptyCapability)4549 TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
4550 GetBroadcastConfigurationNonEmptyCapability) {
4551 if (GetProviderFactoryInterfaceVersion() <
4552 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
4553 GTEST_SKIP();
4554 }
4555
4556 if (!IsBroadcastOffloadSupported()) {
4557 GTEST_SKIP();
4558 }
4559
4560 std::vector<std::optional<LeAudioDeviceCapabilities>> capability = {
4561 GetDefaultBroadcastSinkCapability()};
4562
4563 IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement
4564 requirement =
4565 GetBroadcastRequirement(true /* standard*/, false /* high */);
4566
4567 IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting configuration;
4568
4569 // Check empty capability for source direction
4570 auto aidl_retval = audio_provider_->getLeAudioBroadcastConfiguration(
4571 capability, requirement, &configuration);
4572
4573 ASSERT_TRUE(aidl_retval.isOk());
4574 ASSERT_NE(configuration.numBis, 0);
4575 ASSERT_FALSE(configuration.subgroupsConfigurations.empty());
4576 VerifyBroadcastConfiguration(requirement, configuration);
4577 }
4578
4579 /**
4580 * Test whether each provider of type
4581 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
4582 * started and stopped with broadcast hardware encoding config
4583 */
TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,StartAndEndLeAudioBroadcastSessionWithPossibleBroadcastConfig)4584 TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
4585 StartAndEndLeAudioBroadcastSessionWithPossibleBroadcastConfig) {
4586 if (!IsBroadcastOffloadSupported()) {
4587 GTEST_SKIP();
4588 }
4589
4590 auto lc3_codec_configs = GetBroadcastLc3SupportedList(true /* supported */);
4591 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
4592 .codecType = CodecType::LC3,
4593 .streamMap = {},
4594 };
4595
4596 for (auto& lc3_config : lc3_codec_configs) {
4597 le_audio_broadcast_config.streamMap.resize(1);
4598 le_audio_broadcast_config.streamMap[0]
4599 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
4600 lc3_config);
4601 le_audio_broadcast_config.streamMap[0].streamHandle = 0x0;
4602 le_audio_broadcast_config.streamMap[0].pcmStreamId = 0x0;
4603 le_audio_broadcast_config.streamMap[0].audioChannelAllocation = 0x1 << 0;
4604
4605 DataMQDesc mq_desc;
4606 auto aidl_retval = audio_provider_->startSession(
4607 audio_port_, AudioConfiguration(le_audio_broadcast_config),
4608 latency_modes, &mq_desc);
4609
4610 ASSERT_TRUE(aidl_retval.isOk());
4611 EXPECT_TRUE(audio_provider_->endSession().isOk());
4612 }
4613 }
4614
4615 /**
4616 * Test whether each provider of type
4617 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
4618 * started and stopped with Broadcast hardware encoding config
4619 *
4620 * Disabled since offload codec checking is not ready
4621 */
TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,DISABLED_StartAndEndLeAudioBroadcastSessionWithInvalidAudioConfiguration)4622 TEST_P(
4623 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
4624 DISABLED_StartAndEndLeAudioBroadcastSessionWithInvalidAudioConfiguration) {
4625 if (!IsBroadcastOffloadSupported()) {
4626 GTEST_SKIP();
4627 }
4628
4629 auto lc3_codec_configs = GetBroadcastLc3SupportedList(false /* supported */);
4630 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
4631 .codecType = CodecType::LC3,
4632 .streamMap = {},
4633 };
4634
4635 for (auto& lc3_config : lc3_codec_configs) {
4636 le_audio_broadcast_config.streamMap[0]
4637 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
4638 lc3_config);
4639 DataMQDesc mq_desc;
4640 auto aidl_retval = audio_provider_->startSession(
4641 audio_port_, AudioConfiguration(le_audio_broadcast_config),
4642 latency_modes, &mq_desc);
4643
4644 // AIDL call should fail on invalid codec
4645 ASSERT_FALSE(aidl_retval.isOk());
4646 EXPECT_TRUE(audio_provider_->endSession().isOk());
4647 }
4648 }
4649
4650 /**
4651 * openProvider A2DP_SOFTWARE_DECODING_DATAPATH
4652 */
4653 class BluetoothAudioProviderA2dpDecodingSoftwareAidl
4654 : public BluetoothAudioProviderFactoryAidl {
4655 public:
SetUp()4656 virtual void SetUp() override {
4657 BluetoothAudioProviderFactoryAidl::SetUp();
4658 GetProviderCapabilitiesHelper(SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
4659 OpenProviderHelper(SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
4660 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
4661 audio_provider_ != nullptr);
4662 }
4663
TearDown()4664 virtual void TearDown() override {
4665 audio_port_ = nullptr;
4666 audio_provider_ = nullptr;
4667 BluetoothAudioProviderFactoryAidl::TearDown();
4668 }
4669 };
4670
4671 /**
4672 * Test whether we can open a provider of type
4673 */
TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,OpenA2dpDecodingSoftwareProvider)4674 TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,
4675 OpenA2dpDecodingSoftwareProvider) {}
4676
4677 /**
4678 * Test whether each provider of type
4679 * SessionType::A2DP_SOFTWARE_DECODING_DATAPATH can be started and stopped
4680 * with different PCM config
4681 */
TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,StartAndEndA2dpDecodingSoftwareSessionWithPossiblePcmConfig)4682 TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,
4683 StartAndEndA2dpDecodingSoftwareSessionWithPossiblePcmConfig) {
4684 for (auto sample_rate : a2dp_sample_rates) {
4685 for (auto bits_per_sample : a2dp_bits_per_samples) {
4686 for (auto channel_mode : a2dp_channel_modes) {
4687 PcmConfiguration pcm_config{
4688 .sampleRateHz = sample_rate,
4689 .channelMode = channel_mode,
4690 .bitsPerSample = bits_per_sample,
4691 };
4692 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
4693 DataMQDesc mq_desc;
4694 auto aidl_retval = audio_provider_->startSession(
4695 audio_port_, AudioConfiguration(pcm_config), latency_modes,
4696 &mq_desc);
4697 DataMQ data_mq(mq_desc);
4698
4699 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
4700 if (is_codec_config_valid) {
4701 EXPECT_TRUE(data_mq.isValid());
4702 }
4703 EXPECT_TRUE(audio_provider_->endSession().isOk());
4704 }
4705 }
4706 }
4707 }
4708
4709 /**
4710 * openProvider A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH
4711 */
4712 class BluetoothAudioProviderA2dpDecodingHardwareAidl
4713 : public BluetoothAudioProviderFactoryAidl {
4714 public:
SetUp()4715 virtual void SetUp() override {
4716 BluetoothAudioProviderFactoryAidl::SetUp();
4717 GetProviderCapabilitiesHelper(
4718 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
4719 OpenProviderHelper(SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
4720 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
4721 audio_provider_ != nullptr);
4722 }
4723
TearDown()4724 virtual void TearDown() override {
4725 audio_port_ = nullptr;
4726 audio_provider_ = nullptr;
4727 BluetoothAudioProviderFactoryAidl::TearDown();
4728 }
4729
IsOffloadSupported()4730 bool IsOffloadSupported() { return (temp_provider_capabilities_.size() > 0); }
4731 };
4732
4733 /**
4734 * Test whether we can open a provider of type
4735 */
TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,OpenA2dpDecodingHardwareProvider)4736 TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
4737 OpenA2dpDecodingHardwareProvider) {}
4738
4739 /**
4740 * Test whether each provider of type
4741 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
4742 * with SBC hardware encoding config
4743 */
TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,StartAndEndA2dpSbcDecodingHardwareSession)4744 TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
4745 StartAndEndA2dpSbcDecodingHardwareSession) {
4746 if (!IsOffloadSupported()) {
4747 GTEST_SKIP();
4748 }
4749
4750 CodecConfiguration codec_config = {
4751 .codecType = CodecType::SBC,
4752 .encodedAudioBitrate = 328000,
4753 .peerMtu = 1005,
4754 .isScmstEnabled = false,
4755 };
4756 auto sbc_codec_specifics = GetSbcCodecSpecificSupportedList(true);
4757
4758 for (auto& codec_specific : sbc_codec_specifics) {
4759 copy_codec_specific(codec_config.config, codec_specific);
4760 DataMQDesc mq_desc;
4761 auto aidl_retval = audio_provider_->startSession(
4762 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
4763
4764 ASSERT_TRUE(aidl_retval.isOk());
4765 EXPECT_TRUE(audio_provider_->endSession().isOk());
4766 }
4767 }
4768
4769 /**
4770 * Test whether each provider of type
4771 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
4772 * with AAC hardware encoding config
4773 */
TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,StartAndEndA2dpAacDecodingHardwareSession)4774 TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
4775 StartAndEndA2dpAacDecodingHardwareSession) {
4776 if (!IsOffloadSupported()) {
4777 GTEST_SKIP();
4778 }
4779
4780 CodecConfiguration codec_config = {
4781 .codecType = CodecType::AAC,
4782 .encodedAudioBitrate = 320000,
4783 .peerMtu = 1005,
4784 .isScmstEnabled = false,
4785 };
4786 auto aac_codec_specifics = GetAacCodecSpecificSupportedList(true);
4787
4788 for (auto& codec_specific : aac_codec_specifics) {
4789 copy_codec_specific(codec_config.config, codec_specific);
4790 DataMQDesc mq_desc;
4791 auto aidl_retval = audio_provider_->startSession(
4792 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
4793
4794 ASSERT_TRUE(aidl_retval.isOk());
4795 EXPECT_TRUE(audio_provider_->endSession().isOk());
4796 }
4797 }
4798
4799 /**
4800 * Test whether each provider of type
4801 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
4802 * with LDAC hardware encoding config
4803 */
TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,StartAndEndA2dpLdacDecodingHardwareSession)4804 TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
4805 StartAndEndA2dpLdacDecodingHardwareSession) {
4806 if (!IsOffloadSupported()) {
4807 GTEST_SKIP();
4808 }
4809
4810 CodecConfiguration codec_config = {
4811 .codecType = CodecType::LDAC,
4812 .encodedAudioBitrate = 990000,
4813 .peerMtu = 1005,
4814 .isScmstEnabled = false,
4815 };
4816 auto ldac_codec_specifics = GetLdacCodecSpecificSupportedList(true);
4817
4818 for (auto& codec_specific : ldac_codec_specifics) {
4819 copy_codec_specific(codec_config.config, codec_specific);
4820 DataMQDesc mq_desc;
4821 auto aidl_retval = audio_provider_->startSession(
4822 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
4823
4824 ASSERT_TRUE(aidl_retval.isOk());
4825 EXPECT_TRUE(audio_provider_->endSession().isOk());
4826 }
4827 }
4828
4829 /**
4830 * Test whether each provider of type
4831 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
4832 * with Opus hardware encoding config
4833 */
TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,StartAndEndA2dpOpusDecodingHardwareSession)4834 TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
4835 StartAndEndA2dpOpusDecodingHardwareSession) {
4836 if (!IsOffloadSupported()) {
4837 GTEST_SKIP();
4838 }
4839
4840 CodecConfiguration codec_config = {
4841 .codecType = CodecType::OPUS,
4842 .encodedAudioBitrate = 990000,
4843 .peerMtu = 1005,
4844 .isScmstEnabled = false,
4845 };
4846 auto opus_codec_specifics = GetOpusCodecSpecificSupportedList(true);
4847
4848 for (auto& codec_specific : opus_codec_specifics) {
4849 copy_codec_specific(codec_config.config, codec_specific);
4850 DataMQDesc mq_desc;
4851 auto aidl_retval = audio_provider_->startSession(
4852 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
4853
4854 ASSERT_TRUE(aidl_retval.isOk());
4855 EXPECT_TRUE(audio_provider_->endSession().isOk());
4856 }
4857 }
4858
4859 /**
4860 * Test whether each provider of type
4861 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
4862 * with AptX hardware encoding config
4863 */
TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,StartAndEndA2dpAptxDecodingHardwareSession)4864 TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
4865 StartAndEndA2dpAptxDecodingHardwareSession) {
4866 if (!IsOffloadSupported()) {
4867 GTEST_SKIP();
4868 }
4869
4870 for (auto codec_type : {CodecType::APTX, CodecType::APTX_HD}) {
4871 CodecConfiguration codec_config = {
4872 .codecType = codec_type,
4873 .encodedAudioBitrate =
4874 (codec_type == CodecType::APTX ? 352000 : 576000),
4875 .peerMtu = 1005,
4876 .isScmstEnabled = false,
4877 };
4878
4879 auto aptx_codec_specifics = GetAptxCodecSpecificSupportedList(
4880 (codec_type == CodecType::APTX_HD ? true : false), true);
4881
4882 for (auto& codec_specific : aptx_codec_specifics) {
4883 copy_codec_specific(codec_config.config, codec_specific);
4884 DataMQDesc mq_desc;
4885 auto aidl_retval = audio_provider_->startSession(
4886 audio_port_, AudioConfiguration(codec_config), latency_modes,
4887 &mq_desc);
4888
4889 ASSERT_TRUE(aidl_retval.isOk());
4890 EXPECT_TRUE(audio_provider_->endSession().isOk());
4891 }
4892 }
4893 }
4894
4895 /**
4896 * Test whether each provider of type
4897 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
4898 * with an invalid codec config
4899 */
TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,StartAndEndA2dpDecodingHardwareSessionInvalidCodecConfig)4900 TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
4901 StartAndEndA2dpDecodingHardwareSessionInvalidCodecConfig) {
4902 if (!IsOffloadSupported()) {
4903 GTEST_SKIP();
4904 }
4905 ASSERT_NE(audio_provider_, nullptr);
4906
4907 std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
4908 for (auto codec_type : ndk::enum_range<CodecType>()) {
4909 switch (codec_type) {
4910 case CodecType::SBC:
4911 codec_specifics = GetSbcCodecSpecificSupportedList(false);
4912 break;
4913 case CodecType::AAC:
4914 codec_specifics = GetAacCodecSpecificSupportedList(false);
4915 break;
4916 case CodecType::LDAC:
4917 codec_specifics = GetLdacCodecSpecificSupportedList(false);
4918 break;
4919 case CodecType::APTX:
4920 codec_specifics = GetAptxCodecSpecificSupportedList(false, false);
4921 break;
4922 case CodecType::APTX_HD:
4923 codec_specifics = GetAptxCodecSpecificSupportedList(true, false);
4924 break;
4925 case CodecType::OPUS:
4926 codec_specifics = GetOpusCodecSpecificSupportedList(false);
4927 continue;
4928 case CodecType::APTX_ADAPTIVE:
4929 case CodecType::APTX_ADAPTIVE_LE:
4930 case CodecType::APTX_ADAPTIVE_LEX:
4931 case CodecType::LC3:
4932 case CodecType::VENDOR:
4933 case CodecType::UNKNOWN:
4934 codec_specifics.clear();
4935 break;
4936 }
4937 if (codec_specifics.empty()) {
4938 continue;
4939 }
4940
4941 CodecConfiguration codec_config = {
4942 .codecType = codec_type,
4943 .encodedAudioBitrate = 328000,
4944 .peerMtu = 1005,
4945 .isScmstEnabled = false,
4946 };
4947 for (auto codec_specific : codec_specifics) {
4948 copy_codec_specific(codec_config.config, codec_specific);
4949 DataMQDesc mq_desc;
4950 auto aidl_retval = audio_provider_->startSession(
4951 audio_port_, AudioConfiguration(codec_config), latency_modes,
4952 &mq_desc);
4953
4954 // AIDL call should fail on invalid codec
4955 ASSERT_FALSE(aidl_retval.isOk());
4956 EXPECT_TRUE(audio_provider_->endSession().isOk());
4957 }
4958 }
4959 }
4960
4961 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
4962 BluetoothAudioProviderFactoryAidl);
4963 INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderFactoryAidl,
4964 testing::ValuesIn(android::getAidlHalInstanceNames(
4965 IBluetoothAudioProviderFactory::descriptor)),
4966 android::PrintInstanceNameToString);
4967
4968 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothAudioProviderAidl);
4969 INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderAidl,
4970 testing::ValuesIn(android::getAidlHalInstanceNames(
4971 IBluetoothAudioProviderFactory::descriptor)),
4972 android::PrintInstanceNameToString);
4973
4974 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
4975 BluetoothAudioProviderA2dpEncodingSoftwareAidl);
4976 INSTANTIATE_TEST_SUITE_P(PerInstance,
4977 BluetoothAudioProviderA2dpEncodingSoftwareAidl,
4978 testing::ValuesIn(android::getAidlHalInstanceNames(
4979 IBluetoothAudioProviderFactory::descriptor)),
4980 android::PrintInstanceNameToString);
4981
4982 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
4983 BluetoothAudioProviderA2dpEncodingHardwareAidl);
4984 INSTANTIATE_TEST_SUITE_P(PerInstance,
4985 BluetoothAudioProviderA2dpEncodingHardwareAidl,
4986 testing::ValuesIn(android::getAidlHalInstanceNames(
4987 IBluetoothAudioProviderFactory::descriptor)),
4988 android::PrintInstanceNameToString);
4989
4990 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
4991 BluetoothAudioProviderHearingAidSoftwareAidl);
4992 INSTANTIATE_TEST_SUITE_P(PerInstance,
4993 BluetoothAudioProviderHearingAidSoftwareAidl,
4994 testing::ValuesIn(android::getAidlHalInstanceNames(
4995 IBluetoothAudioProviderFactory::descriptor)),
4996 android::PrintInstanceNameToString);
4997
4998 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
4999 BluetoothAudioProviderLeAudioOutputSoftwareAidl);
5000 INSTANTIATE_TEST_SUITE_P(PerInstance,
5001 BluetoothAudioProviderLeAudioOutputSoftwareAidl,
5002 testing::ValuesIn(android::getAidlHalInstanceNames(
5003 IBluetoothAudioProviderFactory::descriptor)),
5004 android::PrintInstanceNameToString);
5005
5006 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
5007 BluetoothAudioProviderLeAudioInputSoftwareAidl);
5008 INSTANTIATE_TEST_SUITE_P(PerInstance,
5009 BluetoothAudioProviderLeAudioInputSoftwareAidl,
5010 testing::ValuesIn(android::getAidlHalInstanceNames(
5011 IBluetoothAudioProviderFactory::descriptor)),
5012 android::PrintInstanceNameToString);
5013
5014 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
5015 BluetoothAudioProviderLeAudioOutputHardwareAidl);
5016 INSTANTIATE_TEST_SUITE_P(PerInstance,
5017 BluetoothAudioProviderLeAudioOutputHardwareAidl,
5018 testing::ValuesIn(android::getAidlHalInstanceNames(
5019 IBluetoothAudioProviderFactory::descriptor)),
5020 android::PrintInstanceNameToString);
5021
5022 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
5023 BluetoothAudioProviderLeAudioInputHardwareAidl);
5024 INSTANTIATE_TEST_SUITE_P(PerInstance,
5025 BluetoothAudioProviderLeAudioInputHardwareAidl,
5026 testing::ValuesIn(android::getAidlHalInstanceNames(
5027 IBluetoothAudioProviderFactory::descriptor)),
5028 android::PrintInstanceNameToString);
5029
5030 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
5031 BluetoothAudioProviderLeAudioBroadcastSoftwareAidl);
5032 INSTANTIATE_TEST_SUITE_P(PerInstance,
5033 BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
5034 testing::ValuesIn(android::getAidlHalInstanceNames(
5035 IBluetoothAudioProviderFactory::descriptor)),
5036 android::PrintInstanceNameToString);
5037
5038 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
5039 BluetoothAudioProviderLeAudioBroadcastHardwareAidl);
5040 INSTANTIATE_TEST_SUITE_P(PerInstance,
5041 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
5042 testing::ValuesIn(android::getAidlHalInstanceNames(
5043 IBluetoothAudioProviderFactory::descriptor)),
5044 android::PrintInstanceNameToString);
5045
5046 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
5047 BluetoothAudioProviderA2dpDecodingSoftwareAidl);
5048 INSTANTIATE_TEST_SUITE_P(PerInstance,
5049 BluetoothAudioProviderA2dpDecodingSoftwareAidl,
5050 testing::ValuesIn(android::getAidlHalInstanceNames(
5051 IBluetoothAudioProviderFactory::descriptor)),
5052 android::PrintInstanceNameToString);
5053
5054 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
5055 BluetoothAudioProviderA2dpDecodingHardwareAidl);
5056 INSTANTIATE_TEST_SUITE_P(PerInstance,
5057 BluetoothAudioProviderA2dpDecodingHardwareAidl,
5058 testing::ValuesIn(android::getAidlHalInstanceNames(
5059 IBluetoothAudioProviderFactory::descriptor)),
5060 android::PrintInstanceNameToString);
5061
5062 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
5063 BluetoothAudioProviderHfpHardwareAidl);
5064 INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderHfpHardwareAidl,
5065 testing::ValuesIn(android::getAidlHalInstanceNames(
5066 IBluetoothAudioProviderFactory::descriptor)),
5067 android::PrintInstanceNameToString);
5068
5069 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
5070 BluetoothAudioProviderHfpSoftwareDecodingAidl);
5071 INSTANTIATE_TEST_SUITE_P(PerInstance,
5072 BluetoothAudioProviderHfpSoftwareDecodingAidl,
5073 testing::ValuesIn(android::getAidlHalInstanceNames(
5074 IBluetoothAudioProviderFactory::descriptor)),
5075 android::PrintInstanceNameToString);
5076
5077 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
5078 BluetoothAudioProviderHfpSoftwareEncodingAidl);
5079 INSTANTIATE_TEST_SUITE_P(PerInstance,
5080 BluetoothAudioProviderHfpSoftwareEncodingAidl,
5081 testing::ValuesIn(android::getAidlHalInstanceNames(
5082 IBluetoothAudioProviderFactory::descriptor)),
5083 android::PrintInstanceNameToString);
5084
main(int argc,char ** argv)5085 int main(int argc, char** argv) {
5086 ::testing::InitGoogleTest(&argc, argv);
5087 ABinderProcess_setThreadPoolMaxThreadCount(1);
5088 ABinderProcess_startThreadPool();
5089 return RUN_ALL_TESTS();
5090 }
5091