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