blob: 4032407a93a3a6bebc23d7d6f279f1820e848937 [file] [log] [blame]
Josh Wu049e2cd2022-01-12 05:42:58 -08001/*
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 <fmq/AidlMessageQueue.h>
27
28#include <cstdint>
29#include <future>
30#include <unordered_set>
31#include <vector>
32
33using aidl::android::hardware::audio::common::SinkMetadata;
34using aidl::android::hardware::audio::common::SourceMetadata;
35using aidl::android::hardware::bluetooth::audio::AacCapabilities;
36using aidl::android::hardware::bluetooth::audio::AacConfiguration;
37using aidl::android::hardware::bluetooth::audio::AptxCapabilities;
38using aidl::android::hardware::bluetooth::audio::AptxConfiguration;
39using aidl::android::hardware::bluetooth::audio::AudioCapabilities;
40using aidl::android::hardware::bluetooth::audio::AudioConfiguration;
41using aidl::android::hardware::bluetooth::audio::BnBluetoothAudioPort;
42using aidl::android::hardware::bluetooth::audio::ChannelMode;
43using aidl::android::hardware::bluetooth::audio::CodecCapabilities;
44using aidl::android::hardware::bluetooth::audio::CodecConfiguration;
45using aidl::android::hardware::bluetooth::audio::CodecType;
46using aidl::android::hardware::bluetooth::audio::IBluetoothAudioPort;
47using aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider;
48using aidl::android::hardware::bluetooth::audio::IBluetoothAudioProviderFactory;
49using aidl::android::hardware::bluetooth::audio::LatencyMode;
50using aidl::android::hardware::bluetooth::audio::Lc3Capabilities;
51using aidl::android::hardware::bluetooth::audio::Lc3Configuration;
52using aidl::android::hardware::bluetooth::audio::LdacCapabilities;
53using aidl::android::hardware::bluetooth::audio::LdacConfiguration;
54using aidl::android::hardware::bluetooth::audio::
55 LeAudioCodecCapabilitiesSetting;
56using aidl::android::hardware::bluetooth::audio::LeAudioCodecConfiguration;
57using aidl::android::hardware::bluetooth::audio::LeAudioConfiguration;
58using aidl::android::hardware::bluetooth::audio::PcmConfiguration;
59using aidl::android::hardware::bluetooth::audio::PresentationPosition;
60using aidl::android::hardware::bluetooth::audio::SbcAllocMethod;
61using aidl::android::hardware::bluetooth::audio::SbcCapabilities;
62using aidl::android::hardware::bluetooth::audio::SbcChannelMode;
63using aidl::android::hardware::bluetooth::audio::SbcConfiguration;
64using aidl::android::hardware::bluetooth::audio::SessionType;
65using aidl::android::hardware::bluetooth::audio::UnicastCapability;
66using aidl::android::hardware::common::fmq::MQDescriptor;
67using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
68using android::AidlMessageQueue;
69using android::ProcessState;
70using android::String16;
71using ndk::ScopedAStatus;
72using ndk::SpAIBinder;
73
74using MqDataType = int8_t;
75using MqDataMode = SynchronizedReadWrite;
76using DataMQ = AidlMessageQueue<MqDataType, MqDataMode>;
77using DataMQDesc = MQDescriptor<MqDataType, MqDataMode>;
78
79// Constants
80
81static constexpr int32_t a2dp_sample_rates[] = {0, 44100, 48000, 88200, 96000};
82static constexpr int8_t a2dp_bits_per_samples[] = {0, 16, 24, 32};
83static constexpr ChannelMode a2dp_channel_modes[] = {
84 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
85static constexpr CodecType a2dp_codec_types[] = {
86 CodecType::UNKNOWN, CodecType::SBC, CodecType::AAC,
87 CodecType::APTX, CodecType::APTX_HD, CodecType::LDAC,
88 CodecType::LC3, CodecType::APTX_ADAPTIVE};
Chen Chenc92270e2022-02-14 18:29:52 -080089static std::vector<LatencyMode> latency_modes = {LatencyMode::FREE};
Josh Wu049e2cd2022-01-12 05:42:58 -080090// Helpers
91
92template <typename T>
93struct identity {
94 typedef T type;
95};
96
97template <class T>
98bool contained_in_vector(const std::vector<T>& vector,
99 const typename identity<T>::type& target) {
100 return std::find(vector.begin(), vector.end(), target) != vector.end();
101}
102
103void copy_codec_specific(CodecConfiguration::CodecSpecific& dst,
104 const CodecConfiguration::CodecSpecific& src) {
105 switch (src.getTag()) {
106 case CodecConfiguration::CodecSpecific::sbcConfig:
107 dst.set<CodecConfiguration::CodecSpecific::sbcConfig>(
108 src.get<CodecConfiguration::CodecSpecific::sbcConfig>());
109 break;
110 case CodecConfiguration::CodecSpecific::aacConfig:
111 dst.set<CodecConfiguration::CodecSpecific::aacConfig>(
112 src.get<CodecConfiguration::CodecSpecific::aacConfig>());
113 break;
114 case CodecConfiguration::CodecSpecific::ldacConfig:
115 dst.set<CodecConfiguration::CodecSpecific::ldacConfig>(
116 src.get<CodecConfiguration::CodecSpecific::ldacConfig>());
117 break;
118 case CodecConfiguration::CodecSpecific::aptxConfig:
119 dst.set<CodecConfiguration::CodecSpecific::aptxConfig>(
120 src.get<CodecConfiguration::CodecSpecific::aptxConfig>());
121 break;
122 case CodecConfiguration::CodecSpecific::lc3Config:
123 dst.set<CodecConfiguration::CodecSpecific::lc3Config>(
124 src.get<CodecConfiguration::CodecSpecific::lc3Config>());
125 break;
126 case CodecConfiguration::CodecSpecific::aptxAdaptiveConfig:
127 dst.set<CodecConfiguration::CodecSpecific::aptxAdaptiveConfig>(
128 src.get<CodecConfiguration::CodecSpecific::aptxAdaptiveConfig>());
129 break;
130 default:
131 break;
132 }
133}
134
135class BluetoothAudioPort : public BnBluetoothAudioPort {
136 public:
137 BluetoothAudioPort() {}
138
139 ndk::ScopedAStatus startStream() { return ScopedAStatus::ok(); }
140
141 ndk::ScopedAStatus suspendStream() { return ScopedAStatus::ok(); }
142
143 ndk::ScopedAStatus stopStream() { return ScopedAStatus::ok(); }
144
145 ndk::ScopedAStatus getPresentationPosition(PresentationPosition*) {
146 return ScopedAStatus::ok();
147 }
148
149 ndk::ScopedAStatus updateSourceMetadata(const SourceMetadata&) {
150 return ScopedAStatus::ok();
151 }
152
153 ndk::ScopedAStatus updateSinkMetadata(const SinkMetadata&) {
154 return ScopedAStatus::ok();
155 }
156
157 ndk::ScopedAStatus setLatencyMode(const LatencyMode) {
158 return ScopedAStatus::ok();
159 }
160
161 ndk::ScopedAStatus setCodecType(const CodecType) {
162 return ScopedAStatus::ok();
163 }
164
165 protected:
166 virtual ~BluetoothAudioPort() = default;
167};
168
169class BluetoothAudioProviderFactoryAidl
170 : public testing::TestWithParam<std::string> {
171 public:
172 virtual void SetUp() override {
173 provider_factory_ = IBluetoothAudioProviderFactory::fromBinder(
174 SpAIBinder(AServiceManager_getService(GetParam().c_str())));
175 audio_provider_ = nullptr;
176 ASSERT_NE(provider_factory_, nullptr);
177 }
178
179 virtual void TearDown() override { provider_factory_ = nullptr; }
180
181 void GetProviderCapabilitiesHelper(const SessionType& session_type) {
182 temp_provider_capabilities_.clear();
183 auto aidl_retval = provider_factory_->getProviderCapabilities(
184 session_type, &temp_provider_capabilities_);
185 // AIDL calls should not be failed and callback has to be executed
186 ASSERT_TRUE(aidl_retval.isOk());
187 switch (session_type) {
188 case SessionType::UNKNOWN: {
189 ASSERT_TRUE(temp_provider_capabilities_.empty());
190 } break;
191 case SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH:
192 case SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH:
193 case SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH:
194 case SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH:
195 case SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH: {
196 // All software paths are mandatory and must have exact 1
197 // "PcmParameters"
198 ASSERT_EQ(temp_provider_capabilities_.size(), 1);
199 ASSERT_EQ(temp_provider_capabilities_[0].getTag(),
200 AudioCapabilities::pcmCapabilities);
201 } break;
202 case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH: {
203 std::unordered_set<CodecType> codec_types;
204 // empty capability means offload is unsupported
205 for (auto& audio_capability : temp_provider_capabilities_) {
206 ASSERT_EQ(audio_capability.getTag(),
207 AudioCapabilities::a2dpCapabilities);
208 const auto& codec_capabilities =
209 audio_capability.get<AudioCapabilities::a2dpCapabilities>();
210 // Every codec can present once at most
211 ASSERT_EQ(codec_types.count(codec_capabilities.codecType), 0);
212 switch (codec_capabilities.codecType) {
213 case CodecType::SBC:
214 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
215 CodecCapabilities::Capabilities::sbcCapabilities);
216 break;
217 case CodecType::AAC:
218 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
219 CodecCapabilities::Capabilities::aacCapabilities);
220 break;
221 case CodecType::APTX:
222 case CodecType::APTX_HD:
223 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
224 CodecCapabilities::Capabilities::aptxCapabilities);
225 break;
226 case CodecType::LDAC:
227 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
228 CodecCapabilities::Capabilities::ldacCapabilities);
229 break;
230 case CodecType::LC3:
231 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
232 CodecCapabilities::Capabilities::lc3Capabilities);
233 break;
234 case CodecType::APTX_ADAPTIVE:
235 case CodecType::VENDOR:
236 case CodecType::UNKNOWN:
237 break;
238 }
239 codec_types.insert(codec_capabilities.codecType);
240 }
241 } break;
242 case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
243 case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
244 case SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH: {
245 ASSERT_FALSE(temp_provider_capabilities_.empty());
246 for (auto audio_capability : temp_provider_capabilities_) {
247 ASSERT_EQ(audio_capability.getTag(),
248 AudioCapabilities::leAudioCapabilities);
249 }
250 } break;
251 }
252 }
253
254 /***
255 * This helps to open the specified provider and check the openProvider()
256 * has corruct return values. BUT, to keep it simple, it does not consider
257 * the capability, and please do so at the SetUp of each session's test.
258 ***/
259 void OpenProviderHelper(const SessionType& session_type) {
260 auto aidl_retval =
261 provider_factory_->openProvider(session_type, &audio_provider_);
262 if (aidl_retval.isOk()) {
263 ASSERT_NE(session_type, SessionType::UNKNOWN);
264 ASSERT_NE(audio_provider_, nullptr);
265 audio_port_ = ndk::SharedRefBase::make<BluetoothAudioPort>();
266 } else {
267 // Hardware offloading is optional
268 ASSERT_TRUE(
269 session_type == SessionType::UNKNOWN ||
270 session_type ==
271 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
272 session_type ==
273 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
274 session_type ==
275 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
276 session_type ==
277 SessionType::
278 LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
279 ASSERT_EQ(audio_provider_, nullptr);
280 }
281 }
282
283 bool IsPcmConfigSupported(const PcmConfiguration& pcm_config) {
284 if (temp_provider_capabilities_.size() != 1 ||
285 temp_provider_capabilities_[0].getTag() !=
286 AudioCapabilities::pcmCapabilities) {
287 return false;
288 }
289 auto pcm_capability = temp_provider_capabilities_[0]
290 .get<AudioCapabilities::pcmCapabilities>();
291 return (contained_in_vector(pcm_capability.channelMode,
292 pcm_config.channelMode) &&
293 contained_in_vector(pcm_capability.sampleRateHz,
294 pcm_config.sampleRateHz) &&
295 contained_in_vector(pcm_capability.bitsPerSample,
296 pcm_config.bitsPerSample));
297 }
298
299 std::shared_ptr<IBluetoothAudioProviderFactory> provider_factory_;
300 std::shared_ptr<IBluetoothAudioProvider> audio_provider_;
301 std::shared_ptr<IBluetoothAudioPort> audio_port_;
302 std::vector<AudioCapabilities> temp_provider_capabilities_;
303
304 static constexpr SessionType kSessionTypes[] = {
305 SessionType::UNKNOWN,
306 SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
307 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
308 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
309 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
310 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
311 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
312 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
313 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
314 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
315 };
316};
317
318/**
319 * Test whether we can get the FactoryService from HIDL
320 */
321TEST_P(BluetoothAudioProviderFactoryAidl, GetProviderFactoryService) {}
322
323/**
324 * Test whether we can open a provider for each provider returned by
325 * getProviderCapabilities() with non-empty capabalities
326 */
327TEST_P(BluetoothAudioProviderFactoryAidl,
328 OpenProviderAndCheckCapabilitiesBySession) {
329 for (auto session_type : kSessionTypes) {
330 GetProviderCapabilitiesHelper(session_type);
331 OpenProviderHelper(session_type);
332 // We must be able to open a provider if its getProviderCapabilities()
333 // returns non-empty list.
334 EXPECT_TRUE(temp_provider_capabilities_.empty() ||
335 audio_provider_ != nullptr);
336 }
337}
338
339/**
340 * openProvider A2DP_SOFTWARE_ENCODING_DATAPATH
341 */
342class BluetoothAudioProviderA2dpSoftwareAidl
343 : public BluetoothAudioProviderFactoryAidl {
344 public:
345 virtual void SetUp() override {
346 BluetoothAudioProviderFactoryAidl::SetUp();
347 GetProviderCapabilitiesHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
348 OpenProviderHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
349 ASSERT_NE(audio_provider_, nullptr);
350 }
351
352 virtual void TearDown() override {
353 audio_port_ = nullptr;
354 audio_provider_ = nullptr;
355 BluetoothAudioProviderFactoryAidl::TearDown();
356 }
357};
358
359/**
360 * Test whether we can open a provider of type
361 */
362TEST_P(BluetoothAudioProviderA2dpSoftwareAidl, OpenA2dpSoftwareProvider) {}
363
364/**
365 * Test whether each provider of type
366 * SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH can be started and stopped with
367 * different PCM config
368 */
369TEST_P(BluetoothAudioProviderA2dpSoftwareAidl,
370 StartAndEndA2dpSoftwareSessionWithPossiblePcmConfig) {
371 for (auto sample_rate : a2dp_sample_rates) {
372 for (auto bits_per_sample : a2dp_bits_per_samples) {
373 for (auto channel_mode : a2dp_channel_modes) {
374 PcmConfiguration pcm_config{
375 .sampleRateHz = sample_rate,
376 .bitsPerSample = bits_per_sample,
377 .channelMode = channel_mode,
378 };
379 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
380 DataMQDesc mq_desc;
381 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -0800382 audio_port_, AudioConfiguration(pcm_config), latency_modes,
383 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -0800384 DataMQ data_mq(mq_desc);
385
386 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
387 if (is_codec_config_valid) {
388 EXPECT_TRUE(data_mq.isValid());
389 }
390 EXPECT_TRUE(audio_provider_->endSession().isOk());
391 }
392 }
393 }
394}
395
396/**
397 * openProvider A2DP_HARDWARE_OFFLOAD_DATAPATH
398 */
399class BluetoothAudioProviderA2dpHardwareAidl
400 : public BluetoothAudioProviderFactoryAidl {
401 public:
402 virtual void SetUp() override {
403 BluetoothAudioProviderFactoryAidl::SetUp();
404 GetProviderCapabilitiesHelper(
405 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
406 OpenProviderHelper(SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
407 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
408 audio_provider_ != nullptr);
409 }
410
411 virtual void TearDown() override {
412 audio_port_ = nullptr;
413 audio_provider_ = nullptr;
414 BluetoothAudioProviderFactoryAidl::TearDown();
415 }
416
417 bool IsOffloadSupported() { return (temp_provider_capabilities_.size() > 0); }
418
419 void GetA2dpOffloadCapabilityHelper(const CodecType& codec_type) {
420 temp_codec_capabilities_ = nullptr;
421 for (auto codec_capability : temp_provider_capabilities_) {
422 auto& a2dp_capabilities =
423 codec_capability.get<AudioCapabilities::a2dpCapabilities>();
424 if (a2dp_capabilities.codecType != codec_type) {
425 continue;
426 }
427 temp_codec_capabilities_ = &a2dp_capabilities;
428 }
429 }
430
431 std::vector<CodecConfiguration::CodecSpecific>
432 GetSbcCodecSpecificSupportedList(bool supported) {
433 std::vector<CodecConfiguration::CodecSpecific> sbc_codec_specifics;
434 if (!supported) {
435 SbcConfiguration sbc_config{.sampleRateHz = 0, .bitsPerSample = 0};
436 sbc_codec_specifics.push_back(
437 CodecConfiguration::CodecSpecific(sbc_config));
438 return sbc_codec_specifics;
439 }
440 GetA2dpOffloadCapabilityHelper(CodecType::SBC);
441 if (temp_codec_capabilities_ == nullptr ||
442 temp_codec_capabilities_->codecType != CodecType::SBC) {
443 return sbc_codec_specifics;
444 }
445 // parse the capability
446 auto& sbc_capability =
447 temp_codec_capabilities_->capabilities
448 .get<CodecCapabilities::Capabilities::sbcCapabilities>();
449 if (sbc_capability.minBitpool > sbc_capability.maxBitpool) {
450 return sbc_codec_specifics;
451 }
452
453 // combine those parameters into one list of
454 // CodecConfiguration::CodecSpecific
455 for (int32_t sample_rate : sbc_capability.sampleRateHz) {
456 for (int8_t block_length : sbc_capability.blockLength) {
457 for (int8_t num_subbands : sbc_capability.numSubbands) {
458 for (int8_t bits_per_sample : sbc_capability.bitsPerSample) {
459 for (auto channel_mode : sbc_capability.channelMode) {
460 for (auto alloc_method : sbc_capability.allocMethod) {
461 SbcConfiguration sbc_data = {
462 .sampleRateHz = sample_rate,
463 .channelMode = channel_mode,
464 .blockLength = block_length,
465 .numSubbands = num_subbands,
466 .allocMethod = alloc_method,
467 .bitsPerSample = bits_per_sample,
468 .minBitpool = sbc_capability.minBitpool,
469 .maxBitpool = sbc_capability.maxBitpool};
470 sbc_codec_specifics.push_back(
471 CodecConfiguration::CodecSpecific(sbc_data));
472 }
473 }
474 }
475 }
476 }
477 }
478 return sbc_codec_specifics;
479 }
480
481 std::vector<CodecConfiguration::CodecSpecific>
482 GetAacCodecSpecificSupportedList(bool supported) {
483 std::vector<CodecConfiguration::CodecSpecific> aac_codec_specifics;
484 if (!supported) {
485 AacConfiguration aac_config{.sampleRateHz = 0, .bitsPerSample = 0};
486 aac_codec_specifics.push_back(
487 CodecConfiguration::CodecSpecific(aac_config));
488 return aac_codec_specifics;
489 }
490 GetA2dpOffloadCapabilityHelper(CodecType::AAC);
491 if (temp_codec_capabilities_ == nullptr ||
492 temp_codec_capabilities_->codecType != CodecType::AAC) {
493 return aac_codec_specifics;
494 }
495 // parse the capability
496 auto& aac_capability =
497 temp_codec_capabilities_->capabilities
498 .get<CodecCapabilities::Capabilities::aacCapabilities>();
499
500 std::vector<bool> variable_bit_rate_enableds = {false};
501 if (aac_capability.variableBitRateSupported) {
502 variable_bit_rate_enableds.push_back(true);
503 }
504
505 // combine those parameters into one list of
506 // CodecConfiguration::CodecSpecific
507 for (auto object_type : aac_capability.objectType) {
508 for (int32_t sample_rate : aac_capability.sampleRateHz) {
509 for (auto channel_mode : aac_capability.channelMode) {
510 for (int8_t bits_per_sample : aac_capability.bitsPerSample) {
511 for (auto variable_bit_rate_enabled : variable_bit_rate_enableds) {
512 AacConfiguration aac_data{
513 .objectType = object_type,
514 .sampleRateHz = sample_rate,
515 .channelMode = channel_mode,
516 .variableBitRateEnabled = variable_bit_rate_enabled,
517 .bitsPerSample = bits_per_sample};
518 aac_codec_specifics.push_back(
519 CodecConfiguration::CodecSpecific(aac_data));
520 }
521 }
522 }
523 }
524 }
525 return aac_codec_specifics;
526 }
527
528 std::vector<CodecConfiguration::CodecSpecific>
529 GetLdacCodecSpecificSupportedList(bool supported) {
530 std::vector<CodecConfiguration::CodecSpecific> ldac_codec_specifics;
531 if (!supported) {
532 LdacConfiguration ldac_config{.sampleRateHz = 0, .bitsPerSample = 0};
533 ldac_codec_specifics.push_back(
534 CodecConfiguration::CodecSpecific(ldac_config));
535 return ldac_codec_specifics;
536 }
537 GetA2dpOffloadCapabilityHelper(CodecType::LDAC);
538 if (temp_codec_capabilities_ == nullptr ||
539 temp_codec_capabilities_->codecType != CodecType::LDAC) {
540 return ldac_codec_specifics;
541 }
542 // parse the capability
543 auto& ldac_capability =
544 temp_codec_capabilities_->capabilities
545 .get<CodecCapabilities::Capabilities::ldacCapabilities>();
546
547 // combine those parameters into one list of
548 // CodecConfiguration::CodecSpecific
549 for (int32_t sample_rate : ldac_capability.sampleRateHz) {
550 for (int8_t bits_per_sample : ldac_capability.bitsPerSample) {
551 for (auto channel_mode : ldac_capability.channelMode) {
552 for (auto quality_index : ldac_capability.qualityIndex) {
553 LdacConfiguration ldac_data{.sampleRateHz = sample_rate,
554 .channelMode = channel_mode,
555 .qualityIndex = quality_index,
556 .bitsPerSample = bits_per_sample};
557 ldac_codec_specifics.push_back(
558 CodecConfiguration::CodecSpecific(ldac_data));
559 }
560 }
561 }
562 }
563 return ldac_codec_specifics;
564 }
565
566 std::vector<CodecConfiguration::CodecSpecific>
567 GetAptxCodecSpecificSupportedList(bool is_hd, bool supported) {
568 std::vector<CodecConfiguration::CodecSpecific> aptx_codec_specifics;
569 if (!supported) {
570 AptxConfiguration aptx_config{.sampleRateHz = 0, .bitsPerSample = 0};
571 aptx_codec_specifics.push_back(
572 CodecConfiguration::CodecSpecific(aptx_config));
573 return aptx_codec_specifics;
574 }
575 GetA2dpOffloadCapabilityHelper(
576 (is_hd ? CodecType::APTX_HD : CodecType::APTX));
577 if (temp_codec_capabilities_ == nullptr) {
578 return aptx_codec_specifics;
579 }
580 if ((is_hd && temp_codec_capabilities_->codecType != CodecType::APTX_HD) ||
581 (!is_hd && temp_codec_capabilities_->codecType != CodecType::APTX)) {
582 return aptx_codec_specifics;
583 }
584
585 // parse the capability
586 auto& aptx_capability =
587 temp_codec_capabilities_->capabilities
588 .get<CodecCapabilities::Capabilities::aptxCapabilities>();
589
590 // combine those parameters into one list of
591 // CodecConfiguration::CodecSpecific
592 for (int8_t bits_per_sample : aptx_capability.bitsPerSample) {
593 for (int32_t sample_rate : aptx_capability.sampleRateHz) {
594 for (auto channel_mode : aptx_capability.channelMode) {
595 AptxConfiguration aptx_data{.sampleRateHz = sample_rate,
596 .channelMode = channel_mode,
597 .bitsPerSample = bits_per_sample};
598 aptx_codec_specifics.push_back(
599 CodecConfiguration::CodecSpecific(aptx_data));
600 }
601 }
602 }
603 return aptx_codec_specifics;
604 }
605
606 std::vector<CodecConfiguration::CodecSpecific>
607 GetLc3CodecSpecificSupportedList(bool supported) {
608 std::vector<CodecConfiguration::CodecSpecific> lc3_codec_specifics;
609 if (!supported) {
610 Lc3Configuration lc3_config{.samplingFrequencyHz = 0,
611 .frameDurationUs = 0};
612 lc3_codec_specifics.push_back(
613 CodecConfiguration::CodecSpecific(lc3_config));
614 return lc3_codec_specifics;
615 }
616 GetA2dpOffloadCapabilityHelper(CodecType::LC3);
617 if (temp_codec_capabilities_ == nullptr ||
618 temp_codec_capabilities_->codecType != CodecType::LC3) {
619 return lc3_codec_specifics;
620 }
621 // parse the capability
622 auto& lc3_capability =
623 temp_codec_capabilities_->capabilities
624 .get<CodecCapabilities::Capabilities::lc3Capabilities>();
625
626 // combine those parameters into one list of
627 // CodecConfiguration::CodecSpecific
628 for (int32_t samplingFrequencyHz : lc3_capability.samplingFrequencyHz) {
629 for (int32_t frameDurationUs : lc3_capability.frameDurationUs) {
630 for (auto channel_mode : lc3_capability.channelMode) {
631 Lc3Configuration lc3_data{.samplingFrequencyHz = samplingFrequencyHz,
632 .channelMode = channel_mode,
633 .frameDurationUs = frameDurationUs};
634 lc3_codec_specifics.push_back(
635 CodecConfiguration::CodecSpecific(lc3_data));
636 }
637 }
638 }
639 return lc3_codec_specifics;
640 }
641
642 // temp storage saves the specified codec capability by
643 // GetOffloadCodecCapabilityHelper()
644 CodecCapabilities* temp_codec_capabilities_;
645};
646
647/**
648 * Test whether we can open a provider of type
649 */
650TEST_P(BluetoothAudioProviderA2dpHardwareAidl, OpenA2dpHardwareProvider) {}
651
652/**
653 * Test whether each provider of type
654 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
655 * SBC hardware encoding config
656 */
657TEST_P(BluetoothAudioProviderA2dpHardwareAidl,
658 StartAndEndA2dpSbcHardwareSession) {
659 if (!IsOffloadSupported()) {
660 return;
661 }
662
663 CodecConfiguration codec_config = {
664 .codecType = CodecType::SBC,
665 .encodedAudioBitrate = 328000,
666 .peerMtu = 1005,
667 .isScmstEnabled = false,
668 };
669 auto sbc_codec_specifics = GetSbcCodecSpecificSupportedList(true);
670
671 for (auto& codec_specific : sbc_codec_specifics) {
672 copy_codec_specific(codec_config.config, codec_specific);
673 DataMQDesc mq_desc;
674 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -0800675 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -0800676
677 ASSERT_TRUE(aidl_retval.isOk());
678 EXPECT_TRUE(audio_provider_->endSession().isOk());
679 }
680}
681
682/**
683 * Test whether each provider of type
684 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
685 * AAC hardware encoding config
686 */
687TEST_P(BluetoothAudioProviderA2dpHardwareAidl,
688 StartAndEndA2dpAacHardwareSession) {
689 if (!IsOffloadSupported()) {
690 return;
691 }
692
693 CodecConfiguration codec_config = {
694 .codecType = CodecType::AAC,
695 .encodedAudioBitrate = 320000,
696 .peerMtu = 1005,
697 .isScmstEnabled = false,
698 };
699 auto aac_codec_specifics = GetAacCodecSpecificSupportedList(true);
700
701 for (auto& codec_specific : aac_codec_specifics) {
702 copy_codec_specific(codec_config.config, codec_specific);
703 DataMQDesc mq_desc;
704 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -0800705 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -0800706
707 ASSERT_TRUE(aidl_retval.isOk());
708 EXPECT_TRUE(audio_provider_->endSession().isOk());
709 }
710}
711
712/**
713 * Test whether each provider of type
714 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
715 * LDAC hardware encoding config
716 */
717TEST_P(BluetoothAudioProviderA2dpHardwareAidl,
718 StartAndEndA2dpLdacHardwareSession) {
719 if (!IsOffloadSupported()) {
720 return;
721 }
722
723 CodecConfiguration codec_config = {
724 .codecType = CodecType::LDAC,
725 .encodedAudioBitrate = 990000,
726 .peerMtu = 1005,
727 .isScmstEnabled = false,
728 };
729 auto ldac_codec_specifics = GetLdacCodecSpecificSupportedList(true);
730
731 for (auto& codec_specific : ldac_codec_specifics) {
732 copy_codec_specific(codec_config.config, codec_specific);
733 DataMQDesc mq_desc;
734 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -0800735 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -0800736
737 ASSERT_TRUE(aidl_retval.isOk());
738 EXPECT_TRUE(audio_provider_->endSession().isOk());
739 }
740}
741
742/**
743 * Test whether each provider of type
744 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
745 * LDAC hardware encoding config
746 */
747TEST_P(BluetoothAudioProviderA2dpHardwareAidl,
748 StartAndEndA2dpLc3HardwareSession) {
749 if (!IsOffloadSupported()) {
750 return;
751 }
752
753 CodecConfiguration codec_config = {
754 .codecType = CodecType::LC3,
755 .encodedAudioBitrate = 990000,
756 .peerMtu = 1005,
757 .isScmstEnabled = false,
758 };
759 auto lc3_codec_specifics = GetLc3CodecSpecificSupportedList(true);
760
761 for (auto& codec_specific : lc3_codec_specifics) {
762 copy_codec_specific(codec_config.config, codec_specific);
763 DataMQDesc mq_desc;
764 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -0800765 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -0800766
767 ASSERT_TRUE(aidl_retval.isOk());
768 EXPECT_TRUE(audio_provider_->endSession().isOk());
769 }
770}
771
772/**
773 * Test whether each provider of type
774 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
775 * AptX hardware encoding config
776 */
777TEST_P(BluetoothAudioProviderA2dpHardwareAidl,
778 StartAndEndA2dpAptxHardwareSession) {
779 if (!IsOffloadSupported()) {
780 return;
781 }
782
783 for (auto codec_type : {CodecType::APTX, CodecType::APTX_HD}) {
784 CodecConfiguration codec_config = {
785 .codecType = codec_type,
786 .encodedAudioBitrate =
787 (codec_type == CodecType::APTX ? 352000 : 576000),
788 .peerMtu = 1005,
789 .isScmstEnabled = false,
790 };
791
792 auto aptx_codec_specifics = GetAptxCodecSpecificSupportedList(
793 (codec_type == CodecType::APTX_HD ? true : false), true);
794
795 for (auto& codec_specific : aptx_codec_specifics) {
796 copy_codec_specific(codec_config.config, codec_specific);
797 DataMQDesc mq_desc;
798 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -0800799 audio_port_, AudioConfiguration(codec_config), latency_modes,
800 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -0800801
802 ASSERT_TRUE(aidl_retval.isOk());
803 EXPECT_TRUE(audio_provider_->endSession().isOk());
804 }
805 }
806}
807
808/**
809 * Test whether each provider of type
810 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
811 * an invalid codec config
812 */
813TEST_P(BluetoothAudioProviderA2dpHardwareAidl,
814 StartAndEndA2dpHardwareSessionInvalidCodecConfig) {
815 if (!IsOffloadSupported()) {
816 return;
817 }
818 ASSERT_NE(audio_provider_, nullptr);
819
820 std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
821 for (auto codec_type : a2dp_codec_types) {
822 switch (codec_type) {
823 case CodecType::SBC:
824 codec_specifics = GetSbcCodecSpecificSupportedList(false);
825 break;
826 case CodecType::AAC:
827 codec_specifics = GetAacCodecSpecificSupportedList(false);
828 break;
829 case CodecType::LDAC:
830 codec_specifics = GetLdacCodecSpecificSupportedList(false);
831 break;
832 case CodecType::APTX:
833 codec_specifics = GetAptxCodecSpecificSupportedList(false, false);
834 break;
835 case CodecType::APTX_HD:
836 codec_specifics = GetAptxCodecSpecificSupportedList(true, false);
837 break;
838 case CodecType::LC3:
839 codec_specifics = GetLc3CodecSpecificSupportedList(false);
840 continue;
841 case CodecType::APTX_ADAPTIVE:
842 case CodecType::VENDOR:
843 case CodecType::UNKNOWN:
844 codec_specifics.clear();
845 break;
846 }
847 if (codec_specifics.empty()) {
848 continue;
849 }
850
851 CodecConfiguration codec_config = {
852 .codecType = codec_type,
853 .encodedAudioBitrate = 328000,
854 .peerMtu = 1005,
855 .isScmstEnabled = false,
856 };
857 for (auto codec_specific : codec_specifics) {
858 copy_codec_specific(codec_config.config, codec_specific);
859 DataMQDesc mq_desc;
860 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -0800861 audio_port_, AudioConfiguration(codec_config), latency_modes,
862 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -0800863
864 // AIDL call should fail on invalid codec
865 ASSERT_FALSE(aidl_retval.isOk());
866 EXPECT_TRUE(audio_provider_->endSession().isOk());
867 }
868 }
869}
870
871/**
872 * openProvider HEARING_AID_SOFTWARE_ENCODING_DATAPATH
873 */
874class BluetoothAudioProviderHearingAidSoftwareAidl
875 : public BluetoothAudioProviderFactoryAidl {
876 public:
877 virtual void SetUp() override {
878 BluetoothAudioProviderFactoryAidl::SetUp();
879 GetProviderCapabilitiesHelper(
880 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
881 OpenProviderHelper(SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
882 ASSERT_NE(audio_provider_, nullptr);
883 }
884
885 virtual void TearDown() override {
886 audio_port_ = nullptr;
887 audio_provider_ = nullptr;
888 BluetoothAudioProviderFactoryAidl::TearDown();
889 }
890
891 static constexpr int32_t hearing_aid_sample_rates_[] = {0, 16000, 24000};
892 static constexpr int8_t hearing_aid_bits_per_samples_[] = {0, 16, 24};
893 static constexpr ChannelMode hearing_aid_channel_modes_[] = {
894 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
895};
896
897/**
898 * Test whether we can open a provider of type
899 */
900TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl,
901 OpenHearingAidSoftwareProvider) {}
902
903/**
904 * Test whether each provider of type
905 * SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH can be started and
906 * stopped with different PCM config
907 */
908TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl,
909 StartAndEndHearingAidSessionWithPossiblePcmConfig) {
910 for (int32_t sample_rate : hearing_aid_sample_rates_) {
911 for (int8_t bits_per_sample : hearing_aid_bits_per_samples_) {
912 for (auto channel_mode : hearing_aid_channel_modes_) {
913 PcmConfiguration pcm_config{
914 .sampleRateHz = sample_rate,
915 .bitsPerSample = bits_per_sample,
916 .channelMode = channel_mode,
917 };
918 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
919 DataMQDesc mq_desc;
920 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -0800921 audio_port_, AudioConfiguration(pcm_config), latency_modes,
922 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -0800923 DataMQ data_mq(mq_desc);
924
925 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
926 if (is_codec_config_valid) {
927 EXPECT_TRUE(data_mq.isValid());
928 }
929 EXPECT_TRUE(audio_provider_->endSession().isOk());
930 }
931 }
932 }
933}
934
935/**
936 * openProvider LE_AUDIO_SOFTWARE_ENCODING_DATAPATH
937 */
938class BluetoothAudioProviderLeAudioOutputSoftwareAidl
939 : public BluetoothAudioProviderFactoryAidl {
940 public:
941 virtual void SetUp() override {
942 BluetoothAudioProviderFactoryAidl::SetUp();
943 GetProviderCapabilitiesHelper(
944 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
945 OpenProviderHelper(SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
946 ASSERT_NE(audio_provider_, nullptr);
947 }
948
949 virtual void TearDown() override {
950 audio_port_ = nullptr;
951 audio_provider_ = nullptr;
952 BluetoothAudioProviderFactoryAidl::TearDown();
953 }
954
955 static constexpr int32_t le_audio_output_sample_rates_[] = {
956 0, 8000, 16000, 24000, 32000, 44100, 48000,
957 };
958 static constexpr int8_t le_audio_output_bits_per_samples_[] = {0, 16, 24};
959 static constexpr ChannelMode le_audio_output_channel_modes_[] = {
960 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
961 static constexpr int32_t le_audio_output_data_interval_us_[] = {
962 0 /* Invalid */, 10000 /* Valid 10ms */};
963};
964
965/**
966 * Test whether each provider of type
967 * SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH can be started and
968 * stopped
969 */
970TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl,
971 OpenLeAudioOutputSoftwareProvider) {}
972
973/**
974 * Test whether each provider of type
975 * SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH can be started and
976 * stopped with different PCM config
977 */
978TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl,
979 StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
980 for (auto sample_rate : le_audio_output_sample_rates_) {
981 for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
982 for (auto channel_mode : le_audio_output_channel_modes_) {
983 for (auto data_interval_us : le_audio_output_data_interval_us_) {
984 PcmConfiguration pcm_config{
985 .sampleRateHz = sample_rate,
986 .bitsPerSample = bits_per_sample,
987 .channelMode = channel_mode,
988 .dataIntervalUs = data_interval_us,
989 };
990 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
991 DataMQDesc mq_desc;
992 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -0800993 audio_port_, AudioConfiguration(pcm_config), latency_modes,
994 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -0800995 DataMQ data_mq(mq_desc);
996
997 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
998 if (is_codec_config_valid) {
999 EXPECT_TRUE(data_mq.isValid());
1000 }
1001 EXPECT_TRUE(audio_provider_->endSession().isOk());
1002 }
1003 }
1004 }
1005 }
1006}
1007
1008/**
1009 * openProvider LE_AUDIO_SOFTWARE_DECODED_DATAPATH
1010 */
1011class BluetoothAudioProviderLeAudioInputSoftwareAidl
1012 : public BluetoothAudioProviderFactoryAidl {
1013 public:
1014 virtual void SetUp() override {
1015 BluetoothAudioProviderFactoryAidl::SetUp();
1016 GetProviderCapabilitiesHelper(
1017 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH);
1018 OpenProviderHelper(SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH);
1019 ASSERT_NE(audio_provider_, nullptr);
1020 }
1021
1022 virtual void TearDown() override {
1023 audio_port_ = nullptr;
1024 audio_provider_ = nullptr;
1025 BluetoothAudioProviderFactoryAidl::TearDown();
1026 }
1027
1028 static constexpr int32_t le_audio_input_sample_rates_[] = {
1029 0, 8000, 16000, 24000, 32000, 44100, 48000};
1030 static constexpr int8_t le_audio_input_bits_per_samples_[] = {0, 16, 24};
1031 static constexpr ChannelMode le_audio_input_channel_modes_[] = {
1032 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
1033 static constexpr int32_t le_audio_input_data_interval_us_[] = {
1034 0 /* Invalid */, 10000 /* Valid 10ms */};
1035};
1036
1037/**
1038 * Test whether each provider of type
1039 * SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH can be started and
1040 * stopped
1041 */
1042TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl,
1043 OpenLeAudioInputSoftwareProvider) {}
1044
1045/**
1046 * Test whether each provider of type
1047 * SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH can be started and
1048 * stopped with different PCM config
1049 */
1050TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl,
1051 StartAndEndLeAudioInputSessionWithPossiblePcmConfig) {
1052 for (auto sample_rate : le_audio_input_sample_rates_) {
1053 for (auto bits_per_sample : le_audio_input_bits_per_samples_) {
1054 for (auto channel_mode : le_audio_input_channel_modes_) {
1055 for (auto data_interval_us : le_audio_input_data_interval_us_) {
1056 PcmConfiguration pcm_config{
1057 .sampleRateHz = sample_rate,
1058 .bitsPerSample = bits_per_sample,
1059 .channelMode = channel_mode,
1060 .dataIntervalUs = data_interval_us,
1061 };
1062 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
1063 DataMQDesc mq_desc;
1064 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001065 audio_port_, AudioConfiguration(pcm_config), latency_modes,
1066 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001067 DataMQ data_mq(mq_desc);
1068
1069 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
1070 if (is_codec_config_valid) {
1071 EXPECT_TRUE(data_mq.isValid());
1072 }
1073 EXPECT_TRUE(audio_provider_->endSession().isOk());
1074 }
1075 }
1076 }
1077 }
1078}
1079
1080/**
1081 * openProvider LE_AUDIO_HARDWARE_OFFLOAD_DECODED_DATAPATH
1082 */
1083class BluetoothAudioProviderLeAudioOutputHardwareAidl
1084 : public BluetoothAudioProviderFactoryAidl {
1085 public:
1086 virtual void SetUp() override {
1087 BluetoothAudioProviderFactoryAidl::SetUp();
1088 GetProviderCapabilitiesHelper(
1089 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
1090 OpenProviderHelper(
1091 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
1092 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
1093 audio_provider_ != nullptr);
1094 }
1095
1096 virtual void TearDown() override {
1097 audio_port_ = nullptr;
1098 audio_provider_ = nullptr;
1099 BluetoothAudioProviderFactoryAidl::TearDown();
1100 }
1101
1102 bool IsOffloadOutputSupported() {
1103 for (auto& capability : temp_provider_capabilities_) {
1104 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
1105 continue;
1106 }
1107 auto& le_audio_capability =
1108 capability.get<AudioCapabilities::leAudioCapabilities>();
1109 if (le_audio_capability.unicastEncodeCapability.codecType !=
1110 CodecType::UNKNOWN)
1111 return true;
1112 }
1113 return false;
1114 }
1115
1116 std::vector<Lc3Configuration> GetUnicastLc3SupportedList(bool decoding,
1117 bool supported) {
1118 std::vector<Lc3Configuration> le_audio_codec_configs;
1119 if (!supported) {
1120 Lc3Configuration lc3_config{.samplingFrequencyHz = 0, .pcmBitDepth = 0};
1121 le_audio_codec_configs.push_back(lc3_config);
1122 return le_audio_codec_configs;
1123 }
1124
1125 // There might be more than one LeAudioCodecCapabilitiesSetting
1126 std::vector<Lc3Capabilities> lc3_capabilities;
1127 for (auto& capability : temp_provider_capabilities_) {
1128 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
1129 continue;
1130 }
1131 auto& le_audio_capability =
1132 capability.get<AudioCapabilities::leAudioCapabilities>();
1133 auto& unicast_capability =
1134 decoding ? le_audio_capability.unicastDecodeCapability
1135 : le_audio_capability.unicastEncodeCapability;
1136 if (unicast_capability.codecType != CodecType::LC3) {
1137 continue;
1138 }
1139 auto& lc3_capability = unicast_capability.leAudioCodecCapabilities.get<
1140 UnicastCapability::LeAudioCodecCapabilities::lc3Capabilities>();
1141 lc3_capabilities.push_back(lc3_capability);
1142 }
1143
1144 // Combine those parameters into one list of LeAudioCodecConfiguration
1145 // This seems horrible, but usually each Lc3Capability only contains a
1146 // single Lc3Configuration, which means every array has a length of 1.
1147 for (auto& lc3_capability : lc3_capabilities) {
1148 for (int32_t samplingFrequencyHz : lc3_capability.samplingFrequencyHz) {
1149 for (int32_t frameDurationUs : lc3_capability.frameDurationUs) {
1150 for (int32_t octetsPerFrame : lc3_capability.octetsPerFrame) {
1151 Lc3Configuration lc3_config = {
1152 .samplingFrequencyHz = samplingFrequencyHz,
1153 .frameDurationUs = frameDurationUs,
1154 .octetsPerFrame = octetsPerFrame,
1155 };
1156 le_audio_codec_configs.push_back(lc3_config);
1157 }
1158 }
1159 }
1160 }
1161
1162 return le_audio_codec_configs;
1163 }
1164
1165 LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
1166};
1167
1168/**
1169 * Test whether each provider of type
1170 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
1171 * stopped
1172 */
1173TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
1174 OpenLeAudioOutputHardwareProvider) {}
1175
1176/**
1177 * Test whether each provider of type
1178 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
1179 * stopped with Unicast hardware encoding config
1180 */
1181TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
1182 StartAndEndLeAudioOutputSessionWithPossibleUnicastConfig) {
1183 if (!IsOffloadOutputSupported()) {
1184 return;
1185 }
1186
1187 auto lc3_codec_configs =
1188 GetUnicastLc3SupportedList(false /* decoding */, true /* supported */);
1189 LeAudioConfiguration le_audio_config = {
1190 .codecType = CodecType::LC3,
1191 .peerDelayUs = 0,
1192 };
1193
1194 for (auto& lc3_config : lc3_codec_configs) {
1195 le_audio_config.leAudioCodecConfig
1196 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
1197 DataMQDesc mq_desc;
1198 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001199 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
1200 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001201
1202 ASSERT_TRUE(aidl_retval.isOk());
1203 EXPECT_TRUE(audio_provider_->endSession().isOk());
1204 }
1205}
1206
1207/**
1208 * Test whether each provider of type
1209 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
1210 * stopped with Unicast hardware encoding config
1211 *
1212 * Disabled since offload codec checking is not ready
1213 */
1214TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
1215 DISABLED_StartAndEndLeAudioOutputSessionWithInvalidAudioConfiguration) {
1216 if (!IsOffloadOutputSupported()) {
1217 return;
1218 }
1219
1220 auto lc3_codec_configs =
1221 GetUnicastLc3SupportedList(false /* decoding */, false /* supported */);
1222 LeAudioConfiguration le_audio_config = {
1223 .codecType = CodecType::LC3,
1224 .peerDelayUs = 0,
1225 };
1226
1227 for (auto& lc3_config : lc3_codec_configs) {
1228 le_audio_config.leAudioCodecConfig
1229 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
1230 DataMQDesc mq_desc;
1231 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001232 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
1233 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001234
1235 // AIDL call should fail on invalid codec
1236 ASSERT_FALSE(aidl_retval.isOk());
1237 EXPECT_TRUE(audio_provider_->endSession().isOk());
1238 }
1239}
1240
1241/**
1242 * openProvider LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH
1243 */
1244class BluetoothAudioProviderLeAudioInputHardwareAidl
1245 : public BluetoothAudioProviderLeAudioOutputHardwareAidl {
1246 public:
1247 virtual void SetUp() override {
1248 BluetoothAudioProviderFactoryAidl::SetUp();
1249 GetProviderCapabilitiesHelper(
1250 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
1251 OpenProviderHelper(
1252 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
1253 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
1254 audio_provider_ != nullptr);
1255 }
1256
1257 bool IsOffloadInputSupported() {
1258 for (auto& capability : temp_provider_capabilities_) {
1259 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
1260 continue;
1261 }
1262 auto& le_audio_capability =
1263 capability.get<AudioCapabilities::leAudioCapabilities>();
1264 if (le_audio_capability.unicastDecodeCapability.codecType !=
1265 CodecType::UNKNOWN)
1266 return true;
1267 }
1268 return false;
1269 }
1270
1271 virtual void TearDown() override {
1272 audio_port_ = nullptr;
1273 audio_provider_ = nullptr;
1274 BluetoothAudioProviderFactoryAidl::TearDown();
1275 }
1276};
1277
1278/**
1279 * Test whether each provider of type
1280 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
1281 * stopped
1282 */
1283TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
1284 OpenLeAudioInputHardwareProvider) {}
1285
1286/**
1287 * Test whether each provider of type
1288 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
1289 * stopped with Unicast hardware encoding config
1290 */
1291TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
1292 StartAndEndLeAudioInputSessionWithPossibleUnicastConfig) {
1293 if (!IsOffloadInputSupported()) {
1294 return;
1295 }
1296
1297 auto lc3_codec_configs =
1298 GetUnicastLc3SupportedList(true /* decoding */, true /* supported */);
1299 LeAudioConfiguration le_audio_config = {
1300 .codecType = CodecType::LC3,
1301 .peerDelayUs = 0,
1302 };
1303
1304 for (auto& lc3_config : lc3_codec_configs) {
1305 le_audio_config.leAudioCodecConfig
1306 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
1307 DataMQDesc mq_desc;
1308 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001309 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
1310 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001311
1312 ASSERT_TRUE(aidl_retval.isOk());
1313 EXPECT_TRUE(audio_provider_->endSession().isOk());
1314 }
1315}
1316
1317/**
1318 * Test whether each provider of type
1319 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
1320 * stopped with Unicast hardware encoding config
1321 *
1322 * Disabled since offload codec checking is not ready
1323 */
1324TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
1325 DISABLED_StartAndEndLeAudioInputSessionWithInvalidAudioConfiguration) {
1326 if (!IsOffloadInputSupported()) {
1327 return;
1328 }
1329
1330 auto lc3_codec_configs =
1331 GetUnicastLc3SupportedList(true /* decoding */, false /* supported */);
1332 LeAudioConfiguration le_audio_config = {
1333 .codecType = CodecType::LC3,
1334 .peerDelayUs = 0,
1335 };
1336
1337 for (auto& lc3_config : lc3_codec_configs) {
1338 le_audio_config.leAudioCodecConfig
1339 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
1340
1341 DataMQDesc mq_desc;
1342 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001343 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
1344 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001345
1346 // AIDL call should fail on invalid codec
1347 ASSERT_FALSE(aidl_retval.isOk());
1348 EXPECT_TRUE(audio_provider_->endSession().isOk());
1349 }
1350}
1351
1352/**
1353 * openProvider LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH
1354 */
1355class BluetoothAudioProviderLeAudioBroadcastSoftwareAidl
1356 : public BluetoothAudioProviderFactoryAidl {
1357 public:
1358 virtual void SetUp() override {
1359 BluetoothAudioProviderFactoryAidl::SetUp();
1360 GetProviderCapabilitiesHelper(
1361 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
1362 OpenProviderHelper(
1363 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
1364 ASSERT_NE(audio_provider_, nullptr);
1365 }
1366
1367 virtual void TearDown() override {
1368 audio_port_ = nullptr;
1369 audio_provider_ = nullptr;
1370 BluetoothAudioProviderFactoryAidl::TearDown();
1371 }
1372
1373 static constexpr int32_t le_audio_output_sample_rates_[] = {
1374 0, 8000, 16000, 24000, 32000, 44100, 48000,
1375 };
1376 static constexpr int8_t le_audio_output_bits_per_samples_[] = {0, 16, 24};
1377 static constexpr ChannelMode le_audio_output_channel_modes_[] = {
1378 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
1379 static constexpr int32_t le_audio_output_data_interval_us_[] = {
1380 0 /* Invalid */, 10000 /* Valid 10ms */};
1381};
1382
1383/**
1384 * Test whether each provider of type
1385 * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started and
1386 * stopped
1387 */
1388TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
1389 DISABLED_OpenLeAudioOutputSoftwareProvider) {}
1390
1391/**
1392 * Test whether each provider of type
1393 * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started and
1394 * stopped with different PCM config
1395 */
1396TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
1397 DISABLED_StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
1398 for (auto sample_rate : le_audio_output_sample_rates_) {
1399 for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
1400 for (auto channel_mode : le_audio_output_channel_modes_) {
1401 for (auto data_interval_us : le_audio_output_data_interval_us_) {
1402 PcmConfiguration pcm_config{
1403 .sampleRateHz = sample_rate,
1404 .bitsPerSample = bits_per_sample,
1405 .channelMode = channel_mode,
1406 .dataIntervalUs = data_interval_us,
1407 };
1408 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
1409 DataMQDesc mq_desc;
1410 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001411 audio_port_, AudioConfiguration(pcm_config), latency_modes,
1412 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001413 DataMQ data_mq(mq_desc);
1414
1415 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
1416 if (is_codec_config_valid) {
1417 EXPECT_TRUE(data_mq.isValid());
1418 }
1419 EXPECT_TRUE(audio_provider_->endSession().isOk());
1420 }
1421 }
1422 }
1423 }
1424}
1425
1426GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
1427 BluetoothAudioProviderFactoryAidl);
1428INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderFactoryAidl,
1429 testing::ValuesIn(android::getAidlHalInstanceNames(
1430 IBluetoothAudioProviderFactory::descriptor)),
1431 android::PrintInstanceNameToString);
1432
1433GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
1434 BluetoothAudioProviderA2dpSoftwareAidl);
1435INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderA2dpSoftwareAidl,
1436 testing::ValuesIn(android::getAidlHalInstanceNames(
1437 IBluetoothAudioProviderFactory::descriptor)),
1438 android::PrintInstanceNameToString);
1439
1440GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
1441 BluetoothAudioProviderA2dpHardwareAidl);
1442INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderA2dpHardwareAidl,
1443 testing::ValuesIn(android::getAidlHalInstanceNames(
1444 IBluetoothAudioProviderFactory::descriptor)),
1445 android::PrintInstanceNameToString);
1446
1447GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
1448 BluetoothAudioProviderHearingAidSoftwareAidl);
1449INSTANTIATE_TEST_SUITE_P(PerInstance,
1450 BluetoothAudioProviderHearingAidSoftwareAidl,
1451 testing::ValuesIn(android::getAidlHalInstanceNames(
1452 IBluetoothAudioProviderFactory::descriptor)),
1453 android::PrintInstanceNameToString);
1454
1455GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
1456 BluetoothAudioProviderLeAudioOutputSoftwareAidl);
1457INSTANTIATE_TEST_SUITE_P(PerInstance,
1458 BluetoothAudioProviderLeAudioOutputSoftwareAidl,
1459 testing::ValuesIn(android::getAidlHalInstanceNames(
1460 IBluetoothAudioProviderFactory::descriptor)),
1461 android::PrintInstanceNameToString);
1462
1463GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
1464 BluetoothAudioProviderLeAudioInputSoftwareAidl);
1465INSTANTIATE_TEST_SUITE_P(PerInstance,
1466 BluetoothAudioProviderLeAudioInputSoftwareAidl,
1467 testing::ValuesIn(android::getAidlHalInstanceNames(
1468 IBluetoothAudioProviderFactory::descriptor)),
1469 android::PrintInstanceNameToString);
1470
1471GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
1472 BluetoothAudioProviderLeAudioOutputHardwareAidl);
1473INSTANTIATE_TEST_SUITE_P(PerInstance,
1474 BluetoothAudioProviderLeAudioOutputHardwareAidl,
1475 testing::ValuesIn(android::getAidlHalInstanceNames(
1476 IBluetoothAudioProviderFactory::descriptor)),
1477 android::PrintInstanceNameToString);
1478
1479GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
1480 BluetoothAudioProviderLeAudioInputHardwareAidl);
1481INSTANTIATE_TEST_SUITE_P(PerInstance,
1482 BluetoothAudioProviderLeAudioInputHardwareAidl,
1483 testing::ValuesIn(android::getAidlHalInstanceNames(
1484 IBluetoothAudioProviderFactory::descriptor)),
1485 android::PrintInstanceNameToString);
1486
1487GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
1488 BluetoothAudioProviderLeAudioBroadcastSoftwareAidl);
1489INSTANTIATE_TEST_SUITE_P(PerInstance,
1490 BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
1491 testing::ValuesIn(android::getAidlHalInstanceNames(
1492 IBluetoothAudioProviderFactory::descriptor)),
1493 android::PrintInstanceNameToString);
1494
1495// TODO(219668925): Add LE Audio Broadcast VTS
1496// GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
1497// BluetoothAudioProviderLeAudioBroadcastHardwareAidl);
1498// INSTANTIATE_TEST_SUITE_P(PerInstance,
1499// BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
1500// testing::ValuesIn(android::getAidlHalInstanceNames(
1501// IBluetoothAudioProviderFactory::descriptor)),
1502// android::PrintInstanceNameToString);
1503
1504int main(int argc, char** argv) {
1505 ::testing::InitGoogleTest(&argc, argv);
1506 ABinderProcess_setThreadPoolMaxThreadCount(1);
1507 ABinderProcess_startThreadPool();
1508 return RUN_ALL_TESTS();
1509}