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::AacCapabilities;
37 using aidl::android::hardware::bluetooth::audio::AacConfiguration;
38 using aidl::android::hardware::bluetooth::audio::AptxCapabilities;
39 using aidl::android::hardware::bluetooth::audio::AptxConfiguration;
40 using aidl::android::hardware::bluetooth::audio::AudioCapabilities;
41 using aidl::android::hardware::bluetooth::audio::AudioConfiguration;
42 using aidl::android::hardware::bluetooth::audio::BnBluetoothAudioPort;
43 using aidl::android::hardware::bluetooth::audio::BroadcastCapability;
44 using aidl::android::hardware::bluetooth::audio::ChannelMode;
45 using aidl::android::hardware::bluetooth::audio::CodecCapabilities;
46 using aidl::android::hardware::bluetooth::audio::CodecConfiguration;
47 using aidl::android::hardware::bluetooth::audio::CodecType;
48 using aidl::android::hardware::bluetooth::audio::IBluetoothAudioPort;
49 using aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider;
50 using aidl::android::hardware::bluetooth::audio::IBluetoothAudioProviderFactory;
51 using aidl::android::hardware::bluetooth::audio::LatencyMode;
52 using aidl::android::hardware::bluetooth::audio::Lc3Capabilities;
53 using aidl::android::hardware::bluetooth::audio::Lc3Configuration;
54 using aidl::android::hardware::bluetooth::audio::LdacCapabilities;
55 using aidl::android::hardware::bluetooth::audio::LdacConfiguration;
56 using aidl::android::hardware::bluetooth::audio::LeAudioBroadcastConfiguration;
57 using aidl::android::hardware::bluetooth::audio::
58 LeAudioCodecCapabilitiesSetting;
59 using aidl::android::hardware::bluetooth::audio::LeAudioCodecConfiguration;
60 using aidl::android::hardware::bluetooth::audio::LeAudioConfiguration;
61 using aidl::android::hardware::bluetooth::audio::OpusCapabilities;
62 using aidl::android::hardware::bluetooth::audio::OpusConfiguration;
63 using aidl::android::hardware::bluetooth::audio::PcmConfiguration;
64 using aidl::android::hardware::bluetooth::audio::PresentationPosition;
65 using aidl::android::hardware::bluetooth::audio::SbcAllocMethod;
66 using aidl::android::hardware::bluetooth::audio::SbcCapabilities;
67 using aidl::android::hardware::bluetooth::audio::SbcChannelMode;
68 using aidl::android::hardware::bluetooth::audio::SbcConfiguration;
69 using aidl::android::hardware::bluetooth::audio::SessionType;
70 using aidl::android::hardware::bluetooth::audio::UnicastCapability;
71 using aidl::android::hardware::common::fmq::MQDescriptor;
72 using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
73 using android::AidlMessageQueue;
74 using android::ProcessState;
75 using android::String16;
76 using ndk::ScopedAStatus;
77 using ndk::SpAIBinder;
78
79 using MqDataType = int8_t;
80 using MqDataMode = SynchronizedReadWrite;
81 using DataMQ = AidlMessageQueue<MqDataType, MqDataMode>;
82 using DataMQDesc = MQDescriptor<MqDataType, MqDataMode>;
83
84 // Constants
85
86 static constexpr int32_t a2dp_sample_rates[] = {0, 44100, 48000, 88200, 96000};
87 static constexpr int8_t a2dp_bits_per_samples[] = {0, 16, 24, 32};
88 static constexpr ChannelMode a2dp_channel_modes[] = {
89 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
90 static constexpr CodecType a2dp_codec_types[] = {
91 CodecType::UNKNOWN, CodecType::SBC, CodecType::AAC,
92 CodecType::APTX, CodecType::APTX_HD, CodecType::LDAC,
93 CodecType::LC3, CodecType::APTX_ADAPTIVE};
94 static std::vector<LatencyMode> latency_modes = {LatencyMode::FREE};
95 // Helpers
96
97 template <typename T>
98 struct identity {
99 typedef T type;
100 };
101
102 template <class T>
contained_in_vector(const std::vector<T> & vector,const typename identity<T>::type & target)103 bool contained_in_vector(const std::vector<T>& vector,
104 const typename identity<T>::type& target) {
105 return std::find(vector.begin(), vector.end(), target) != vector.end();
106 }
107
copy_codec_specific(CodecConfiguration::CodecSpecific & dst,const CodecConfiguration::CodecSpecific & src)108 void copy_codec_specific(CodecConfiguration::CodecSpecific& dst,
109 const CodecConfiguration::CodecSpecific& src) {
110 switch (src.getTag()) {
111 case CodecConfiguration::CodecSpecific::sbcConfig:
112 dst.set<CodecConfiguration::CodecSpecific::sbcConfig>(
113 src.get<CodecConfiguration::CodecSpecific::sbcConfig>());
114 break;
115 case CodecConfiguration::CodecSpecific::aacConfig:
116 dst.set<CodecConfiguration::CodecSpecific::aacConfig>(
117 src.get<CodecConfiguration::CodecSpecific::aacConfig>());
118 break;
119 case CodecConfiguration::CodecSpecific::ldacConfig:
120 dst.set<CodecConfiguration::CodecSpecific::ldacConfig>(
121 src.get<CodecConfiguration::CodecSpecific::ldacConfig>());
122 break;
123 case CodecConfiguration::CodecSpecific::aptxConfig:
124 dst.set<CodecConfiguration::CodecSpecific::aptxConfig>(
125 src.get<CodecConfiguration::CodecSpecific::aptxConfig>());
126 break;
127 case CodecConfiguration::CodecSpecific::opusConfig:
128 dst.set<CodecConfiguration::CodecSpecific::opusConfig>(
129 src.get<CodecConfiguration::CodecSpecific::opusConfig>());
130 break;
131 case CodecConfiguration::CodecSpecific::aptxAdaptiveConfig:
132 dst.set<CodecConfiguration::CodecSpecific::aptxAdaptiveConfig>(
133 src.get<CodecConfiguration::CodecSpecific::aptxAdaptiveConfig>());
134 break;
135 default:
136 break;
137 }
138 }
139
140 class BluetoothAudioPort : public BnBluetoothAudioPort {
141 public:
BluetoothAudioPort()142 BluetoothAudioPort() {}
143
startStream(bool)144 ndk::ScopedAStatus startStream(bool) { return ScopedAStatus::ok(); }
145
suspendStream()146 ndk::ScopedAStatus suspendStream() { return ScopedAStatus::ok(); }
147
stopStream()148 ndk::ScopedAStatus stopStream() { return ScopedAStatus::ok(); }
149
getPresentationPosition(PresentationPosition *)150 ndk::ScopedAStatus getPresentationPosition(PresentationPosition*) {
151 return ScopedAStatus::ok();
152 }
153
updateSourceMetadata(const SourceMetadata &)154 ndk::ScopedAStatus updateSourceMetadata(const SourceMetadata&) {
155 return ScopedAStatus::ok();
156 }
157
updateSinkMetadata(const SinkMetadata &)158 ndk::ScopedAStatus updateSinkMetadata(const SinkMetadata&) {
159 return ScopedAStatus::ok();
160 }
161
setLatencyMode(const LatencyMode)162 ndk::ScopedAStatus setLatencyMode(const LatencyMode) {
163 return ScopedAStatus::ok();
164 }
165
setCodecType(const CodecType)166 ndk::ScopedAStatus setCodecType(const CodecType) {
167 return ScopedAStatus::ok();
168 }
169
170 protected:
171 virtual ~BluetoothAudioPort() = default;
172 };
173
174 class BluetoothAudioProviderFactoryAidl
175 : public testing::TestWithParam<std::string> {
176 public:
SetUp()177 virtual void SetUp() override {
178 provider_factory_ = IBluetoothAudioProviderFactory::fromBinder(
179 SpAIBinder(AServiceManager_getService(GetParam().c_str())));
180 audio_provider_ = nullptr;
181 ASSERT_NE(provider_factory_, nullptr);
182 }
183
TearDown()184 virtual void TearDown() override { provider_factory_ = nullptr; }
185
GetProviderCapabilitiesHelper(const SessionType & session_type)186 void GetProviderCapabilitiesHelper(const SessionType& session_type) {
187 temp_provider_capabilities_.clear();
188 auto aidl_retval = provider_factory_->getProviderCapabilities(
189 session_type, &temp_provider_capabilities_);
190 // AIDL calls should not be failed and callback has to be executed
191 ASSERT_TRUE(aidl_retval.isOk());
192 switch (session_type) {
193 case SessionType::UNKNOWN: {
194 ASSERT_TRUE(temp_provider_capabilities_.empty());
195 } break;
196 case SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH:
197 case SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH:
198 case SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH:
199 case SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH:
200 case SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH: {
201 // All software paths are mandatory and must have exact 1
202 // "PcmParameters"
203 ASSERT_EQ(temp_provider_capabilities_.size(), 1);
204 ASSERT_EQ(temp_provider_capabilities_[0].getTag(),
205 AudioCapabilities::pcmCapabilities);
206 } break;
207 case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
208 case SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH: {
209 std::unordered_set<CodecType> codec_types;
210 // empty capability means offload is unsupported
211 for (auto& audio_capability : temp_provider_capabilities_) {
212 ASSERT_EQ(audio_capability.getTag(),
213 AudioCapabilities::a2dpCapabilities);
214 const auto& codec_capabilities =
215 audio_capability.get<AudioCapabilities::a2dpCapabilities>();
216 // Every codec can present once at most
217 ASSERT_EQ(codec_types.count(codec_capabilities.codecType), 0);
218 switch (codec_capabilities.codecType) {
219 case CodecType::SBC:
220 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
221 CodecCapabilities::Capabilities::sbcCapabilities);
222 break;
223 case CodecType::AAC:
224 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
225 CodecCapabilities::Capabilities::aacCapabilities);
226 break;
227 case CodecType::APTX:
228 case CodecType::APTX_HD:
229 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
230 CodecCapabilities::Capabilities::aptxCapabilities);
231 break;
232 case CodecType::LDAC:
233 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
234 CodecCapabilities::Capabilities::ldacCapabilities);
235 break;
236 case CodecType::OPUS:
237 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
238 CodecCapabilities::Capabilities::opusCapabilities);
239 break;
240 case CodecType::APTX_ADAPTIVE:
241 case CodecType::LC3:
242 case CodecType::VENDOR:
243 case CodecType::UNKNOWN:
244 break;
245 }
246 codec_types.insert(codec_capabilities.codecType);
247 }
248 } break;
249 case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
250 case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
251 case SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH: {
252 // empty capability means offload is unsupported since capabilities are
253 // not hardcoded
254 for (auto audio_capability : temp_provider_capabilities_) {
255 ASSERT_EQ(audio_capability.getTag(),
256 AudioCapabilities::leAudioCapabilities);
257 }
258 } break;
259 case SessionType::A2DP_SOFTWARE_DECODING_DATAPATH: {
260 if (!temp_provider_capabilities_.empty()) {
261 ASSERT_EQ(temp_provider_capabilities_.size(), 1);
262 ASSERT_EQ(temp_provider_capabilities_[0].getTag(),
263 AudioCapabilities::pcmCapabilities);
264 }
265 } break;
266 default: {
267 ASSERT_TRUE(temp_provider_capabilities_.empty());
268 }
269 }
270 }
271
272 /***
273 * This helps to open the specified provider and check the openProvider()
274 * has corruct return values. BUT, to keep it simple, it does not consider
275 * the capability, and please do so at the SetUp of each session's test.
276 ***/
OpenProviderHelper(const SessionType & session_type)277 void OpenProviderHelper(const SessionType& session_type) {
278 auto aidl_retval =
279 provider_factory_->openProvider(session_type, &audio_provider_);
280 if (aidl_retval.isOk()) {
281 ASSERT_NE(session_type, SessionType::UNKNOWN);
282 ASSERT_NE(audio_provider_, nullptr);
283 audio_port_ = ndk::SharedRefBase::make<BluetoothAudioPort>();
284 } else {
285 // optional session type
286 ASSERT_TRUE(
287 session_type == SessionType::UNKNOWN ||
288 session_type ==
289 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
290 session_type ==
291 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
292 session_type ==
293 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
294 session_type ==
295 SessionType::
296 LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
297 session_type ==
298 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
299 session_type == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
300 ASSERT_EQ(audio_provider_, nullptr);
301 }
302 }
303
GetA2dpOffloadCapabilityHelper(const CodecType & codec_type)304 void GetA2dpOffloadCapabilityHelper(const CodecType& codec_type) {
305 temp_codec_capabilities_ = nullptr;
306 for (auto& codec_capability : temp_provider_capabilities_) {
307 auto& a2dp_capabilities =
308 codec_capability.get<AudioCapabilities::a2dpCapabilities>();
309 if (a2dp_capabilities.codecType != codec_type) {
310 continue;
311 }
312 temp_codec_capabilities_ = &a2dp_capabilities;
313 }
314 }
315
316 std::vector<CodecConfiguration::CodecSpecific>
GetSbcCodecSpecificSupportedList(bool supported)317 GetSbcCodecSpecificSupportedList(bool supported) {
318 std::vector<CodecConfiguration::CodecSpecific> sbc_codec_specifics;
319 if (!supported) {
320 SbcConfiguration sbc_config{.sampleRateHz = 0, .bitsPerSample = 0};
321 sbc_codec_specifics.push_back(
322 CodecConfiguration::CodecSpecific(sbc_config));
323 return sbc_codec_specifics;
324 }
325 GetA2dpOffloadCapabilityHelper(CodecType::SBC);
326 if (temp_codec_capabilities_ == nullptr ||
327 temp_codec_capabilities_->codecType != CodecType::SBC) {
328 return sbc_codec_specifics;
329 }
330 // parse the capability
331 auto& sbc_capability =
332 temp_codec_capabilities_->capabilities
333 .get<CodecCapabilities::Capabilities::sbcCapabilities>();
334 if (sbc_capability.minBitpool > sbc_capability.maxBitpool) {
335 return sbc_codec_specifics;
336 }
337
338 // combine those parameters into one list of
339 // CodecConfiguration::CodecSpecific
340 for (int32_t sample_rate : sbc_capability.sampleRateHz) {
341 for (int8_t block_length : sbc_capability.blockLength) {
342 for (int8_t num_subbands : sbc_capability.numSubbands) {
343 for (int8_t bits_per_sample : sbc_capability.bitsPerSample) {
344 for (auto channel_mode : sbc_capability.channelMode) {
345 for (auto alloc_method : sbc_capability.allocMethod) {
346 SbcConfiguration sbc_data = {
347 .sampleRateHz = sample_rate,
348 .channelMode = channel_mode,
349 .blockLength = block_length,
350 .numSubbands = num_subbands,
351 .allocMethod = alloc_method,
352 .bitsPerSample = bits_per_sample,
353 .minBitpool = sbc_capability.minBitpool,
354 .maxBitpool = sbc_capability.maxBitpool};
355 sbc_codec_specifics.push_back(
356 CodecConfiguration::CodecSpecific(sbc_data));
357 }
358 }
359 }
360 }
361 }
362 }
363 return sbc_codec_specifics;
364 }
365
366 std::vector<CodecConfiguration::CodecSpecific>
GetAacCodecSpecificSupportedList(bool supported)367 GetAacCodecSpecificSupportedList(bool supported) {
368 std::vector<CodecConfiguration::CodecSpecific> aac_codec_specifics;
369 if (!supported) {
370 AacConfiguration aac_config{.sampleRateHz = 0, .bitsPerSample = 0};
371 aac_codec_specifics.push_back(
372 CodecConfiguration::CodecSpecific(aac_config));
373 return aac_codec_specifics;
374 }
375 GetA2dpOffloadCapabilityHelper(CodecType::AAC);
376 if (temp_codec_capabilities_ == nullptr ||
377 temp_codec_capabilities_->codecType != CodecType::AAC) {
378 return aac_codec_specifics;
379 }
380 // parse the capability
381 auto& aac_capability =
382 temp_codec_capabilities_->capabilities
383 .get<CodecCapabilities::Capabilities::aacCapabilities>();
384
385 std::vector<bool> variable_bit_rate_enableds = {false};
386 if (aac_capability.variableBitRateSupported) {
387 variable_bit_rate_enableds.push_back(true);
388 }
389
390 // combine those parameters into one list of
391 // CodecConfiguration::CodecSpecific
392 for (auto object_type : aac_capability.objectType) {
393 for (int32_t sample_rate : aac_capability.sampleRateHz) {
394 for (auto channel_mode : aac_capability.channelMode) {
395 for (int8_t bits_per_sample : aac_capability.bitsPerSample) {
396 for (auto variable_bit_rate_enabled : variable_bit_rate_enableds) {
397 AacConfiguration aac_data{
398 .objectType = object_type,
399 .sampleRateHz = sample_rate,
400 .channelMode = channel_mode,
401 .variableBitRateEnabled = variable_bit_rate_enabled,
402 .bitsPerSample = bits_per_sample};
403 aac_codec_specifics.push_back(
404 CodecConfiguration::CodecSpecific(aac_data));
405 }
406 }
407 }
408 }
409 }
410 return aac_codec_specifics;
411 }
412
413 std::vector<CodecConfiguration::CodecSpecific>
GetLdacCodecSpecificSupportedList(bool supported)414 GetLdacCodecSpecificSupportedList(bool supported) {
415 std::vector<CodecConfiguration::CodecSpecific> ldac_codec_specifics;
416 if (!supported) {
417 LdacConfiguration ldac_config{.sampleRateHz = 0, .bitsPerSample = 0};
418 ldac_codec_specifics.push_back(
419 CodecConfiguration::CodecSpecific(ldac_config));
420 return ldac_codec_specifics;
421 }
422 GetA2dpOffloadCapabilityHelper(CodecType::LDAC);
423 if (temp_codec_capabilities_ == nullptr ||
424 temp_codec_capabilities_->codecType != CodecType::LDAC) {
425 return ldac_codec_specifics;
426 }
427 // parse the capability
428 auto& ldac_capability =
429 temp_codec_capabilities_->capabilities
430 .get<CodecCapabilities::Capabilities::ldacCapabilities>();
431
432 // combine those parameters into one list of
433 // CodecConfiguration::CodecSpecific
434 for (int32_t sample_rate : ldac_capability.sampleRateHz) {
435 for (int8_t bits_per_sample : ldac_capability.bitsPerSample) {
436 for (auto channel_mode : ldac_capability.channelMode) {
437 for (auto quality_index : ldac_capability.qualityIndex) {
438 LdacConfiguration ldac_data{.sampleRateHz = sample_rate,
439 .channelMode = channel_mode,
440 .qualityIndex = quality_index,
441 .bitsPerSample = bits_per_sample};
442 ldac_codec_specifics.push_back(
443 CodecConfiguration::CodecSpecific(ldac_data));
444 }
445 }
446 }
447 }
448 return ldac_codec_specifics;
449 }
450
451 std::vector<CodecConfiguration::CodecSpecific>
GetAptxCodecSpecificSupportedList(bool is_hd,bool supported)452 GetAptxCodecSpecificSupportedList(bool is_hd, bool supported) {
453 std::vector<CodecConfiguration::CodecSpecific> aptx_codec_specifics;
454 if (!supported) {
455 AptxConfiguration aptx_config{.sampleRateHz = 0, .bitsPerSample = 0};
456 aptx_codec_specifics.push_back(
457 CodecConfiguration::CodecSpecific(aptx_config));
458 return aptx_codec_specifics;
459 }
460 GetA2dpOffloadCapabilityHelper(
461 (is_hd ? CodecType::APTX_HD : CodecType::APTX));
462 if (temp_codec_capabilities_ == nullptr) {
463 return aptx_codec_specifics;
464 }
465 if ((is_hd && temp_codec_capabilities_->codecType != CodecType::APTX_HD) ||
466 (!is_hd && temp_codec_capabilities_->codecType != CodecType::APTX)) {
467 return aptx_codec_specifics;
468 }
469
470 // parse the capability
471 auto& aptx_capability =
472 temp_codec_capabilities_->capabilities
473 .get<CodecCapabilities::Capabilities::aptxCapabilities>();
474
475 // combine those parameters into one list of
476 // CodecConfiguration::CodecSpecific
477 for (int8_t bits_per_sample : aptx_capability.bitsPerSample) {
478 for (int32_t sample_rate : aptx_capability.sampleRateHz) {
479 for (auto channel_mode : aptx_capability.channelMode) {
480 AptxConfiguration aptx_data{.sampleRateHz = sample_rate,
481 .channelMode = channel_mode,
482 .bitsPerSample = bits_per_sample};
483 aptx_codec_specifics.push_back(
484 CodecConfiguration::CodecSpecific(aptx_data));
485 }
486 }
487 }
488 return aptx_codec_specifics;
489 }
490
491 std::vector<CodecConfiguration::CodecSpecific>
GetOpusCodecSpecificSupportedList(bool supported)492 GetOpusCodecSpecificSupportedList(bool supported) {
493 std::vector<CodecConfiguration::CodecSpecific> opus_codec_specifics;
494 if (!supported) {
495 OpusConfiguration opus_config{.samplingFrequencyHz = 0,
496 .frameDurationUs = 0};
497 opus_codec_specifics.push_back(
498 CodecConfiguration::CodecSpecific(opus_config));
499 return opus_codec_specifics;
500 }
501 GetA2dpOffloadCapabilityHelper(CodecType::OPUS);
502 if (temp_codec_capabilities_ == nullptr ||
503 temp_codec_capabilities_->codecType != CodecType::OPUS) {
504 return opus_codec_specifics;
505 }
506 // parse the capability
507 auto& opus_capability =
508 temp_codec_capabilities_->capabilities
509 .get<CodecCapabilities::Capabilities::opusCapabilities>();
510
511 // combine those parameters into one list of
512 // CodecConfiguration::CodecSpecific
513 for (int32_t samplingFrequencyHz : opus_capability->samplingFrequencyHz) {
514 for (int32_t frameDurationUs : opus_capability->frameDurationUs) {
515 for (auto channel_mode : opus_capability->channelMode) {
516 OpusConfiguration opus_data{
517 .samplingFrequencyHz = samplingFrequencyHz,
518 .frameDurationUs = frameDurationUs,
519 .channelMode = channel_mode,
520 };
521 opus_codec_specifics.push_back(
522 CodecConfiguration::CodecSpecific(opus_data));
523 }
524 }
525 }
526 return opus_codec_specifics;
527 }
528
IsPcmConfigSupported(const PcmConfiguration & pcm_config)529 bool IsPcmConfigSupported(const PcmConfiguration& pcm_config) {
530 if (temp_provider_capabilities_.size() != 1 ||
531 temp_provider_capabilities_[0].getTag() !=
532 AudioCapabilities::pcmCapabilities) {
533 return false;
534 }
535 auto pcm_capability = temp_provider_capabilities_[0]
536 .get<AudioCapabilities::pcmCapabilities>();
537 return (contained_in_vector(pcm_capability.channelMode,
538 pcm_config.channelMode) &&
539 contained_in_vector(pcm_capability.sampleRateHz,
540 pcm_config.sampleRateHz) &&
541 contained_in_vector(pcm_capability.bitsPerSample,
542 pcm_config.bitsPerSample));
543 }
544
545 std::shared_ptr<IBluetoothAudioProviderFactory> provider_factory_;
546 std::shared_ptr<IBluetoothAudioProvider> audio_provider_;
547 std::shared_ptr<IBluetoothAudioPort> audio_port_;
548 std::vector<AudioCapabilities> temp_provider_capabilities_;
549
550 // temp storage saves the specified codec capability by
551 // GetOffloadCodecCapabilityHelper()
552 CodecCapabilities* temp_codec_capabilities_;
553
554 static constexpr SessionType kSessionTypes[] = {
555 SessionType::UNKNOWN,
556 SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
557 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
558 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
559 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
560 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
561 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
562 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
563 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
564 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
565 SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
566 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
567 };
568 };
569
570 /**
571 * Test whether we can get the FactoryService from HIDL
572 */
TEST_P(BluetoothAudioProviderFactoryAidl,GetProviderFactoryService)573 TEST_P(BluetoothAudioProviderFactoryAidl, GetProviderFactoryService) {}
574
575 /**
576 * Test whether we can open a provider for each provider returned by
577 * getProviderCapabilities() with non-empty capabalities
578 */
TEST_P(BluetoothAudioProviderFactoryAidl,OpenProviderAndCheckCapabilitiesBySession)579 TEST_P(BluetoothAudioProviderFactoryAidl,
580 OpenProviderAndCheckCapabilitiesBySession) {
581 for (auto session_type : kSessionTypes) {
582 GetProviderCapabilitiesHelper(session_type);
583 OpenProviderHelper(session_type);
584 // We must be able to open a provider if its getProviderCapabilities()
585 // returns non-empty list.
586 EXPECT_TRUE(temp_provider_capabilities_.empty() ||
587 audio_provider_ != nullptr);
588 }
589 }
590
591 /**
592 * openProvider A2DP_SOFTWARE_ENCODING_DATAPATH
593 */
594 class BluetoothAudioProviderA2dpEncodingSoftwareAidl
595 : public BluetoothAudioProviderFactoryAidl {
596 public:
SetUp()597 virtual void SetUp() override {
598 BluetoothAudioProviderFactoryAidl::SetUp();
599 GetProviderCapabilitiesHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
600 OpenProviderHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
601 ASSERT_NE(audio_provider_, nullptr);
602 }
603
TearDown()604 virtual void TearDown() override {
605 audio_port_ = nullptr;
606 audio_provider_ = nullptr;
607 BluetoothAudioProviderFactoryAidl::TearDown();
608 }
609 };
610
611 /**
612 * Test whether we can open a provider of type
613 */
TEST_P(BluetoothAudioProviderA2dpEncodingSoftwareAidl,OpenA2dpEncodingSoftwareProvider)614 TEST_P(BluetoothAudioProviderA2dpEncodingSoftwareAidl,
615 OpenA2dpEncodingSoftwareProvider) {}
616
617 /**
618 * Test whether each provider of type
619 * SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH can be started and stopped with
620 * different PCM config
621 */
TEST_P(BluetoothAudioProviderA2dpEncodingSoftwareAidl,StartAndEndA2dpEncodingSoftwareSessionWithPossiblePcmConfig)622 TEST_P(BluetoothAudioProviderA2dpEncodingSoftwareAidl,
623 StartAndEndA2dpEncodingSoftwareSessionWithPossiblePcmConfig) {
624 for (auto sample_rate : a2dp_sample_rates) {
625 for (auto bits_per_sample : a2dp_bits_per_samples) {
626 for (auto channel_mode : a2dp_channel_modes) {
627 PcmConfiguration pcm_config{
628 .sampleRateHz = sample_rate,
629 .channelMode = channel_mode,
630 .bitsPerSample = bits_per_sample,
631 };
632 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
633 DataMQDesc mq_desc;
634 auto aidl_retval = audio_provider_->startSession(
635 audio_port_, AudioConfiguration(pcm_config), latency_modes,
636 &mq_desc);
637 DataMQ data_mq(mq_desc);
638
639 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
640 if (is_codec_config_valid) {
641 EXPECT_TRUE(data_mq.isValid());
642 }
643 EXPECT_TRUE(audio_provider_->endSession().isOk());
644 }
645 }
646 }
647 }
648
649 /**
650 * openProvider A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH
651 */
652 class BluetoothAudioProviderA2dpEncodingHardwareAidl
653 : public BluetoothAudioProviderFactoryAidl {
654 public:
SetUp()655 virtual void SetUp() override {
656 BluetoothAudioProviderFactoryAidl::SetUp();
657 GetProviderCapabilitiesHelper(
658 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
659 OpenProviderHelper(SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
660 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
661 audio_provider_ != nullptr);
662 }
663
TearDown()664 virtual void TearDown() override {
665 audio_port_ = nullptr;
666 audio_provider_ = nullptr;
667 BluetoothAudioProviderFactoryAidl::TearDown();
668 }
669
IsOffloadSupported()670 bool IsOffloadSupported() { return (temp_provider_capabilities_.size() > 0); }
671 };
672
673 /**
674 * Test whether we can open a provider of type
675 */
TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,OpenA2dpEncodingHardwareProvider)676 TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
677 OpenA2dpEncodingHardwareProvider) {}
678
679 /**
680 * Test whether each provider of type
681 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
682 * SBC hardware encoding config
683 */
TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,StartAndEndA2dpSbcEncodingHardwareSession)684 TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
685 StartAndEndA2dpSbcEncodingHardwareSession) {
686 if (!IsOffloadSupported()) {
687 return;
688 }
689
690 CodecConfiguration codec_config = {
691 .codecType = CodecType::SBC,
692 .encodedAudioBitrate = 328000,
693 .peerMtu = 1005,
694 .isScmstEnabled = false,
695 };
696 auto sbc_codec_specifics = GetSbcCodecSpecificSupportedList(true);
697
698 for (auto& codec_specific : sbc_codec_specifics) {
699 copy_codec_specific(codec_config.config, codec_specific);
700 DataMQDesc mq_desc;
701 auto aidl_retval = audio_provider_->startSession(
702 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
703
704 ASSERT_TRUE(aidl_retval.isOk());
705 EXPECT_TRUE(audio_provider_->endSession().isOk());
706 }
707 }
708
709 /**
710 * Test whether each provider of type
711 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
712 * AAC hardware encoding config
713 */
TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,StartAndEndA2dpAacEncodingHardwareSession)714 TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
715 StartAndEndA2dpAacEncodingHardwareSession) {
716 if (!IsOffloadSupported()) {
717 return;
718 }
719
720 CodecConfiguration codec_config = {
721 .codecType = CodecType::AAC,
722 .encodedAudioBitrate = 320000,
723 .peerMtu = 1005,
724 .isScmstEnabled = false,
725 };
726 auto aac_codec_specifics = GetAacCodecSpecificSupportedList(true);
727
728 for (auto& codec_specific : aac_codec_specifics) {
729 copy_codec_specific(codec_config.config, codec_specific);
730 DataMQDesc mq_desc;
731 auto aidl_retval = audio_provider_->startSession(
732 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
733
734 ASSERT_TRUE(aidl_retval.isOk());
735 EXPECT_TRUE(audio_provider_->endSession().isOk());
736 }
737 }
738
739 /**
740 * Test whether each provider of type
741 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
742 * LDAC hardware encoding config
743 */
TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,StartAndEndA2dpLdacEncodingHardwareSession)744 TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
745 StartAndEndA2dpLdacEncodingHardwareSession) {
746 if (!IsOffloadSupported()) {
747 return;
748 }
749
750 CodecConfiguration codec_config = {
751 .codecType = CodecType::LDAC,
752 .encodedAudioBitrate = 990000,
753 .peerMtu = 1005,
754 .isScmstEnabled = false,
755 };
756 auto ldac_codec_specifics = GetLdacCodecSpecificSupportedList(true);
757
758 for (auto& codec_specific : ldac_codec_specifics) {
759 copy_codec_specific(codec_config.config, codec_specific);
760 DataMQDesc mq_desc;
761 auto aidl_retval = audio_provider_->startSession(
762 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
763
764 ASSERT_TRUE(aidl_retval.isOk());
765 EXPECT_TRUE(audio_provider_->endSession().isOk());
766 }
767 }
768
769 /**
770 * Test whether each provider of type
771 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
772 * Opus hardware encoding config
773 */
TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,StartAndEndA2dpOpusEncodingHardwareSession)774 TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
775 StartAndEndA2dpOpusEncodingHardwareSession) {
776 if (!IsOffloadSupported()) {
777 return;
778 }
779
780 CodecConfiguration codec_config = {
781 .codecType = CodecType::OPUS,
782 .encodedAudioBitrate = 990000,
783 .peerMtu = 1005,
784 .isScmstEnabled = false,
785 };
786 auto opus_codec_specifics = GetOpusCodecSpecificSupportedList(true);
787
788 for (auto& codec_specific : opus_codec_specifics) {
789 copy_codec_specific(codec_config.config, codec_specific);
790 DataMQDesc mq_desc;
791 auto aidl_retval = audio_provider_->startSession(
792 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
793
794 ASSERT_TRUE(aidl_retval.isOk());
795 EXPECT_TRUE(audio_provider_->endSession().isOk());
796 }
797 }
798
799 /**
800 * Test whether each provider of type
801 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
802 * AptX hardware encoding config
803 */
TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,StartAndEndA2dpAptxEncodingHardwareSession)804 TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
805 StartAndEndA2dpAptxEncodingHardwareSession) {
806 if (!IsOffloadSupported()) {
807 return;
808 }
809
810 for (auto codec_type : {CodecType::APTX, CodecType::APTX_HD}) {
811 CodecConfiguration codec_config = {
812 .codecType = codec_type,
813 .encodedAudioBitrate =
814 (codec_type == CodecType::APTX ? 352000 : 576000),
815 .peerMtu = 1005,
816 .isScmstEnabled = false,
817 };
818
819 auto aptx_codec_specifics = GetAptxCodecSpecificSupportedList(
820 (codec_type == CodecType::APTX_HD ? true : false), true);
821
822 for (auto& codec_specific : aptx_codec_specifics) {
823 copy_codec_specific(codec_config.config, codec_specific);
824 DataMQDesc mq_desc;
825 auto aidl_retval = audio_provider_->startSession(
826 audio_port_, AudioConfiguration(codec_config), latency_modes,
827 &mq_desc);
828
829 ASSERT_TRUE(aidl_retval.isOk());
830 EXPECT_TRUE(audio_provider_->endSession().isOk());
831 }
832 }
833 }
834
835 /**
836 * Test whether each provider of type
837 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
838 * an invalid codec config
839 */
TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,StartAndEndA2dpEncodingHardwareSessionInvalidCodecConfig)840 TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
841 StartAndEndA2dpEncodingHardwareSessionInvalidCodecConfig) {
842 if (!IsOffloadSupported()) {
843 return;
844 }
845 ASSERT_NE(audio_provider_, nullptr);
846
847 std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
848 for (auto codec_type : a2dp_codec_types) {
849 switch (codec_type) {
850 case CodecType::SBC:
851 codec_specifics = GetSbcCodecSpecificSupportedList(false);
852 break;
853 case CodecType::AAC:
854 codec_specifics = GetAacCodecSpecificSupportedList(false);
855 break;
856 case CodecType::LDAC:
857 codec_specifics = GetLdacCodecSpecificSupportedList(false);
858 break;
859 case CodecType::APTX:
860 codec_specifics = GetAptxCodecSpecificSupportedList(false, false);
861 break;
862 case CodecType::APTX_HD:
863 codec_specifics = GetAptxCodecSpecificSupportedList(true, false);
864 break;
865 case CodecType::OPUS:
866 codec_specifics = GetOpusCodecSpecificSupportedList(false);
867 continue;
868 case CodecType::APTX_ADAPTIVE:
869 case CodecType::LC3:
870 case CodecType::VENDOR:
871 case CodecType::UNKNOWN:
872 codec_specifics.clear();
873 break;
874 }
875 if (codec_specifics.empty()) {
876 continue;
877 }
878
879 CodecConfiguration codec_config = {
880 .codecType = codec_type,
881 .encodedAudioBitrate = 328000,
882 .peerMtu = 1005,
883 .isScmstEnabled = false,
884 };
885 for (auto codec_specific : codec_specifics) {
886 copy_codec_specific(codec_config.config, codec_specific);
887 DataMQDesc mq_desc;
888 auto aidl_retval = audio_provider_->startSession(
889 audio_port_, AudioConfiguration(codec_config), latency_modes,
890 &mq_desc);
891
892 // AIDL call should fail on invalid codec
893 ASSERT_FALSE(aidl_retval.isOk());
894 EXPECT_TRUE(audio_provider_->endSession().isOk());
895 }
896 }
897 }
898
899 /**
900 * openProvider HEARING_AID_SOFTWARE_ENCODING_DATAPATH
901 */
902 class BluetoothAudioProviderHearingAidSoftwareAidl
903 : public BluetoothAudioProviderFactoryAidl {
904 public:
SetUp()905 virtual void SetUp() override {
906 BluetoothAudioProviderFactoryAidl::SetUp();
907 GetProviderCapabilitiesHelper(
908 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
909 OpenProviderHelper(SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
910 ASSERT_NE(audio_provider_, nullptr);
911 }
912
TearDown()913 virtual void TearDown() override {
914 audio_port_ = nullptr;
915 audio_provider_ = nullptr;
916 BluetoothAudioProviderFactoryAidl::TearDown();
917 }
918
919 static constexpr int32_t hearing_aid_sample_rates_[] = {0, 16000, 24000};
920 static constexpr int8_t hearing_aid_bits_per_samples_[] = {0, 16, 24};
921 static constexpr ChannelMode hearing_aid_channel_modes_[] = {
922 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
923 };
924
925 /**
926 * Test whether we can open a provider of type
927 */
TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl,OpenHearingAidSoftwareProvider)928 TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl,
929 OpenHearingAidSoftwareProvider) {}
930
931 /**
932 * Test whether each provider of type
933 * SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH can be started and
934 * stopped with different PCM config
935 */
TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl,StartAndEndHearingAidSessionWithPossiblePcmConfig)936 TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl,
937 StartAndEndHearingAidSessionWithPossiblePcmConfig) {
938 for (int32_t sample_rate : hearing_aid_sample_rates_) {
939 for (int8_t bits_per_sample : hearing_aid_bits_per_samples_) {
940 for (auto channel_mode : hearing_aid_channel_modes_) {
941 PcmConfiguration pcm_config{
942 .sampleRateHz = sample_rate,
943 .channelMode = channel_mode,
944 .bitsPerSample = bits_per_sample,
945 };
946 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
947 DataMQDesc mq_desc;
948 auto aidl_retval = audio_provider_->startSession(
949 audio_port_, AudioConfiguration(pcm_config), latency_modes,
950 &mq_desc);
951 DataMQ data_mq(mq_desc);
952
953 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
954 if (is_codec_config_valid) {
955 EXPECT_TRUE(data_mq.isValid());
956 }
957 EXPECT_TRUE(audio_provider_->endSession().isOk());
958 }
959 }
960 }
961 }
962
963 /**
964 * openProvider LE_AUDIO_SOFTWARE_ENCODING_DATAPATH
965 */
966 class BluetoothAudioProviderLeAudioOutputSoftwareAidl
967 : public BluetoothAudioProviderFactoryAidl {
968 public:
SetUp()969 virtual void SetUp() override {
970 BluetoothAudioProviderFactoryAidl::SetUp();
971 GetProviderCapabilitiesHelper(
972 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
973 OpenProviderHelper(SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
974 ASSERT_NE(audio_provider_, nullptr);
975 }
976
TearDown()977 virtual void TearDown() override {
978 audio_port_ = nullptr;
979 audio_provider_ = nullptr;
980 BluetoothAudioProviderFactoryAidl::TearDown();
981 }
982
983 static constexpr int32_t le_audio_output_sample_rates_[] = {
984 0, 8000, 16000, 24000, 32000, 44100, 48000,
985 };
986 static constexpr int8_t le_audio_output_bits_per_samples_[] = {0, 16, 24};
987 static constexpr ChannelMode le_audio_output_channel_modes_[] = {
988 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
989 static constexpr int32_t le_audio_output_data_interval_us_[] = {
990 0 /* Invalid */, 10000 /* Valid 10ms */};
991 };
992
993 /**
994 * Test whether each provider of type
995 * SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH can be started and
996 * stopped
997 */
TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl,OpenLeAudioOutputSoftwareProvider)998 TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl,
999 OpenLeAudioOutputSoftwareProvider) {}
1000
1001 /**
1002 * Test whether each provider of type
1003 * SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH can be started and
1004 * stopped with different PCM config
1005 */
TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl,StartAndEndLeAudioOutputSessionWithPossiblePcmConfig)1006 TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl,
1007 StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
1008 for (auto sample_rate : le_audio_output_sample_rates_) {
1009 for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
1010 for (auto channel_mode : le_audio_output_channel_modes_) {
1011 for (auto data_interval_us : le_audio_output_data_interval_us_) {
1012 PcmConfiguration pcm_config{
1013 .sampleRateHz = sample_rate,
1014 .channelMode = channel_mode,
1015 .bitsPerSample = bits_per_sample,
1016 .dataIntervalUs = data_interval_us,
1017 };
1018 bool is_codec_config_valid =
1019 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
1020 DataMQDesc mq_desc;
1021 auto aidl_retval = audio_provider_->startSession(
1022 audio_port_, AudioConfiguration(pcm_config), latency_modes,
1023 &mq_desc);
1024 DataMQ data_mq(mq_desc);
1025
1026 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
1027 if (is_codec_config_valid) {
1028 EXPECT_TRUE(data_mq.isValid());
1029 }
1030 EXPECT_TRUE(audio_provider_->endSession().isOk());
1031 }
1032 }
1033 }
1034 }
1035 }
1036
1037 /**
1038 * openProvider LE_AUDIO_SOFTWARE_DECODING_DATAPATH
1039 */
1040 class BluetoothAudioProviderLeAudioInputSoftwareAidl
1041 : public BluetoothAudioProviderFactoryAidl {
1042 public:
SetUp()1043 virtual void SetUp() override {
1044 BluetoothAudioProviderFactoryAidl::SetUp();
1045 GetProviderCapabilitiesHelper(
1046 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH);
1047 OpenProviderHelper(SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH);
1048 ASSERT_NE(audio_provider_, nullptr);
1049 }
1050
TearDown()1051 virtual void TearDown() override {
1052 audio_port_ = nullptr;
1053 audio_provider_ = nullptr;
1054 BluetoothAudioProviderFactoryAidl::TearDown();
1055 }
1056
1057 static constexpr int32_t le_audio_input_sample_rates_[] = {
1058 0, 8000, 16000, 24000, 32000, 44100, 48000};
1059 static constexpr int8_t le_audio_input_bits_per_samples_[] = {0, 16, 24};
1060 static constexpr ChannelMode le_audio_input_channel_modes_[] = {
1061 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
1062 static constexpr int32_t le_audio_input_data_interval_us_[] = {
1063 0 /* Invalid */, 10000 /* Valid 10ms */};
1064 };
1065
1066 /**
1067 * Test whether each provider of type
1068 * SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH can be started and
1069 * stopped
1070 */
TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl,OpenLeAudioInputSoftwareProvider)1071 TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl,
1072 OpenLeAudioInputSoftwareProvider) {}
1073
1074 /**
1075 * Test whether each provider of type
1076 * SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH can be started and
1077 * stopped with different PCM config
1078 */
TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl,StartAndEndLeAudioInputSessionWithPossiblePcmConfig)1079 TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl,
1080 StartAndEndLeAudioInputSessionWithPossiblePcmConfig) {
1081 for (auto sample_rate : le_audio_input_sample_rates_) {
1082 for (auto bits_per_sample : le_audio_input_bits_per_samples_) {
1083 for (auto channel_mode : le_audio_input_channel_modes_) {
1084 for (auto data_interval_us : le_audio_input_data_interval_us_) {
1085 PcmConfiguration pcm_config{
1086 .sampleRateHz = sample_rate,
1087 .channelMode = channel_mode,
1088 .bitsPerSample = bits_per_sample,
1089 .dataIntervalUs = data_interval_us,
1090 };
1091 bool is_codec_config_valid =
1092 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
1093 DataMQDesc mq_desc;
1094 auto aidl_retval = audio_provider_->startSession(
1095 audio_port_, AudioConfiguration(pcm_config), latency_modes,
1096 &mq_desc);
1097 DataMQ data_mq(mq_desc);
1098
1099 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
1100 if (is_codec_config_valid) {
1101 EXPECT_TRUE(data_mq.isValid());
1102 }
1103 EXPECT_TRUE(audio_provider_->endSession().isOk());
1104 }
1105 }
1106 }
1107 }
1108 }
1109
1110 /**
1111 * openProvider LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH
1112 */
1113 class BluetoothAudioProviderLeAudioOutputHardwareAidl
1114 : public BluetoothAudioProviderFactoryAidl {
1115 public:
SetUp()1116 virtual void SetUp() override {
1117 BluetoothAudioProviderFactoryAidl::SetUp();
1118 GetProviderCapabilitiesHelper(
1119 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
1120 OpenProviderHelper(
1121 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
1122 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
1123 audio_provider_ != nullptr);
1124 }
1125
TearDown()1126 virtual void TearDown() override {
1127 audio_port_ = nullptr;
1128 audio_provider_ = nullptr;
1129 BluetoothAudioProviderFactoryAidl::TearDown();
1130 }
1131
IsOffloadOutputSupported()1132 bool IsOffloadOutputSupported() {
1133 for (auto& capability : temp_provider_capabilities_) {
1134 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
1135 continue;
1136 }
1137 auto& le_audio_capability =
1138 capability.get<AudioCapabilities::leAudioCapabilities>();
1139 if (le_audio_capability.unicastEncodeCapability.codecType !=
1140 CodecType::UNKNOWN)
1141 return true;
1142 }
1143 return false;
1144 }
1145
GetUnicastLc3SupportedList(bool decoding,bool supported)1146 std::vector<Lc3Configuration> GetUnicastLc3SupportedList(bool decoding,
1147 bool supported) {
1148 std::vector<Lc3Configuration> le_audio_codec_configs;
1149 if (!supported) {
1150 Lc3Configuration lc3_config{.pcmBitDepth = 0, .samplingFrequencyHz = 0};
1151 le_audio_codec_configs.push_back(lc3_config);
1152 return le_audio_codec_configs;
1153 }
1154
1155 // There might be more than one LeAudioCodecCapabilitiesSetting
1156 std::vector<Lc3Capabilities> lc3_capabilities;
1157 for (auto& capability : temp_provider_capabilities_) {
1158 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
1159 continue;
1160 }
1161 auto& le_audio_capability =
1162 capability.get<AudioCapabilities::leAudioCapabilities>();
1163 auto& unicast_capability =
1164 decoding ? le_audio_capability.unicastDecodeCapability
1165 : le_audio_capability.unicastEncodeCapability;
1166 if (unicast_capability.codecType != CodecType::LC3) {
1167 continue;
1168 }
1169 auto& lc3_capability = unicast_capability.leAudioCodecCapabilities.get<
1170 UnicastCapability::LeAudioCodecCapabilities::lc3Capabilities>();
1171 lc3_capabilities.push_back(lc3_capability);
1172 }
1173
1174 // Combine those parameters into one list of LeAudioCodecConfiguration
1175 // This seems horrible, but usually each Lc3Capability only contains a
1176 // single Lc3Configuration, which means every array has a length of 1.
1177 for (auto& lc3_capability : lc3_capabilities) {
1178 for (int32_t samplingFrequencyHz : lc3_capability.samplingFrequencyHz) {
1179 for (int32_t frameDurationUs : lc3_capability.frameDurationUs) {
1180 for (int32_t octetsPerFrame : lc3_capability.octetsPerFrame) {
1181 Lc3Configuration lc3_config = {
1182 .samplingFrequencyHz = samplingFrequencyHz,
1183 .frameDurationUs = frameDurationUs,
1184 .octetsPerFrame = octetsPerFrame,
1185 };
1186 le_audio_codec_configs.push_back(lc3_config);
1187 }
1188 }
1189 }
1190 }
1191
1192 return le_audio_codec_configs;
1193 }
1194
1195 LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
1196 };
1197
1198 /**
1199 * Test whether each provider of type
1200 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
1201 * stopped
1202 */
TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,OpenLeAudioOutputHardwareProvider)1203 TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
1204 OpenLeAudioOutputHardwareProvider) {}
1205
1206 /**
1207 * Test whether each provider of type
1208 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
1209 * stopped with Unicast hardware encoding config
1210 */
TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,StartAndEndLeAudioOutputSessionWithPossibleUnicastConfig)1211 TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
1212 StartAndEndLeAudioOutputSessionWithPossibleUnicastConfig) {
1213 if (!IsOffloadOutputSupported()) {
1214 return;
1215 }
1216
1217 auto lc3_codec_configs =
1218 GetUnicastLc3SupportedList(false /* decoding */, true /* supported */);
1219 LeAudioConfiguration le_audio_config = {
1220 .codecType = CodecType::LC3,
1221 .peerDelayUs = 0,
1222 };
1223
1224 for (auto& lc3_config : lc3_codec_configs) {
1225 le_audio_config.leAudioCodecConfig
1226 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
1227 DataMQDesc mq_desc;
1228 auto aidl_retval = audio_provider_->startSession(
1229 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
1230 &mq_desc);
1231
1232 ASSERT_TRUE(aidl_retval.isOk());
1233 EXPECT_TRUE(audio_provider_->endSession().isOk());
1234 }
1235 }
1236
1237 /**
1238 * Test whether each provider of type
1239 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
1240 * stopped with Unicast hardware encoding config
1241 *
1242 * Disabled since offload codec checking is not ready
1243 */
TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,DISABLED_StartAndEndLeAudioOutputSessionWithInvalidAudioConfiguration)1244 TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
1245 DISABLED_StartAndEndLeAudioOutputSessionWithInvalidAudioConfiguration) {
1246 if (!IsOffloadOutputSupported()) {
1247 return;
1248 }
1249
1250 auto lc3_codec_configs =
1251 GetUnicastLc3SupportedList(false /* decoding */, false /* supported */);
1252 LeAudioConfiguration le_audio_config = {
1253 .codecType = CodecType::LC3,
1254 .peerDelayUs = 0,
1255 };
1256
1257 for (auto& lc3_config : lc3_codec_configs) {
1258 le_audio_config.leAudioCodecConfig
1259 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
1260 DataMQDesc mq_desc;
1261 auto aidl_retval = audio_provider_->startSession(
1262 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
1263 &mq_desc);
1264
1265 // AIDL call should fail on invalid codec
1266 ASSERT_FALSE(aidl_retval.isOk());
1267 EXPECT_TRUE(audio_provider_->endSession().isOk());
1268 }
1269 }
1270
1271 /**
1272 * openProvider LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH
1273 */
1274 class BluetoothAudioProviderLeAudioInputHardwareAidl
1275 : public BluetoothAudioProviderLeAudioOutputHardwareAidl {
1276 public:
SetUp()1277 virtual void SetUp() override {
1278 BluetoothAudioProviderFactoryAidl::SetUp();
1279 GetProviderCapabilitiesHelper(
1280 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
1281 OpenProviderHelper(
1282 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
1283 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
1284 audio_provider_ != nullptr);
1285 }
1286
IsOffloadInputSupported()1287 bool IsOffloadInputSupported() {
1288 for (auto& capability : temp_provider_capabilities_) {
1289 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
1290 continue;
1291 }
1292 auto& le_audio_capability =
1293 capability.get<AudioCapabilities::leAudioCapabilities>();
1294 if (le_audio_capability.unicastDecodeCapability.codecType !=
1295 CodecType::UNKNOWN)
1296 return true;
1297 }
1298 return false;
1299 }
1300
TearDown()1301 virtual void TearDown() override {
1302 audio_port_ = nullptr;
1303 audio_provider_ = nullptr;
1304 BluetoothAudioProviderFactoryAidl::TearDown();
1305 }
1306 };
1307
1308 /**
1309 * Test whether each provider of type
1310 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
1311 * stopped
1312 */
TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,OpenLeAudioInputHardwareProvider)1313 TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
1314 OpenLeAudioInputHardwareProvider) {}
1315
1316 /**
1317 * Test whether each provider of type
1318 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
1319 * stopped with Unicast hardware encoding config
1320 */
TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,StartAndEndLeAudioInputSessionWithPossibleUnicastConfig)1321 TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
1322 StartAndEndLeAudioInputSessionWithPossibleUnicastConfig) {
1323 if (!IsOffloadInputSupported()) {
1324 return;
1325 }
1326
1327 auto lc3_codec_configs =
1328 GetUnicastLc3SupportedList(true /* decoding */, true /* supported */);
1329 LeAudioConfiguration le_audio_config = {
1330 .codecType = CodecType::LC3,
1331 .peerDelayUs = 0,
1332 };
1333
1334 for (auto& lc3_config : lc3_codec_configs) {
1335 le_audio_config.leAudioCodecConfig
1336 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
1337 DataMQDesc mq_desc;
1338 auto aidl_retval = audio_provider_->startSession(
1339 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
1340 &mq_desc);
1341
1342 ASSERT_TRUE(aidl_retval.isOk());
1343 EXPECT_TRUE(audio_provider_->endSession().isOk());
1344 }
1345 }
1346
1347 /**
1348 * Test whether each provider of type
1349 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
1350 * stopped with Unicast hardware encoding config
1351 *
1352 * Disabled since offload codec checking is not ready
1353 */
TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,DISABLED_StartAndEndLeAudioInputSessionWithInvalidAudioConfiguration)1354 TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
1355 DISABLED_StartAndEndLeAudioInputSessionWithInvalidAudioConfiguration) {
1356 if (!IsOffloadInputSupported()) {
1357 return;
1358 }
1359
1360 auto lc3_codec_configs =
1361 GetUnicastLc3SupportedList(true /* decoding */, false /* supported */);
1362 LeAudioConfiguration le_audio_config = {
1363 .codecType = CodecType::LC3,
1364 .peerDelayUs = 0,
1365 };
1366
1367 for (auto& lc3_config : lc3_codec_configs) {
1368 le_audio_config.leAudioCodecConfig
1369 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
1370
1371 DataMQDesc mq_desc;
1372 auto aidl_retval = audio_provider_->startSession(
1373 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
1374 &mq_desc);
1375
1376 // AIDL call should fail on invalid codec
1377 ASSERT_FALSE(aidl_retval.isOk());
1378 EXPECT_TRUE(audio_provider_->endSession().isOk());
1379 }
1380 }
1381
1382 /**
1383 * openProvider LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH
1384 */
1385 class BluetoothAudioProviderLeAudioBroadcastSoftwareAidl
1386 : public BluetoothAudioProviderFactoryAidl {
1387 public:
SetUp()1388 virtual void SetUp() override {
1389 BluetoothAudioProviderFactoryAidl::SetUp();
1390 GetProviderCapabilitiesHelper(
1391 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
1392 OpenProviderHelper(
1393 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
1394 ASSERT_NE(audio_provider_, nullptr);
1395 }
1396
TearDown()1397 virtual void TearDown() override {
1398 audio_port_ = nullptr;
1399 audio_provider_ = nullptr;
1400 BluetoothAudioProviderFactoryAidl::TearDown();
1401 }
1402
1403 static constexpr int32_t le_audio_output_sample_rates_[] = {
1404 0, 8000, 16000, 24000, 32000, 44100, 48000,
1405 };
1406 static constexpr int8_t le_audio_output_bits_per_samples_[] = {0, 16, 24};
1407 static constexpr ChannelMode le_audio_output_channel_modes_[] = {
1408 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
1409 static constexpr int32_t le_audio_output_data_interval_us_[] = {
1410 0 /* Invalid */, 10000 /* Valid 10ms */};
1411 };
1412
1413 /**
1414 * Test whether each provider of type
1415 * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started and
1416 * stopped
1417 */
TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,OpenLeAudioOutputSoftwareProvider)1418 TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
1419 OpenLeAudioOutputSoftwareProvider) {}
1420
1421 /**
1422 * Test whether each provider of type
1423 * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started and
1424 * stopped with different PCM config
1425 */
TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,StartAndEndLeAudioOutputSessionWithPossiblePcmConfig)1426 TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
1427 StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
1428 for (auto sample_rate : le_audio_output_sample_rates_) {
1429 for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
1430 for (auto channel_mode : le_audio_output_channel_modes_) {
1431 for (auto data_interval_us : le_audio_output_data_interval_us_) {
1432 PcmConfiguration pcm_config{
1433 .sampleRateHz = sample_rate,
1434 .channelMode = channel_mode,
1435 .bitsPerSample = bits_per_sample,
1436 .dataIntervalUs = data_interval_us,
1437 };
1438 bool is_codec_config_valid =
1439 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
1440 DataMQDesc mq_desc;
1441 auto aidl_retval = audio_provider_->startSession(
1442 audio_port_, AudioConfiguration(pcm_config), latency_modes,
1443 &mq_desc);
1444 DataMQ data_mq(mq_desc);
1445
1446 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
1447 if (is_codec_config_valid) {
1448 EXPECT_TRUE(data_mq.isValid());
1449 }
1450 EXPECT_TRUE(audio_provider_->endSession().isOk());
1451 }
1452 }
1453 }
1454 }
1455 }
1456
1457 /**
1458 * openProvider LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH
1459 */
1460 class BluetoothAudioProviderLeAudioBroadcastHardwareAidl
1461 : public BluetoothAudioProviderFactoryAidl {
1462 public:
SetUp()1463 virtual void SetUp() override {
1464 BluetoothAudioProviderFactoryAidl::SetUp();
1465 GetProviderCapabilitiesHelper(
1466 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
1467 OpenProviderHelper(
1468 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
1469 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
1470 audio_provider_ != nullptr);
1471 }
1472
TearDown()1473 virtual void TearDown() override {
1474 audio_port_ = nullptr;
1475 audio_provider_ = nullptr;
1476 BluetoothAudioProviderFactoryAidl::TearDown();
1477 }
1478
IsBroadcastOffloadSupported()1479 bool IsBroadcastOffloadSupported() {
1480 for (auto& capability : temp_provider_capabilities_) {
1481 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
1482 continue;
1483 }
1484 auto& le_audio_capability =
1485 capability.get<AudioCapabilities::leAudioCapabilities>();
1486 if (le_audio_capability.broadcastCapability.codecType !=
1487 CodecType::UNKNOWN)
1488 return true;
1489 }
1490 return false;
1491 }
1492
GetBroadcastLc3SupportedList(bool supported)1493 std::vector<Lc3Configuration> GetBroadcastLc3SupportedList(bool supported) {
1494 std::vector<Lc3Configuration> le_audio_codec_configs;
1495 if (!supported) {
1496 Lc3Configuration lc3_config{.pcmBitDepth = 0, .samplingFrequencyHz = 0};
1497 le_audio_codec_configs.push_back(lc3_config);
1498 return le_audio_codec_configs;
1499 }
1500
1501 // There might be more than one LeAudioCodecCapabilitiesSetting
1502 std::vector<Lc3Capabilities> lc3_capabilities;
1503 for (auto& capability : temp_provider_capabilities_) {
1504 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
1505 continue;
1506 }
1507 auto& le_audio_capability =
1508 capability.get<AudioCapabilities::leAudioCapabilities>();
1509 auto& broadcast_capability = le_audio_capability.broadcastCapability;
1510 if (broadcast_capability.codecType != CodecType::LC3) {
1511 continue;
1512 }
1513 auto& lc3_capability = broadcast_capability.leAudioCodecCapabilities.get<
1514 BroadcastCapability::LeAudioCodecCapabilities::lc3Capabilities>();
1515 for (int idx = 0; idx < lc3_capability->size(); idx++)
1516 lc3_capabilities.push_back(*lc3_capability->at(idx));
1517 }
1518
1519 // Combine those parameters into one list of LeAudioCodecConfiguration
1520 // This seems horrible, but usually each Lc3Capability only contains a
1521 // single Lc3Configuration, which means every array has a length of 1.
1522 for (auto& lc3_capability : lc3_capabilities) {
1523 for (int32_t samplingFrequencyHz : lc3_capability.samplingFrequencyHz) {
1524 for (int32_t frameDurationUs : lc3_capability.frameDurationUs) {
1525 for (int32_t octetsPerFrame : lc3_capability.octetsPerFrame) {
1526 Lc3Configuration lc3_config = {
1527 .samplingFrequencyHz = samplingFrequencyHz,
1528 .frameDurationUs = frameDurationUs,
1529 .octetsPerFrame = octetsPerFrame,
1530 };
1531 le_audio_codec_configs.push_back(lc3_config);
1532 }
1533 }
1534 }
1535 }
1536
1537 return le_audio_codec_configs;
1538 }
1539
1540 LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
1541 };
1542
1543 /**
1544 * Test whether each provider of type
1545 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
1546 * started and stopped
1547 */
TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,OpenLeAudioOutputHardwareProvider)1548 TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
1549 OpenLeAudioOutputHardwareProvider) {}
1550
1551 /**
1552 * Test whether each provider of type
1553 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
1554 * started and stopped with broadcast hardware encoding config
1555 */
TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,StartAndEndLeAudioBroadcastSessionWithPossibleBroadcastConfig)1556 TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
1557 StartAndEndLeAudioBroadcastSessionWithPossibleBroadcastConfig) {
1558 if (!IsBroadcastOffloadSupported()) {
1559 return;
1560 }
1561
1562 auto lc3_codec_configs = GetBroadcastLc3SupportedList(true /* supported */);
1563 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
1564 .codecType = CodecType::LC3,
1565 .streamMap = {},
1566 };
1567
1568 for (auto& lc3_config : lc3_codec_configs) {
1569 le_audio_broadcast_config.streamMap[0]
1570 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
1571 lc3_config);
1572 DataMQDesc mq_desc;
1573 auto aidl_retval = audio_provider_->startSession(
1574 audio_port_, AudioConfiguration(le_audio_broadcast_config),
1575 latency_modes, &mq_desc);
1576
1577 ASSERT_TRUE(aidl_retval.isOk());
1578 EXPECT_TRUE(audio_provider_->endSession().isOk());
1579 }
1580 }
1581
1582 /**
1583 * Test whether each provider of type
1584 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
1585 * started and stopped with Broadcast hardware encoding config
1586 *
1587 * Disabled since offload codec checking is not ready
1588 */
TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,DISABLED_StartAndEndLeAudioBroadcastSessionWithInvalidAudioConfiguration)1589 TEST_P(
1590 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
1591 DISABLED_StartAndEndLeAudioBroadcastSessionWithInvalidAudioConfiguration) {
1592 if (!IsBroadcastOffloadSupported()) {
1593 return;
1594 }
1595
1596 auto lc3_codec_configs = GetBroadcastLc3SupportedList(false /* supported */);
1597 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
1598 .codecType = CodecType::LC3,
1599 .streamMap = {},
1600 };
1601
1602 for (auto& lc3_config : lc3_codec_configs) {
1603 le_audio_broadcast_config.streamMap[0]
1604 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
1605 lc3_config);
1606 DataMQDesc mq_desc;
1607 auto aidl_retval = audio_provider_->startSession(
1608 audio_port_, AudioConfiguration(le_audio_broadcast_config),
1609 latency_modes, &mq_desc);
1610
1611 // AIDL call should fail on invalid codec
1612 ASSERT_FALSE(aidl_retval.isOk());
1613 EXPECT_TRUE(audio_provider_->endSession().isOk());
1614 }
1615 }
1616
1617 /**
1618 * openProvider A2DP_SOFTWARE_DECODING_DATAPATH
1619 */
1620 class BluetoothAudioProviderA2dpDecodingSoftwareAidl
1621 : public BluetoothAudioProviderFactoryAidl {
1622 public:
SetUp()1623 virtual void SetUp() override {
1624 BluetoothAudioProviderFactoryAidl::SetUp();
1625 GetProviderCapabilitiesHelper(SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
1626 OpenProviderHelper(SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
1627 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
1628 audio_provider_ != nullptr);
1629 }
1630
TearDown()1631 virtual void TearDown() override {
1632 audio_port_ = nullptr;
1633 audio_provider_ = nullptr;
1634 BluetoothAudioProviderFactoryAidl::TearDown();
1635 }
1636 };
1637
1638 /**
1639 * Test whether we can open a provider of type
1640 */
TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,OpenA2dpDecodingSoftwareProvider)1641 TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,
1642 OpenA2dpDecodingSoftwareProvider) {}
1643
1644 /**
1645 * Test whether each provider of type
1646 * SessionType::A2DP_SOFTWARE_DECODING_DATAPATH can be started and stopped with
1647 * different PCM config
1648 */
TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,StartAndEndA2dpDecodingSoftwareSessionWithPossiblePcmConfig)1649 TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,
1650 StartAndEndA2dpDecodingSoftwareSessionWithPossiblePcmConfig) {
1651 for (auto sample_rate : a2dp_sample_rates) {
1652 for (auto bits_per_sample : a2dp_bits_per_samples) {
1653 for (auto channel_mode : a2dp_channel_modes) {
1654 PcmConfiguration pcm_config{
1655 .sampleRateHz = sample_rate,
1656 .channelMode = channel_mode,
1657 .bitsPerSample = bits_per_sample,
1658 };
1659 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
1660 DataMQDesc mq_desc;
1661 auto aidl_retval = audio_provider_->startSession(
1662 audio_port_, AudioConfiguration(pcm_config), latency_modes,
1663 &mq_desc);
1664 DataMQ data_mq(mq_desc);
1665
1666 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
1667 if (is_codec_config_valid) {
1668 EXPECT_TRUE(data_mq.isValid());
1669 }
1670 EXPECT_TRUE(audio_provider_->endSession().isOk());
1671 }
1672 }
1673 }
1674 }
1675
1676 /**
1677 * openProvider A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH
1678 */
1679 class BluetoothAudioProviderA2dpDecodingHardwareAidl
1680 : public BluetoothAudioProviderFactoryAidl {
1681 public:
SetUp()1682 virtual void SetUp() override {
1683 BluetoothAudioProviderFactoryAidl::SetUp();
1684 GetProviderCapabilitiesHelper(
1685 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
1686 OpenProviderHelper(SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
1687 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
1688 audio_provider_ != nullptr);
1689 }
1690
TearDown()1691 virtual void TearDown() override {
1692 audio_port_ = nullptr;
1693 audio_provider_ = nullptr;
1694 BluetoothAudioProviderFactoryAidl::TearDown();
1695 }
1696
IsOffloadSupported()1697 bool IsOffloadSupported() { return (temp_provider_capabilities_.size() > 0); }
1698 };
1699
1700 /**
1701 * Test whether we can open a provider of type
1702 */
TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,OpenA2dpDecodingHardwareProvider)1703 TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
1704 OpenA2dpDecodingHardwareProvider) {}
1705
1706 /**
1707 * Test whether each provider of type
1708 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
1709 * SBC hardware encoding config
1710 */
TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,StartAndEndA2dpSbcDecodingHardwareSession)1711 TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
1712 StartAndEndA2dpSbcDecodingHardwareSession) {
1713 if (!IsOffloadSupported()) {
1714 return;
1715 }
1716
1717 CodecConfiguration codec_config = {
1718 .codecType = CodecType::SBC,
1719 .encodedAudioBitrate = 328000,
1720 .peerMtu = 1005,
1721 .isScmstEnabled = false,
1722 };
1723 auto sbc_codec_specifics = GetSbcCodecSpecificSupportedList(true);
1724
1725 for (auto& codec_specific : sbc_codec_specifics) {
1726 copy_codec_specific(codec_config.config, codec_specific);
1727 DataMQDesc mq_desc;
1728 auto aidl_retval = audio_provider_->startSession(
1729 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
1730
1731 ASSERT_TRUE(aidl_retval.isOk());
1732 EXPECT_TRUE(audio_provider_->endSession().isOk());
1733 }
1734 }
1735
1736 /**
1737 * Test whether each provider of type
1738 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
1739 * AAC hardware encoding config
1740 */
TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,StartAndEndA2dpAacDecodingHardwareSession)1741 TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
1742 StartAndEndA2dpAacDecodingHardwareSession) {
1743 if (!IsOffloadSupported()) {
1744 return;
1745 }
1746
1747 CodecConfiguration codec_config = {
1748 .codecType = CodecType::AAC,
1749 .encodedAudioBitrate = 320000,
1750 .peerMtu = 1005,
1751 .isScmstEnabled = false,
1752 };
1753 auto aac_codec_specifics = GetAacCodecSpecificSupportedList(true);
1754
1755 for (auto& codec_specific : aac_codec_specifics) {
1756 copy_codec_specific(codec_config.config, codec_specific);
1757 DataMQDesc mq_desc;
1758 auto aidl_retval = audio_provider_->startSession(
1759 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
1760
1761 ASSERT_TRUE(aidl_retval.isOk());
1762 EXPECT_TRUE(audio_provider_->endSession().isOk());
1763 }
1764 }
1765
1766 /**
1767 * Test whether each provider of type
1768 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
1769 * LDAC hardware encoding config
1770 */
TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,StartAndEndA2dpLdacDecodingHardwareSession)1771 TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
1772 StartAndEndA2dpLdacDecodingHardwareSession) {
1773 if (!IsOffloadSupported()) {
1774 return;
1775 }
1776
1777 CodecConfiguration codec_config = {
1778 .codecType = CodecType::LDAC,
1779 .encodedAudioBitrate = 990000,
1780 .peerMtu = 1005,
1781 .isScmstEnabled = false,
1782 };
1783 auto ldac_codec_specifics = GetLdacCodecSpecificSupportedList(true);
1784
1785 for (auto& codec_specific : ldac_codec_specifics) {
1786 copy_codec_specific(codec_config.config, codec_specific);
1787 DataMQDesc mq_desc;
1788 auto aidl_retval = audio_provider_->startSession(
1789 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
1790
1791 ASSERT_TRUE(aidl_retval.isOk());
1792 EXPECT_TRUE(audio_provider_->endSession().isOk());
1793 }
1794 }
1795
1796 /**
1797 * Test whether each provider of type
1798 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
1799 * Opus hardware encoding config
1800 */
TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,StartAndEndA2dpOpusDecodingHardwareSession)1801 TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
1802 StartAndEndA2dpOpusDecodingHardwareSession) {
1803 if (!IsOffloadSupported()) {
1804 return;
1805 }
1806
1807 CodecConfiguration codec_config = {
1808 .codecType = CodecType::OPUS,
1809 .encodedAudioBitrate = 990000,
1810 .peerMtu = 1005,
1811 .isScmstEnabled = false,
1812 };
1813 auto opus_codec_specifics = GetOpusCodecSpecificSupportedList(true);
1814
1815 for (auto& codec_specific : opus_codec_specifics) {
1816 copy_codec_specific(codec_config.config, codec_specific);
1817 DataMQDesc mq_desc;
1818 auto aidl_retval = audio_provider_->startSession(
1819 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
1820
1821 ASSERT_TRUE(aidl_retval.isOk());
1822 EXPECT_TRUE(audio_provider_->endSession().isOk());
1823 }
1824 }
1825
1826 /**
1827 * Test whether each provider of type
1828 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
1829 * AptX hardware encoding config
1830 */
TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,StartAndEndA2dpAptxDecodingHardwareSession)1831 TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
1832 StartAndEndA2dpAptxDecodingHardwareSession) {
1833 if (!IsOffloadSupported()) {
1834 return;
1835 }
1836
1837 for (auto codec_type : {CodecType::APTX, CodecType::APTX_HD}) {
1838 CodecConfiguration codec_config = {
1839 .codecType = codec_type,
1840 .encodedAudioBitrate =
1841 (codec_type == CodecType::APTX ? 352000 : 576000),
1842 .peerMtu = 1005,
1843 .isScmstEnabled = false,
1844 };
1845
1846 auto aptx_codec_specifics = GetAptxCodecSpecificSupportedList(
1847 (codec_type == CodecType::APTX_HD ? true : false), true);
1848
1849 for (auto& codec_specific : aptx_codec_specifics) {
1850 copy_codec_specific(codec_config.config, codec_specific);
1851 DataMQDesc mq_desc;
1852 auto aidl_retval = audio_provider_->startSession(
1853 audio_port_, AudioConfiguration(codec_config), latency_modes,
1854 &mq_desc);
1855
1856 ASSERT_TRUE(aidl_retval.isOk());
1857 EXPECT_TRUE(audio_provider_->endSession().isOk());
1858 }
1859 }
1860 }
1861
1862 /**
1863 * Test whether each provider of type
1864 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
1865 * an invalid codec config
1866 */
TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,StartAndEndA2dpDecodingHardwareSessionInvalidCodecConfig)1867 TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
1868 StartAndEndA2dpDecodingHardwareSessionInvalidCodecConfig) {
1869 if (!IsOffloadSupported()) {
1870 return;
1871 }
1872 ASSERT_NE(audio_provider_, nullptr);
1873
1874 std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
1875 for (auto codec_type : a2dp_codec_types) {
1876 switch (codec_type) {
1877 case CodecType::SBC:
1878 codec_specifics = GetSbcCodecSpecificSupportedList(false);
1879 break;
1880 case CodecType::AAC:
1881 codec_specifics = GetAacCodecSpecificSupportedList(false);
1882 break;
1883 case CodecType::LDAC:
1884 codec_specifics = GetLdacCodecSpecificSupportedList(false);
1885 break;
1886 case CodecType::APTX:
1887 codec_specifics = GetAptxCodecSpecificSupportedList(false, false);
1888 break;
1889 case CodecType::APTX_HD:
1890 codec_specifics = GetAptxCodecSpecificSupportedList(true, false);
1891 break;
1892 case CodecType::OPUS:
1893 codec_specifics = GetOpusCodecSpecificSupportedList(false);
1894 continue;
1895 case CodecType::APTX_ADAPTIVE:
1896 case CodecType::LC3:
1897 case CodecType::VENDOR:
1898 case CodecType::UNKNOWN:
1899 codec_specifics.clear();
1900 break;
1901 }
1902 if (codec_specifics.empty()) {
1903 continue;
1904 }
1905
1906 CodecConfiguration codec_config = {
1907 .codecType = codec_type,
1908 .encodedAudioBitrate = 328000,
1909 .peerMtu = 1005,
1910 .isScmstEnabled = false,
1911 };
1912 for (auto codec_specific : codec_specifics) {
1913 copy_codec_specific(codec_config.config, codec_specific);
1914 DataMQDesc mq_desc;
1915 auto aidl_retval = audio_provider_->startSession(
1916 audio_port_, AudioConfiguration(codec_config), latency_modes,
1917 &mq_desc);
1918
1919 // AIDL call should fail on invalid codec
1920 ASSERT_FALSE(aidl_retval.isOk());
1921 EXPECT_TRUE(audio_provider_->endSession().isOk());
1922 }
1923 }
1924 }
1925
1926 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
1927 BluetoothAudioProviderFactoryAidl);
1928 INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderFactoryAidl,
1929 testing::ValuesIn(android::getAidlHalInstanceNames(
1930 IBluetoothAudioProviderFactory::descriptor)),
1931 android::PrintInstanceNameToString);
1932
1933 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
1934 BluetoothAudioProviderA2dpEncodingSoftwareAidl);
1935 INSTANTIATE_TEST_SUITE_P(PerInstance,
1936 BluetoothAudioProviderA2dpEncodingSoftwareAidl,
1937 testing::ValuesIn(android::getAidlHalInstanceNames(
1938 IBluetoothAudioProviderFactory::descriptor)),
1939 android::PrintInstanceNameToString);
1940
1941 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
1942 BluetoothAudioProviderA2dpEncodingHardwareAidl);
1943 INSTANTIATE_TEST_SUITE_P(PerInstance,
1944 BluetoothAudioProviderA2dpEncodingHardwareAidl,
1945 testing::ValuesIn(android::getAidlHalInstanceNames(
1946 IBluetoothAudioProviderFactory::descriptor)),
1947 android::PrintInstanceNameToString);
1948
1949 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
1950 BluetoothAudioProviderHearingAidSoftwareAidl);
1951 INSTANTIATE_TEST_SUITE_P(PerInstance,
1952 BluetoothAudioProviderHearingAidSoftwareAidl,
1953 testing::ValuesIn(android::getAidlHalInstanceNames(
1954 IBluetoothAudioProviderFactory::descriptor)),
1955 android::PrintInstanceNameToString);
1956
1957 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
1958 BluetoothAudioProviderLeAudioOutputSoftwareAidl);
1959 INSTANTIATE_TEST_SUITE_P(PerInstance,
1960 BluetoothAudioProviderLeAudioOutputSoftwareAidl,
1961 testing::ValuesIn(android::getAidlHalInstanceNames(
1962 IBluetoothAudioProviderFactory::descriptor)),
1963 android::PrintInstanceNameToString);
1964
1965 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
1966 BluetoothAudioProviderLeAudioInputSoftwareAidl);
1967 INSTANTIATE_TEST_SUITE_P(PerInstance,
1968 BluetoothAudioProviderLeAudioInputSoftwareAidl,
1969 testing::ValuesIn(android::getAidlHalInstanceNames(
1970 IBluetoothAudioProviderFactory::descriptor)),
1971 android::PrintInstanceNameToString);
1972
1973 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
1974 BluetoothAudioProviderLeAudioOutputHardwareAidl);
1975 INSTANTIATE_TEST_SUITE_P(PerInstance,
1976 BluetoothAudioProviderLeAudioOutputHardwareAidl,
1977 testing::ValuesIn(android::getAidlHalInstanceNames(
1978 IBluetoothAudioProviderFactory::descriptor)),
1979 android::PrintInstanceNameToString);
1980
1981 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
1982 BluetoothAudioProviderLeAudioInputHardwareAidl);
1983 INSTANTIATE_TEST_SUITE_P(PerInstance,
1984 BluetoothAudioProviderLeAudioInputHardwareAidl,
1985 testing::ValuesIn(android::getAidlHalInstanceNames(
1986 IBluetoothAudioProviderFactory::descriptor)),
1987 android::PrintInstanceNameToString);
1988
1989 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
1990 BluetoothAudioProviderLeAudioBroadcastSoftwareAidl);
1991 INSTANTIATE_TEST_SUITE_P(PerInstance,
1992 BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
1993 testing::ValuesIn(android::getAidlHalInstanceNames(
1994 IBluetoothAudioProviderFactory::descriptor)),
1995 android::PrintInstanceNameToString);
1996
1997 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
1998 BluetoothAudioProviderLeAudioBroadcastHardwareAidl);
1999 INSTANTIATE_TEST_SUITE_P(PerInstance,
2000 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
2001 testing::ValuesIn(android::getAidlHalInstanceNames(
2002 IBluetoothAudioProviderFactory::descriptor)),
2003 android::PrintInstanceNameToString);
2004
2005 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
2006 BluetoothAudioProviderA2dpDecodingSoftwareAidl);
2007 INSTANTIATE_TEST_SUITE_P(PerInstance,
2008 BluetoothAudioProviderA2dpDecodingSoftwareAidl,
2009 testing::ValuesIn(android::getAidlHalInstanceNames(
2010 IBluetoothAudioProviderFactory::descriptor)),
2011 android::PrintInstanceNameToString);
2012
2013 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
2014 BluetoothAudioProviderA2dpDecodingHardwareAidl);
2015 INSTANTIATE_TEST_SUITE_P(PerInstance,
2016 BluetoothAudioProviderA2dpDecodingHardwareAidl,
2017 testing::ValuesIn(android::getAidlHalInstanceNames(
2018 IBluetoothAudioProviderFactory::descriptor)),
2019 android::PrintInstanceNameToString);
2020
main(int argc,char ** argv)2021 int main(int argc, char** argv) {
2022 ::testing::InitGoogleTest(&argc, argv);
2023 ABinderProcess_setThreadPoolMaxThreadCount(1);
2024 ABinderProcess_startThreadPool();
2025 return RUN_ALL_TESTS();
2026 }
2027