blob: 858fa38825e4dbe58a963ba8a81f045b6b9c9ad5 [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>
shihchienc3ab9f5e2022-09-23 08:18:05 +000026#include <cutils/properties.h>
Josh Wu049e2cd2022-01-12 05:42:58 -080027#include <fmq/AidlMessageQueue.h>
28
29#include <cstdint>
30#include <future>
31#include <unordered_set>
32#include <vector>
33
34using aidl::android::hardware::audio::common::SinkMetadata;
35using aidl::android::hardware::audio::common::SourceMetadata;
36using aidl::android::hardware::bluetooth::audio::AacCapabilities;
37using aidl::android::hardware::bluetooth::audio::AacConfiguration;
Sagar Verma62df9102022-12-07 17:56:04 +053038using aidl::android::hardware::bluetooth::audio::AptxAdaptiveLeCapabilities;
39using aidl::android::hardware::bluetooth::audio::AptxAdaptiveLeConfiguration;
Josh Wu049e2cd2022-01-12 05:42:58 -080040using aidl::android::hardware::bluetooth::audio::AptxCapabilities;
41using aidl::android::hardware::bluetooth::audio::AptxConfiguration;
42using aidl::android::hardware::bluetooth::audio::AudioCapabilities;
43using aidl::android::hardware::bluetooth::audio::AudioConfiguration;
44using aidl::android::hardware::bluetooth::audio::BnBluetoothAudioPort;
Alice Kuo336d90c2022-02-16 09:09:59 +080045using aidl::android::hardware::bluetooth::audio::BroadcastCapability;
Josh Wu049e2cd2022-01-12 05:42:58 -080046using aidl::android::hardware::bluetooth::audio::ChannelMode;
47using aidl::android::hardware::bluetooth::audio::CodecCapabilities;
48using aidl::android::hardware::bluetooth::audio::CodecConfiguration;
49using aidl::android::hardware::bluetooth::audio::CodecType;
50using aidl::android::hardware::bluetooth::audio::IBluetoothAudioPort;
51using aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider;
52using aidl::android::hardware::bluetooth::audio::IBluetoothAudioProviderFactory;
53using aidl::android::hardware::bluetooth::audio::LatencyMode;
54using aidl::android::hardware::bluetooth::audio::Lc3Capabilities;
55using aidl::android::hardware::bluetooth::audio::Lc3Configuration;
56using aidl::android::hardware::bluetooth::audio::LdacCapabilities;
57using aidl::android::hardware::bluetooth::audio::LdacConfiguration;
Alice Kuo336d90c2022-02-16 09:09:59 +080058using aidl::android::hardware::bluetooth::audio::LeAudioBroadcastConfiguration;
Josh Wu049e2cd2022-01-12 05:42:58 -080059using aidl::android::hardware::bluetooth::audio::
60 LeAudioCodecCapabilitiesSetting;
61using aidl::android::hardware::bluetooth::audio::LeAudioCodecConfiguration;
62using aidl::android::hardware::bluetooth::audio::LeAudioConfiguration;
Omer Osmana2587da2022-05-01 03:54:11 +000063using aidl::android::hardware::bluetooth::audio::OpusCapabilities;
64using aidl::android::hardware::bluetooth::audio::OpusConfiguration;
Josh Wu049e2cd2022-01-12 05:42:58 -080065using aidl::android::hardware::bluetooth::audio::PcmConfiguration;
66using aidl::android::hardware::bluetooth::audio::PresentationPosition;
67using aidl::android::hardware::bluetooth::audio::SbcAllocMethod;
68using aidl::android::hardware::bluetooth::audio::SbcCapabilities;
69using aidl::android::hardware::bluetooth::audio::SbcChannelMode;
70using aidl::android::hardware::bluetooth::audio::SbcConfiguration;
71using aidl::android::hardware::bluetooth::audio::SessionType;
72using aidl::android::hardware::bluetooth::audio::UnicastCapability;
73using aidl::android::hardware::common::fmq::MQDescriptor;
74using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
75using android::AidlMessageQueue;
76using android::ProcessState;
77using android::String16;
78using ndk::ScopedAStatus;
79using ndk::SpAIBinder;
80
81using MqDataType = int8_t;
82using MqDataMode = SynchronizedReadWrite;
83using DataMQ = AidlMessageQueue<MqDataType, MqDataMode>;
84using DataMQDesc = MQDescriptor<MqDataType, MqDataMode>;
85
86// Constants
87
88static constexpr int32_t a2dp_sample_rates[] = {0, 44100, 48000, 88200, 96000};
89static constexpr int8_t a2dp_bits_per_samples[] = {0, 16, 24, 32};
90static constexpr ChannelMode a2dp_channel_modes[] = {
91 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
Chen Chenc92270e2022-02-14 18:29:52 -080092static std::vector<LatencyMode> latency_modes = {LatencyMode::FREE};
Josh Wu049e2cd2022-01-12 05:42:58 -080093// Helpers
94
95template <typename T>
96struct identity {
97 typedef T type;
98};
99
100template <class T>
101bool contained_in_vector(const std::vector<T>& vector,
102 const typename identity<T>::type& target) {
103 return std::find(vector.begin(), vector.end(), target) != vector.end();
104}
105
106void copy_codec_specific(CodecConfiguration::CodecSpecific& dst,
107 const CodecConfiguration::CodecSpecific& src) {
108 switch (src.getTag()) {
109 case CodecConfiguration::CodecSpecific::sbcConfig:
110 dst.set<CodecConfiguration::CodecSpecific::sbcConfig>(
111 src.get<CodecConfiguration::CodecSpecific::sbcConfig>());
112 break;
113 case CodecConfiguration::CodecSpecific::aacConfig:
114 dst.set<CodecConfiguration::CodecSpecific::aacConfig>(
115 src.get<CodecConfiguration::CodecSpecific::aacConfig>());
116 break;
117 case CodecConfiguration::CodecSpecific::ldacConfig:
118 dst.set<CodecConfiguration::CodecSpecific::ldacConfig>(
119 src.get<CodecConfiguration::CodecSpecific::ldacConfig>());
120 break;
121 case CodecConfiguration::CodecSpecific::aptxConfig:
122 dst.set<CodecConfiguration::CodecSpecific::aptxConfig>(
123 src.get<CodecConfiguration::CodecSpecific::aptxConfig>());
124 break;
Omer Osmana2587da2022-05-01 03:54:11 +0000125 case CodecConfiguration::CodecSpecific::opusConfig:
126 dst.set<CodecConfiguration::CodecSpecific::opusConfig>(
127 src.get<CodecConfiguration::CodecSpecific::opusConfig>());
Josh Wu049e2cd2022-01-12 05:42:58 -0800128 break;
129 case CodecConfiguration::CodecSpecific::aptxAdaptiveConfig:
130 dst.set<CodecConfiguration::CodecSpecific::aptxAdaptiveConfig>(
131 src.get<CodecConfiguration::CodecSpecific::aptxAdaptiveConfig>());
132 break;
133 default:
134 break;
135 }
136}
137
138class BluetoothAudioPort : public BnBluetoothAudioPort {
139 public:
140 BluetoothAudioPort() {}
141
Chen Chen0a68a922022-02-15 18:43:26 -0800142 ndk::ScopedAStatus startStream(bool) { return ScopedAStatus::ok(); }
Josh Wu049e2cd2022-01-12 05:42:58 -0800143
144 ndk::ScopedAStatus suspendStream() { return ScopedAStatus::ok(); }
145
146 ndk::ScopedAStatus stopStream() { return ScopedAStatus::ok(); }
147
148 ndk::ScopedAStatus getPresentationPosition(PresentationPosition*) {
149 return ScopedAStatus::ok();
150 }
151
152 ndk::ScopedAStatus updateSourceMetadata(const SourceMetadata&) {
153 return ScopedAStatus::ok();
154 }
155
156 ndk::ScopedAStatus updateSinkMetadata(const SinkMetadata&) {
157 return ScopedAStatus::ok();
158 }
159
160 ndk::ScopedAStatus setLatencyMode(const LatencyMode) {
161 return ScopedAStatus::ok();
162 }
163
164 ndk::ScopedAStatus setCodecType(const CodecType) {
165 return ScopedAStatus::ok();
166 }
167
168 protected:
169 virtual ~BluetoothAudioPort() = default;
170};
171
172class BluetoothAudioProviderFactoryAidl
173 : public testing::TestWithParam<std::string> {
174 public:
175 virtual void SetUp() override {
176 provider_factory_ = IBluetoothAudioProviderFactory::fromBinder(
177 SpAIBinder(AServiceManager_getService(GetParam().c_str())));
178 audio_provider_ = nullptr;
179 ASSERT_NE(provider_factory_, nullptr);
180 }
181
182 virtual void TearDown() override { provider_factory_ = nullptr; }
183
184 void GetProviderCapabilitiesHelper(const SessionType& session_type) {
185 temp_provider_capabilities_.clear();
186 auto aidl_retval = provider_factory_->getProviderCapabilities(
187 session_type, &temp_provider_capabilities_);
188 // AIDL calls should not be failed and callback has to be executed
189 ASSERT_TRUE(aidl_retval.isOk());
190 switch (session_type) {
191 case SessionType::UNKNOWN: {
192 ASSERT_TRUE(temp_provider_capabilities_.empty());
193 } break;
194 case SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH:
195 case SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH:
196 case SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH:
197 case SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH:
198 case SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH: {
199 // All software paths are mandatory and must have exact 1
200 // "PcmParameters"
201 ASSERT_EQ(temp_provider_capabilities_.size(), 1);
202 ASSERT_EQ(temp_provider_capabilities_[0].getTag(),
203 AudioCapabilities::pcmCapabilities);
204 } break;
Alice Kuoadcceec2022-03-28 13:28:43 +0800205 case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
206 case SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH: {
Josh Wu049e2cd2022-01-12 05:42:58 -0800207 std::unordered_set<CodecType> codec_types;
208 // empty capability means offload is unsupported
209 for (auto& audio_capability : temp_provider_capabilities_) {
210 ASSERT_EQ(audio_capability.getTag(),
211 AudioCapabilities::a2dpCapabilities);
212 const auto& codec_capabilities =
213 audio_capability.get<AudioCapabilities::a2dpCapabilities>();
214 // Every codec can present once at most
215 ASSERT_EQ(codec_types.count(codec_capabilities.codecType), 0);
216 switch (codec_capabilities.codecType) {
217 case CodecType::SBC:
218 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
219 CodecCapabilities::Capabilities::sbcCapabilities);
220 break;
221 case CodecType::AAC:
222 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
223 CodecCapabilities::Capabilities::aacCapabilities);
224 break;
225 case CodecType::APTX:
226 case CodecType::APTX_HD:
227 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
228 CodecCapabilities::Capabilities::aptxCapabilities);
229 break;
230 case CodecType::LDAC:
231 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
232 CodecCapabilities::Capabilities::ldacCapabilities);
233 break;
Omer Osmana2587da2022-05-01 03:54:11 +0000234 case CodecType::OPUS:
Josh Wu049e2cd2022-01-12 05:42:58 -0800235 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
Omer Osmana2587da2022-05-01 03:54:11 +0000236 CodecCapabilities::Capabilities::opusCapabilities);
Josh Wu049e2cd2022-01-12 05:42:58 -0800237 break;
238 case CodecType::APTX_ADAPTIVE:
Sagar Verma62df9102022-12-07 17:56:04 +0530239 case CodecType::APTX_ADAPTIVE_LE:
240 case CodecType::APTX_ADAPTIVE_LEX:
Omer Osmana2587da2022-05-01 03:54:11 +0000241 case CodecType::LC3:
Josh Wu049e2cd2022-01-12 05:42:58 -0800242 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: {
shihchienc3ab9f5e2022-09-23 08:18:05 +0000252 // empty capability means offload is unsupported since capabilities are
253 // not hardcoded
Josh Wu049e2cd2022-01-12 05:42:58 -0800254 for (auto audio_capability : temp_provider_capabilities_) {
255 ASSERT_EQ(audio_capability.getTag(),
256 AudioCapabilities::leAudioCapabilities);
257 }
258 } break;
Alice Kuoadcceec2022-03-28 13:28:43 +0800259 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 }
Josh Wu049e2cd2022-01-12 05:42:58 -0800269 }
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 ***/
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 {
Alice Kuoadcceec2022-03-28 13:28:43 +0800285 // optional session type
Josh Wu049e2cd2022-01-12 05:42:58 -0800286 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::
Alice Kuoadcceec2022-03-28 13:28:43 +0800296 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);
Josh Wu049e2cd2022-01-12 05:42:58 -0800300 ASSERT_EQ(audio_provider_, nullptr);
301 }
302 }
303
Josh Wu049e2cd2022-01-12 05:42:58 -0800304 void GetA2dpOffloadCapabilityHelper(const CodecType& codec_type) {
305 temp_codec_capabilities_ = nullptr;
Josh Wu4d2938f2022-02-15 09:21:10 -0800306 for (auto& codec_capability : temp_provider_capabilities_) {
Josh Wu049e2cd2022-01-12 05:42:58 -0800307 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>
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>
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
Sagar Verma62df9102022-12-07 17:56:04 +0530390 std::vector<bool> adaptive_bit_rate_supporteds = {false};
391 if (aac_capability.adaptiveBitRateSupported) {
392 adaptive_bit_rate_supporteds.push_back(true);
393 }
394
Josh Wu049e2cd2022-01-12 05:42:58 -0800395 // combine those parameters into one list of
396 // CodecConfiguration::CodecSpecific
397 for (auto object_type : aac_capability.objectType) {
398 for (int32_t sample_rate : aac_capability.sampleRateHz) {
399 for (auto channel_mode : aac_capability.channelMode) {
400 for (int8_t bits_per_sample : aac_capability.bitsPerSample) {
401 for (auto variable_bit_rate_enabled : variable_bit_rate_enableds) {
Sagar Verma62df9102022-12-07 17:56:04 +0530402 for (auto adaptive_bit_rate_supported :
403 adaptive_bit_rate_supporteds) {
404 AacConfiguration aac_data{
405 .objectType = object_type,
406 .sampleRateHz = sample_rate,
407 .channelMode = channel_mode,
408 .variableBitRateEnabled = variable_bit_rate_enabled,
409 .bitsPerSample = bits_per_sample,
410 .adaptiveBitRateSupported = adaptive_bit_rate_supported};
411 aac_codec_specifics.push_back(
412 CodecConfiguration::CodecSpecific(aac_data));
413 }
Josh Wu049e2cd2022-01-12 05:42:58 -0800414 }
415 }
416 }
417 }
418 }
419 return aac_codec_specifics;
420 }
421
422 std::vector<CodecConfiguration::CodecSpecific>
423 GetLdacCodecSpecificSupportedList(bool supported) {
424 std::vector<CodecConfiguration::CodecSpecific> ldac_codec_specifics;
425 if (!supported) {
426 LdacConfiguration ldac_config{.sampleRateHz = 0, .bitsPerSample = 0};
427 ldac_codec_specifics.push_back(
428 CodecConfiguration::CodecSpecific(ldac_config));
429 return ldac_codec_specifics;
430 }
431 GetA2dpOffloadCapabilityHelper(CodecType::LDAC);
432 if (temp_codec_capabilities_ == nullptr ||
433 temp_codec_capabilities_->codecType != CodecType::LDAC) {
434 return ldac_codec_specifics;
435 }
436 // parse the capability
437 auto& ldac_capability =
438 temp_codec_capabilities_->capabilities
439 .get<CodecCapabilities::Capabilities::ldacCapabilities>();
440
441 // combine those parameters into one list of
442 // CodecConfiguration::CodecSpecific
443 for (int32_t sample_rate : ldac_capability.sampleRateHz) {
444 for (int8_t bits_per_sample : ldac_capability.bitsPerSample) {
445 for (auto channel_mode : ldac_capability.channelMode) {
446 for (auto quality_index : ldac_capability.qualityIndex) {
447 LdacConfiguration ldac_data{.sampleRateHz = sample_rate,
448 .channelMode = channel_mode,
449 .qualityIndex = quality_index,
450 .bitsPerSample = bits_per_sample};
451 ldac_codec_specifics.push_back(
452 CodecConfiguration::CodecSpecific(ldac_data));
453 }
454 }
455 }
456 }
457 return ldac_codec_specifics;
458 }
459
460 std::vector<CodecConfiguration::CodecSpecific>
461 GetAptxCodecSpecificSupportedList(bool is_hd, bool supported) {
462 std::vector<CodecConfiguration::CodecSpecific> aptx_codec_specifics;
463 if (!supported) {
464 AptxConfiguration aptx_config{.sampleRateHz = 0, .bitsPerSample = 0};
465 aptx_codec_specifics.push_back(
466 CodecConfiguration::CodecSpecific(aptx_config));
467 return aptx_codec_specifics;
468 }
469 GetA2dpOffloadCapabilityHelper(
470 (is_hd ? CodecType::APTX_HD : CodecType::APTX));
471 if (temp_codec_capabilities_ == nullptr) {
472 return aptx_codec_specifics;
473 }
474 if ((is_hd && temp_codec_capabilities_->codecType != CodecType::APTX_HD) ||
475 (!is_hd && temp_codec_capabilities_->codecType != CodecType::APTX)) {
476 return aptx_codec_specifics;
477 }
478
479 // parse the capability
480 auto& aptx_capability =
481 temp_codec_capabilities_->capabilities
482 .get<CodecCapabilities::Capabilities::aptxCapabilities>();
483
484 // combine those parameters into one list of
485 // CodecConfiguration::CodecSpecific
486 for (int8_t bits_per_sample : aptx_capability.bitsPerSample) {
487 for (int32_t sample_rate : aptx_capability.sampleRateHz) {
488 for (auto channel_mode : aptx_capability.channelMode) {
489 AptxConfiguration aptx_data{.sampleRateHz = sample_rate,
490 .channelMode = channel_mode,
491 .bitsPerSample = bits_per_sample};
492 aptx_codec_specifics.push_back(
493 CodecConfiguration::CodecSpecific(aptx_data));
494 }
495 }
496 }
497 return aptx_codec_specifics;
498 }
499
500 std::vector<CodecConfiguration::CodecSpecific>
Omer Osmana2587da2022-05-01 03:54:11 +0000501 GetOpusCodecSpecificSupportedList(bool supported) {
502 std::vector<CodecConfiguration::CodecSpecific> opus_codec_specifics;
Josh Wu049e2cd2022-01-12 05:42:58 -0800503 if (!supported) {
Omer Osmana2587da2022-05-01 03:54:11 +0000504 OpusConfiguration opus_config{.samplingFrequencyHz = 0,
505 .frameDurationUs = 0};
506 opus_codec_specifics.push_back(
507 CodecConfiguration::CodecSpecific(opus_config));
508 return opus_codec_specifics;
Josh Wu049e2cd2022-01-12 05:42:58 -0800509 }
Omer Osmana2587da2022-05-01 03:54:11 +0000510 GetA2dpOffloadCapabilityHelper(CodecType::OPUS);
Josh Wu049e2cd2022-01-12 05:42:58 -0800511 if (temp_codec_capabilities_ == nullptr ||
Omer Osmana2587da2022-05-01 03:54:11 +0000512 temp_codec_capabilities_->codecType != CodecType::OPUS) {
513 return opus_codec_specifics;
Josh Wu049e2cd2022-01-12 05:42:58 -0800514 }
515 // parse the capability
Omer Osmana2587da2022-05-01 03:54:11 +0000516 auto& opus_capability =
Josh Wu049e2cd2022-01-12 05:42:58 -0800517 temp_codec_capabilities_->capabilities
Omer Osmana2587da2022-05-01 03:54:11 +0000518 .get<CodecCapabilities::Capabilities::opusCapabilities>();
Josh Wu049e2cd2022-01-12 05:42:58 -0800519
520 // combine those parameters into one list of
521 // CodecConfiguration::CodecSpecific
Omer Osmana2587da2022-05-01 03:54:11 +0000522 for (int32_t samplingFrequencyHz : opus_capability->samplingFrequencyHz) {
523 for (int32_t frameDurationUs : opus_capability->frameDurationUs) {
524 for (auto channel_mode : opus_capability->channelMode) {
525 OpusConfiguration opus_data{
526 .samplingFrequencyHz = samplingFrequencyHz,
shihchienc3ab9f5e2022-09-23 08:18:05 +0000527 .frameDurationUs = frameDurationUs,
Omer Osmana2587da2022-05-01 03:54:11 +0000528 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +0000529 };
Omer Osmana2587da2022-05-01 03:54:11 +0000530 opus_codec_specifics.push_back(
531 CodecConfiguration::CodecSpecific(opus_data));
Josh Wu049e2cd2022-01-12 05:42:58 -0800532 }
533 }
534 }
Omer Osmana2587da2022-05-01 03:54:11 +0000535 return opus_codec_specifics;
Josh Wu049e2cd2022-01-12 05:42:58 -0800536 }
537
Alice Kuoadcceec2022-03-28 13:28:43 +0800538 bool IsPcmConfigSupported(const PcmConfiguration& pcm_config) {
539 if (temp_provider_capabilities_.size() != 1 ||
540 temp_provider_capabilities_[0].getTag() !=
541 AudioCapabilities::pcmCapabilities) {
542 return false;
543 }
544 auto pcm_capability = temp_provider_capabilities_[0]
545 .get<AudioCapabilities::pcmCapabilities>();
546 return (contained_in_vector(pcm_capability.channelMode,
547 pcm_config.channelMode) &&
548 contained_in_vector(pcm_capability.sampleRateHz,
549 pcm_config.sampleRateHz) &&
550 contained_in_vector(pcm_capability.bitsPerSample,
551 pcm_config.bitsPerSample));
552 }
553
554 std::shared_ptr<IBluetoothAudioProviderFactory> provider_factory_;
555 std::shared_ptr<IBluetoothAudioProvider> audio_provider_;
556 std::shared_ptr<IBluetoothAudioPort> audio_port_;
557 std::vector<AudioCapabilities> temp_provider_capabilities_;
558
Josh Wu049e2cd2022-01-12 05:42:58 -0800559 // temp storage saves the specified codec capability by
560 // GetOffloadCodecCapabilityHelper()
561 CodecCapabilities* temp_codec_capabilities_;
Alice Kuoadcceec2022-03-28 13:28:43 +0800562
563 static constexpr SessionType kSessionTypes[] = {
564 SessionType::UNKNOWN,
565 SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
566 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
567 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
568 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
569 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
570 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
571 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
572 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
573 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
574 SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
575 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
576 };
577};
578
579/**
580 * Test whether we can get the FactoryService from HIDL
581 */
582TEST_P(BluetoothAudioProviderFactoryAidl, GetProviderFactoryService) {}
583
584/**
585 * Test whether we can open a provider for each provider returned by
586 * getProviderCapabilities() with non-empty capabalities
587 */
588TEST_P(BluetoothAudioProviderFactoryAidl,
589 OpenProviderAndCheckCapabilitiesBySession) {
590 for (auto session_type : kSessionTypes) {
591 GetProviderCapabilitiesHelper(session_type);
592 OpenProviderHelper(session_type);
593 // We must be able to open a provider if its getProviderCapabilities()
594 // returns non-empty list.
595 EXPECT_TRUE(temp_provider_capabilities_.empty() ||
596 audio_provider_ != nullptr);
597 }
598}
599
600/**
601 * openProvider A2DP_SOFTWARE_ENCODING_DATAPATH
602 */
603class BluetoothAudioProviderA2dpEncodingSoftwareAidl
604 : public BluetoothAudioProviderFactoryAidl {
605 public:
606 virtual void SetUp() override {
607 BluetoothAudioProviderFactoryAidl::SetUp();
608 GetProviderCapabilitiesHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
609 OpenProviderHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
610 ASSERT_NE(audio_provider_, nullptr);
611 }
612
613 virtual void TearDown() override {
614 audio_port_ = nullptr;
615 audio_provider_ = nullptr;
616 BluetoothAudioProviderFactoryAidl::TearDown();
617 }
Josh Wu049e2cd2022-01-12 05:42:58 -0800618};
619
620/**
621 * Test whether we can open a provider of type
622 */
Alice Kuoadcceec2022-03-28 13:28:43 +0800623TEST_P(BluetoothAudioProviderA2dpEncodingSoftwareAidl,
624 OpenA2dpEncodingSoftwareProvider) {}
625
626/**
627 * Test whether each provider of type
628 * SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH can be started and stopped with
629 * different PCM config
630 */
631TEST_P(BluetoothAudioProviderA2dpEncodingSoftwareAidl,
632 StartAndEndA2dpEncodingSoftwareSessionWithPossiblePcmConfig) {
633 for (auto sample_rate : a2dp_sample_rates) {
634 for (auto bits_per_sample : a2dp_bits_per_samples) {
635 for (auto channel_mode : a2dp_channel_modes) {
636 PcmConfiguration pcm_config{
637 .sampleRateHz = sample_rate,
Alice Kuoadcceec2022-03-28 13:28:43 +0800638 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +0000639 .bitsPerSample = bits_per_sample,
Alice Kuoadcceec2022-03-28 13:28:43 +0800640 };
641 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
642 DataMQDesc mq_desc;
643 auto aidl_retval = audio_provider_->startSession(
644 audio_port_, AudioConfiguration(pcm_config), latency_modes,
645 &mq_desc);
646 DataMQ data_mq(mq_desc);
647
648 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
649 if (is_codec_config_valid) {
650 EXPECT_TRUE(data_mq.isValid());
651 }
652 EXPECT_TRUE(audio_provider_->endSession().isOk());
653 }
654 }
655 }
656}
657
658/**
659 * openProvider A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH
660 */
661class BluetoothAudioProviderA2dpEncodingHardwareAidl
662 : public BluetoothAudioProviderFactoryAidl {
663 public:
664 virtual void SetUp() override {
665 BluetoothAudioProviderFactoryAidl::SetUp();
666 GetProviderCapabilitiesHelper(
667 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
668 OpenProviderHelper(SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
669 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
670 audio_provider_ != nullptr);
671 }
672
673 virtual void TearDown() override {
674 audio_port_ = nullptr;
675 audio_provider_ = nullptr;
676 BluetoothAudioProviderFactoryAidl::TearDown();
677 }
678
679 bool IsOffloadSupported() { return (temp_provider_capabilities_.size() > 0); }
680};
681
682/**
683 * Test whether we can open a provider of type
684 */
685TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
686 OpenA2dpEncodingHardwareProvider) {}
Josh Wu049e2cd2022-01-12 05:42:58 -0800687
688/**
689 * Test whether each provider of type
690 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
691 * SBC hardware encoding config
692 */
Alice Kuoadcceec2022-03-28 13:28:43 +0800693TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
694 StartAndEndA2dpSbcEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -0800695 if (!IsOffloadSupported()) {
696 return;
697 }
698
699 CodecConfiguration codec_config = {
700 .codecType = CodecType::SBC,
701 .encodedAudioBitrate = 328000,
702 .peerMtu = 1005,
703 .isScmstEnabled = false,
704 };
705 auto sbc_codec_specifics = GetSbcCodecSpecificSupportedList(true);
706
707 for (auto& codec_specific : sbc_codec_specifics) {
708 copy_codec_specific(codec_config.config, codec_specific);
709 DataMQDesc mq_desc;
710 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -0800711 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -0800712
713 ASSERT_TRUE(aidl_retval.isOk());
714 EXPECT_TRUE(audio_provider_->endSession().isOk());
715 }
716}
717
718/**
719 * Test whether each provider of type
720 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
721 * AAC hardware encoding config
722 */
Alice Kuoadcceec2022-03-28 13:28:43 +0800723TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
724 StartAndEndA2dpAacEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -0800725 if (!IsOffloadSupported()) {
726 return;
727 }
728
729 CodecConfiguration codec_config = {
730 .codecType = CodecType::AAC,
731 .encodedAudioBitrate = 320000,
732 .peerMtu = 1005,
733 .isScmstEnabled = false,
734 };
735 auto aac_codec_specifics = GetAacCodecSpecificSupportedList(true);
736
737 for (auto& codec_specific : aac_codec_specifics) {
738 copy_codec_specific(codec_config.config, codec_specific);
739 DataMQDesc mq_desc;
740 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -0800741 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -0800742
743 ASSERT_TRUE(aidl_retval.isOk());
744 EXPECT_TRUE(audio_provider_->endSession().isOk());
745 }
746}
747
748/**
749 * Test whether each provider of type
750 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
751 * LDAC hardware encoding config
752 */
Alice Kuoadcceec2022-03-28 13:28:43 +0800753TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
754 StartAndEndA2dpLdacEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -0800755 if (!IsOffloadSupported()) {
756 return;
757 }
758
759 CodecConfiguration codec_config = {
760 .codecType = CodecType::LDAC,
761 .encodedAudioBitrate = 990000,
762 .peerMtu = 1005,
763 .isScmstEnabled = false,
764 };
765 auto ldac_codec_specifics = GetLdacCodecSpecificSupportedList(true);
766
767 for (auto& codec_specific : ldac_codec_specifics) {
768 copy_codec_specific(codec_config.config, codec_specific);
769 DataMQDesc mq_desc;
770 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -0800771 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -0800772
773 ASSERT_TRUE(aidl_retval.isOk());
774 EXPECT_TRUE(audio_provider_->endSession().isOk());
775 }
776}
777
778/**
779 * Test whether each provider of type
780 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
Omer Osmana2587da2022-05-01 03:54:11 +0000781 * Opus hardware encoding config
Josh Wu049e2cd2022-01-12 05:42:58 -0800782 */
Alice Kuoadcceec2022-03-28 13:28:43 +0800783TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
Omer Osmana2587da2022-05-01 03:54:11 +0000784 StartAndEndA2dpOpusEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -0800785 if (!IsOffloadSupported()) {
786 return;
787 }
788
789 CodecConfiguration codec_config = {
Omer Osmana2587da2022-05-01 03:54:11 +0000790 .codecType = CodecType::OPUS,
Josh Wu049e2cd2022-01-12 05:42:58 -0800791 .encodedAudioBitrate = 990000,
792 .peerMtu = 1005,
793 .isScmstEnabled = false,
794 };
Omer Osmana2587da2022-05-01 03:54:11 +0000795 auto opus_codec_specifics = GetOpusCodecSpecificSupportedList(true);
Josh Wu049e2cd2022-01-12 05:42:58 -0800796
Omer Osmana2587da2022-05-01 03:54:11 +0000797 for (auto& codec_specific : opus_codec_specifics) {
Josh Wu049e2cd2022-01-12 05:42:58 -0800798 copy_codec_specific(codec_config.config, codec_specific);
799 DataMQDesc mq_desc;
800 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -0800801 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -0800802
803 ASSERT_TRUE(aidl_retval.isOk());
804 EXPECT_TRUE(audio_provider_->endSession().isOk());
805 }
806}
807
808/**
809 * Test whether each provider of type
810 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
811 * AptX hardware encoding config
812 */
Alice Kuoadcceec2022-03-28 13:28:43 +0800813TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
814 StartAndEndA2dpAptxEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -0800815 if (!IsOffloadSupported()) {
816 return;
817 }
818
819 for (auto codec_type : {CodecType::APTX, CodecType::APTX_HD}) {
820 CodecConfiguration codec_config = {
821 .codecType = codec_type,
822 .encodedAudioBitrate =
823 (codec_type == CodecType::APTX ? 352000 : 576000),
824 .peerMtu = 1005,
825 .isScmstEnabled = false,
826 };
827
828 auto aptx_codec_specifics = GetAptxCodecSpecificSupportedList(
829 (codec_type == CodecType::APTX_HD ? true : false), true);
830
831 for (auto& codec_specific : aptx_codec_specifics) {
832 copy_codec_specific(codec_config.config, codec_specific);
833 DataMQDesc mq_desc;
834 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -0800835 audio_port_, AudioConfiguration(codec_config), latency_modes,
836 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -0800837
838 ASSERT_TRUE(aidl_retval.isOk());
839 EXPECT_TRUE(audio_provider_->endSession().isOk());
840 }
841 }
842}
843
844/**
845 * Test whether each provider of type
846 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
847 * an invalid codec config
848 */
Alice Kuoadcceec2022-03-28 13:28:43 +0800849TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
850 StartAndEndA2dpEncodingHardwareSessionInvalidCodecConfig) {
Josh Wu049e2cd2022-01-12 05:42:58 -0800851 if (!IsOffloadSupported()) {
852 return;
853 }
854 ASSERT_NE(audio_provider_, nullptr);
855
856 std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
Sagar Verma62df9102022-12-07 17:56:04 +0530857 for (auto codec_type : ndk::enum_range<CodecType>()) {
Josh Wu049e2cd2022-01-12 05:42:58 -0800858 switch (codec_type) {
859 case CodecType::SBC:
860 codec_specifics = GetSbcCodecSpecificSupportedList(false);
861 break;
862 case CodecType::AAC:
863 codec_specifics = GetAacCodecSpecificSupportedList(false);
864 break;
865 case CodecType::LDAC:
866 codec_specifics = GetLdacCodecSpecificSupportedList(false);
867 break;
868 case CodecType::APTX:
869 codec_specifics = GetAptxCodecSpecificSupportedList(false, false);
870 break;
871 case CodecType::APTX_HD:
872 codec_specifics = GetAptxCodecSpecificSupportedList(true, false);
873 break;
Omer Osmana2587da2022-05-01 03:54:11 +0000874 case CodecType::OPUS:
875 codec_specifics = GetOpusCodecSpecificSupportedList(false);
Josh Wu049e2cd2022-01-12 05:42:58 -0800876 continue;
877 case CodecType::APTX_ADAPTIVE:
Sagar Verma62df9102022-12-07 17:56:04 +0530878 case CodecType::APTX_ADAPTIVE_LE:
879 case CodecType::APTX_ADAPTIVE_LEX:
Omer Osmana2587da2022-05-01 03:54:11 +0000880 case CodecType::LC3:
Josh Wu049e2cd2022-01-12 05:42:58 -0800881 case CodecType::VENDOR:
882 case CodecType::UNKNOWN:
883 codec_specifics.clear();
884 break;
885 }
886 if (codec_specifics.empty()) {
887 continue;
888 }
889
890 CodecConfiguration codec_config = {
891 .codecType = codec_type,
892 .encodedAudioBitrate = 328000,
893 .peerMtu = 1005,
894 .isScmstEnabled = false,
895 };
896 for (auto codec_specific : codec_specifics) {
897 copy_codec_specific(codec_config.config, codec_specific);
898 DataMQDesc mq_desc;
899 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -0800900 audio_port_, AudioConfiguration(codec_config), latency_modes,
901 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -0800902
903 // AIDL call should fail on invalid codec
904 ASSERT_FALSE(aidl_retval.isOk());
905 EXPECT_TRUE(audio_provider_->endSession().isOk());
906 }
907 }
908}
909
910/**
911 * openProvider HEARING_AID_SOFTWARE_ENCODING_DATAPATH
912 */
913class BluetoothAudioProviderHearingAidSoftwareAidl
914 : public BluetoothAudioProviderFactoryAidl {
915 public:
916 virtual void SetUp() override {
917 BluetoothAudioProviderFactoryAidl::SetUp();
918 GetProviderCapabilitiesHelper(
919 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
920 OpenProviderHelper(SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
921 ASSERT_NE(audio_provider_, nullptr);
922 }
923
924 virtual void TearDown() override {
925 audio_port_ = nullptr;
926 audio_provider_ = nullptr;
927 BluetoothAudioProviderFactoryAidl::TearDown();
928 }
929
930 static constexpr int32_t hearing_aid_sample_rates_[] = {0, 16000, 24000};
931 static constexpr int8_t hearing_aid_bits_per_samples_[] = {0, 16, 24};
932 static constexpr ChannelMode hearing_aid_channel_modes_[] = {
933 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
934};
935
936/**
937 * Test whether we can open a provider of type
938 */
939TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl,
940 OpenHearingAidSoftwareProvider) {}
941
942/**
943 * Test whether each provider of type
944 * SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH can be started and
945 * stopped with different PCM config
946 */
947TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl,
948 StartAndEndHearingAidSessionWithPossiblePcmConfig) {
949 for (int32_t sample_rate : hearing_aid_sample_rates_) {
950 for (int8_t bits_per_sample : hearing_aid_bits_per_samples_) {
951 for (auto channel_mode : hearing_aid_channel_modes_) {
952 PcmConfiguration pcm_config{
953 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -0800954 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +0000955 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -0800956 };
957 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
958 DataMQDesc mq_desc;
959 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -0800960 audio_port_, AudioConfiguration(pcm_config), latency_modes,
961 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -0800962 DataMQ data_mq(mq_desc);
963
964 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
965 if (is_codec_config_valid) {
966 EXPECT_TRUE(data_mq.isValid());
967 }
968 EXPECT_TRUE(audio_provider_->endSession().isOk());
969 }
970 }
971 }
972}
973
974/**
975 * openProvider LE_AUDIO_SOFTWARE_ENCODING_DATAPATH
976 */
977class BluetoothAudioProviderLeAudioOutputSoftwareAidl
978 : public BluetoothAudioProviderFactoryAidl {
979 public:
980 virtual void SetUp() override {
981 BluetoothAudioProviderFactoryAidl::SetUp();
982 GetProviderCapabilitiesHelper(
983 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
984 OpenProviderHelper(SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
985 ASSERT_NE(audio_provider_, nullptr);
986 }
987
988 virtual void TearDown() override {
989 audio_port_ = nullptr;
990 audio_provider_ = nullptr;
991 BluetoothAudioProviderFactoryAidl::TearDown();
992 }
993
994 static constexpr int32_t le_audio_output_sample_rates_[] = {
995 0, 8000, 16000, 24000, 32000, 44100, 48000,
996 };
997 static constexpr int8_t le_audio_output_bits_per_samples_[] = {0, 16, 24};
998 static constexpr ChannelMode le_audio_output_channel_modes_[] = {
999 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
1000 static constexpr int32_t le_audio_output_data_interval_us_[] = {
1001 0 /* Invalid */, 10000 /* Valid 10ms */};
1002};
1003
1004/**
1005 * Test whether each provider of type
1006 * SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH can be started and
1007 * stopped
1008 */
1009TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl,
1010 OpenLeAudioOutputSoftwareProvider) {}
1011
1012/**
1013 * Test whether each provider of type
1014 * SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH can be started and
1015 * stopped with different PCM config
1016 */
1017TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl,
1018 StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
1019 for (auto sample_rate : le_audio_output_sample_rates_) {
1020 for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
1021 for (auto channel_mode : le_audio_output_channel_modes_) {
1022 for (auto data_interval_us : le_audio_output_data_interval_us_) {
1023 PcmConfiguration pcm_config{
1024 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08001025 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00001026 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08001027 .dataIntervalUs = data_interval_us,
1028 };
Josh Wu8a1be762022-02-15 09:37:29 -08001029 bool is_codec_config_valid =
1030 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
Josh Wu049e2cd2022-01-12 05:42:58 -08001031 DataMQDesc mq_desc;
1032 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001033 audio_port_, AudioConfiguration(pcm_config), latency_modes,
1034 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001035 DataMQ data_mq(mq_desc);
1036
1037 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
1038 if (is_codec_config_valid) {
1039 EXPECT_TRUE(data_mq.isValid());
1040 }
1041 EXPECT_TRUE(audio_provider_->endSession().isOk());
1042 }
1043 }
1044 }
1045 }
1046}
1047
1048/**
Alice Kuo04a399a2022-02-16 09:19:56 +08001049 * openProvider LE_AUDIO_SOFTWARE_DECODING_DATAPATH
Josh Wu049e2cd2022-01-12 05:42:58 -08001050 */
1051class BluetoothAudioProviderLeAudioInputSoftwareAidl
1052 : public BluetoothAudioProviderFactoryAidl {
1053 public:
1054 virtual void SetUp() override {
1055 BluetoothAudioProviderFactoryAidl::SetUp();
1056 GetProviderCapabilitiesHelper(
1057 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH);
1058 OpenProviderHelper(SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH);
1059 ASSERT_NE(audio_provider_, nullptr);
1060 }
1061
1062 virtual void TearDown() override {
1063 audio_port_ = nullptr;
1064 audio_provider_ = nullptr;
1065 BluetoothAudioProviderFactoryAidl::TearDown();
1066 }
1067
1068 static constexpr int32_t le_audio_input_sample_rates_[] = {
1069 0, 8000, 16000, 24000, 32000, 44100, 48000};
1070 static constexpr int8_t le_audio_input_bits_per_samples_[] = {0, 16, 24};
1071 static constexpr ChannelMode le_audio_input_channel_modes_[] = {
1072 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
1073 static constexpr int32_t le_audio_input_data_interval_us_[] = {
1074 0 /* Invalid */, 10000 /* Valid 10ms */};
1075};
1076
1077/**
1078 * Test whether each provider of type
Alice Kuo04a399a2022-02-16 09:19:56 +08001079 * SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08001080 * stopped
1081 */
1082TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl,
1083 OpenLeAudioInputSoftwareProvider) {}
1084
1085/**
1086 * Test whether each provider of type
Alice Kuo04a399a2022-02-16 09:19:56 +08001087 * SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08001088 * stopped with different PCM config
1089 */
1090TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl,
1091 StartAndEndLeAudioInputSessionWithPossiblePcmConfig) {
1092 for (auto sample_rate : le_audio_input_sample_rates_) {
1093 for (auto bits_per_sample : le_audio_input_bits_per_samples_) {
1094 for (auto channel_mode : le_audio_input_channel_modes_) {
1095 for (auto data_interval_us : le_audio_input_data_interval_us_) {
1096 PcmConfiguration pcm_config{
1097 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08001098 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00001099 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08001100 .dataIntervalUs = data_interval_us,
1101 };
Josh Wu8a1be762022-02-15 09:37:29 -08001102 bool is_codec_config_valid =
1103 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
Josh Wu049e2cd2022-01-12 05:42:58 -08001104 DataMQDesc mq_desc;
1105 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001106 audio_port_, AudioConfiguration(pcm_config), latency_modes,
1107 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001108 DataMQ data_mq(mq_desc);
1109
1110 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
1111 if (is_codec_config_valid) {
1112 EXPECT_TRUE(data_mq.isValid());
1113 }
1114 EXPECT_TRUE(audio_provider_->endSession().isOk());
1115 }
1116 }
1117 }
1118 }
1119}
1120
1121/**
Alice Kuo04a399a2022-02-16 09:19:56 +08001122 * openProvider LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH
Josh Wu049e2cd2022-01-12 05:42:58 -08001123 */
1124class BluetoothAudioProviderLeAudioOutputHardwareAidl
1125 : public BluetoothAudioProviderFactoryAidl {
1126 public:
1127 virtual void SetUp() override {
1128 BluetoothAudioProviderFactoryAidl::SetUp();
1129 GetProviderCapabilitiesHelper(
1130 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
1131 OpenProviderHelper(
1132 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
1133 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
1134 audio_provider_ != nullptr);
1135 }
1136
1137 virtual void TearDown() override {
1138 audio_port_ = nullptr;
1139 audio_provider_ = nullptr;
1140 BluetoothAudioProviderFactoryAidl::TearDown();
1141 }
1142
1143 bool IsOffloadOutputSupported() {
1144 for (auto& capability : temp_provider_capabilities_) {
1145 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
1146 continue;
1147 }
1148 auto& le_audio_capability =
1149 capability.get<AudioCapabilities::leAudioCapabilities>();
1150 if (le_audio_capability.unicastEncodeCapability.codecType !=
1151 CodecType::UNKNOWN)
1152 return true;
1153 }
1154 return false;
1155 }
1156
1157 std::vector<Lc3Configuration> GetUnicastLc3SupportedList(bool decoding,
1158 bool supported) {
1159 std::vector<Lc3Configuration> le_audio_codec_configs;
1160 if (!supported) {
shihchienc3ab9f5e2022-09-23 08:18:05 +00001161 Lc3Configuration lc3_config{.pcmBitDepth = 0, .samplingFrequencyHz = 0};
Josh Wu049e2cd2022-01-12 05:42:58 -08001162 le_audio_codec_configs.push_back(lc3_config);
1163 return le_audio_codec_configs;
1164 }
1165
1166 // There might be more than one LeAudioCodecCapabilitiesSetting
1167 std::vector<Lc3Capabilities> lc3_capabilities;
1168 for (auto& capability : temp_provider_capabilities_) {
1169 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
1170 continue;
1171 }
1172 auto& le_audio_capability =
1173 capability.get<AudioCapabilities::leAudioCapabilities>();
1174 auto& unicast_capability =
1175 decoding ? le_audio_capability.unicastDecodeCapability
1176 : le_audio_capability.unicastEncodeCapability;
1177 if (unicast_capability.codecType != CodecType::LC3) {
1178 continue;
1179 }
1180 auto& lc3_capability = unicast_capability.leAudioCodecCapabilities.get<
1181 UnicastCapability::LeAudioCodecCapabilities::lc3Capabilities>();
1182 lc3_capabilities.push_back(lc3_capability);
1183 }
1184
1185 // Combine those parameters into one list of LeAudioCodecConfiguration
1186 // This seems horrible, but usually each Lc3Capability only contains a
1187 // single Lc3Configuration, which means every array has a length of 1.
1188 for (auto& lc3_capability : lc3_capabilities) {
1189 for (int32_t samplingFrequencyHz : lc3_capability.samplingFrequencyHz) {
1190 for (int32_t frameDurationUs : lc3_capability.frameDurationUs) {
1191 for (int32_t octetsPerFrame : lc3_capability.octetsPerFrame) {
1192 Lc3Configuration lc3_config = {
1193 .samplingFrequencyHz = samplingFrequencyHz,
1194 .frameDurationUs = frameDurationUs,
1195 .octetsPerFrame = octetsPerFrame,
1196 };
1197 le_audio_codec_configs.push_back(lc3_config);
1198 }
1199 }
1200 }
1201 }
1202
1203 return le_audio_codec_configs;
1204 }
1205
Sagar Verma62df9102022-12-07 17:56:04 +05301206 static constexpr int32_t apx_adaptive_le_config_codec_modes[] = {0, 1, 2, 3};
1207
1208 std::vector<AptxAdaptiveLeConfiguration>
1209 GetUnicastAptxAdaptiveLeSupportedList(bool decoding, bool supported,
1210 bool is_le_extended) {
1211 std::vector<AptxAdaptiveLeConfiguration> le_audio_codec_configs;
1212 if (!supported) {
1213 AptxAdaptiveLeConfiguration aptx_adaptive_le_config{
1214 .pcmBitDepth = 0, .samplingFrequencyHz = 0};
1215 le_audio_codec_configs.push_back(aptx_adaptive_le_config);
1216 return le_audio_codec_configs;
1217 }
1218
1219 // There might be more than one LeAudioCodecCapabilitiesSetting
1220 std::vector<AptxAdaptiveLeCapabilities> aptx_adaptive_le_capabilities;
1221 for (auto& capability : temp_provider_capabilities_) {
1222 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
1223 continue;
1224 }
1225 auto& le_audio_capability =
1226 capability.get<AudioCapabilities::leAudioCapabilities>();
1227 auto& unicast_capability =
1228 decoding ? le_audio_capability.unicastDecodeCapability
1229 : le_audio_capability.unicastEncodeCapability;
1230 if ((!is_le_extended &&
1231 unicast_capability.codecType != CodecType::APTX_ADAPTIVE_LE) ||
1232 (is_le_extended &&
1233 unicast_capability.codecType != CodecType::APTX_ADAPTIVE_LEX)) {
1234 continue;
1235 }
1236
1237 auto& aptx_adaptive_le_capability =
1238 unicast_capability.leAudioCodecCapabilities
1239 .get<UnicastCapability::LeAudioCodecCapabilities::
1240 aptxAdaptiveLeCapabilities>();
1241
1242 aptx_adaptive_le_capabilities.push_back(aptx_adaptive_le_capability);
1243 }
1244
1245 for (auto& aptx_adaptive_le_capability : aptx_adaptive_le_capabilities) {
1246 for (int32_t samplingFrequencyHz :
1247 aptx_adaptive_le_capability.samplingFrequencyHz) {
1248 for (int32_t frameDurationUs :
1249 aptx_adaptive_le_capability.frameDurationUs) {
1250 for (int32_t octetsPerFrame :
1251 aptx_adaptive_le_capability.octetsPerFrame) {
1252 for (int8_t blocksPerSdu :
1253 aptx_adaptive_le_capability.blocksPerSdu) {
1254 for (int32_t codecMode : apx_adaptive_le_config_codec_modes) {
1255 AptxAdaptiveLeConfiguration aptx_adaptive_le_config = {
1256 .samplingFrequencyHz = samplingFrequencyHz,
1257 .frameDurationUs = frameDurationUs,
1258 .octetsPerFrame = octetsPerFrame,
1259 .blocksPerSdu = blocksPerSdu,
1260 .codecMode = codecMode,
1261 };
1262 le_audio_codec_configs.push_back(aptx_adaptive_le_config);
1263 }
1264 }
1265 }
1266 }
1267 }
1268 }
1269
1270 return le_audio_codec_configs;
1271 }
1272
Josh Wu049e2cd2022-01-12 05:42:58 -08001273 LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
1274};
1275
1276/**
1277 * Test whether each provider of type
1278 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
1279 * stopped
1280 */
1281TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
1282 OpenLeAudioOutputHardwareProvider) {}
1283
1284/**
1285 * Test whether each provider of type
1286 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
1287 * stopped with Unicast hardware encoding config
1288 */
1289TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
1290 StartAndEndLeAudioOutputSessionWithPossibleUnicastConfig) {
1291 if (!IsOffloadOutputSupported()) {
1292 return;
1293 }
1294
1295 auto lc3_codec_configs =
1296 GetUnicastLc3SupportedList(false /* decoding */, true /* supported */);
1297 LeAudioConfiguration le_audio_config = {
1298 .codecType = CodecType::LC3,
1299 .peerDelayUs = 0,
1300 };
1301
1302 for (auto& lc3_config : lc3_codec_configs) {
1303 le_audio_config.leAudioCodecConfig
1304 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
1305 DataMQDesc mq_desc;
1306 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001307 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
1308 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001309
1310 ASSERT_TRUE(aidl_retval.isOk());
1311 EXPECT_TRUE(audio_provider_->endSession().isOk());
1312 }
1313}
1314
1315/**
1316 * Test whether each provider of type
1317 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
1318 * stopped with Unicast hardware encoding config
1319 *
1320 * Disabled since offload codec checking is not ready
1321 */
1322TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
1323 DISABLED_StartAndEndLeAudioOutputSessionWithInvalidAudioConfiguration) {
1324 if (!IsOffloadOutputSupported()) {
1325 return;
1326 }
1327
1328 auto lc3_codec_configs =
1329 GetUnicastLc3SupportedList(false /* decoding */, false /* supported */);
1330 LeAudioConfiguration le_audio_config = {
1331 .codecType = CodecType::LC3,
1332 .peerDelayUs = 0,
1333 };
1334
1335 for (auto& lc3_config : lc3_codec_configs) {
1336 le_audio_config.leAudioCodecConfig
1337 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
1338 DataMQDesc mq_desc;
1339 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001340 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
1341 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001342
1343 // AIDL call should fail on invalid codec
1344 ASSERT_FALSE(aidl_retval.isOk());
1345 EXPECT_TRUE(audio_provider_->endSession().isOk());
1346 }
1347}
1348
Sagar Verma62df9102022-12-07 17:56:04 +05301349static std::vector<uint8_t> vendorMetadata = {0x0B, // Length
1350 0xFF, // Type: Vendor-specific
1351 0x0A, 0x00, // Company_ID
1352 0x01, 0x02, 0x03, 0x04, // Data
1353 0x05, 0x06, 0x07, 0x08};
1354
1355/**
1356 * Test whether each provider of type
1357 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
1358 * stopped with Unicast hardware encoding config
1359 */
1360TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
1361 StartAndEndLeAudioOutputSessionWithAptxAdaptiveLeUnicastConfig) {
1362 if (!IsOffloadOutputSupported()) {
1363 return;
1364 }
1365 for (auto codec_type :
1366 {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
1367 bool is_le_extended = (codec_type == CodecType::APTX_ADAPTIVE_LEX);
1368 auto aptx_adaptive_le_codec_configs =
1369 GetUnicastAptxAdaptiveLeSupportedList(false, true, is_le_extended);
1370 LeAudioConfiguration le_audio_config = {
1371 .codecType = codec_type,
1372 .peerDelayUs = 0,
1373 .vendorSpecificMetadata = vendorMetadata,
1374 };
1375
1376 for (auto& aptx_adaptive_le_config : aptx_adaptive_le_codec_configs) {
1377 le_audio_config.leAudioCodecConfig
1378 .set<LeAudioCodecConfiguration::aptxAdaptiveLeConfig>(
1379 aptx_adaptive_le_config);
1380 DataMQDesc mq_desc;
1381 auto aidl_retval = audio_provider_->startSession(
1382 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
1383 &mq_desc);
1384
1385 ASSERT_TRUE(aidl_retval.isOk());
1386 EXPECT_TRUE(audio_provider_->endSession().isOk());
1387 }
1388 }
1389}
1390
1391/**
1392 * Test whether each provider of type
1393 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
1394 * stopped with Unicast hardware encoding config
1395 */
1396TEST_P(
1397 BluetoothAudioProviderLeAudioOutputHardwareAidl,
1398 BluetoothAudioProviderLeAudioOutputHardwareAidl_StartAndEndLeAudioOutputSessionWithInvalidAptxAdaptiveLeAudioConfiguration) {
1399 if (!IsOffloadOutputSupported()) {
1400 return;
1401 }
1402
1403 for (auto codec_type :
1404 {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
1405 bool is_le_extended = (codec_type == CodecType::APTX_ADAPTIVE_LEX);
1406 auto aptx_adaptive_le_codec_configs =
1407 GetUnicastAptxAdaptiveLeSupportedList(false, true, is_le_extended);
1408 LeAudioConfiguration le_audio_config = {
1409 .codecType = codec_type,
1410 .peerDelayUs = 0,
1411 .vendorSpecificMetadata = vendorMetadata,
1412 };
1413
1414 for (auto& aptx_adaptive_le_config : aptx_adaptive_le_codec_configs) {
1415 le_audio_config.leAudioCodecConfig
1416 .set<LeAudioCodecConfiguration::aptxAdaptiveLeConfig>(
1417 aptx_adaptive_le_config);
1418 DataMQDesc mq_desc;
1419 auto aidl_retval = audio_provider_->startSession(
1420 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
1421 &mq_desc);
1422
1423 // AIDL call should fail on invalid codec
1424 ASSERT_FALSE(aidl_retval.isOk());
1425 EXPECT_TRUE(audio_provider_->endSession().isOk());
1426 }
1427 }
1428}
1429
Josh Wu049e2cd2022-01-12 05:42:58 -08001430/**
1431 * openProvider LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH
1432 */
1433class BluetoothAudioProviderLeAudioInputHardwareAidl
1434 : public BluetoothAudioProviderLeAudioOutputHardwareAidl {
1435 public:
1436 virtual void SetUp() override {
1437 BluetoothAudioProviderFactoryAidl::SetUp();
1438 GetProviderCapabilitiesHelper(
1439 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
1440 OpenProviderHelper(
1441 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
1442 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
1443 audio_provider_ != nullptr);
1444 }
1445
1446 bool IsOffloadInputSupported() {
1447 for (auto& capability : temp_provider_capabilities_) {
1448 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
1449 continue;
1450 }
1451 auto& le_audio_capability =
1452 capability.get<AudioCapabilities::leAudioCapabilities>();
1453 if (le_audio_capability.unicastDecodeCapability.codecType !=
1454 CodecType::UNKNOWN)
1455 return true;
1456 }
1457 return false;
1458 }
1459
1460 virtual void TearDown() override {
1461 audio_port_ = nullptr;
1462 audio_provider_ = nullptr;
1463 BluetoothAudioProviderFactoryAidl::TearDown();
1464 }
1465};
1466
1467/**
1468 * Test whether each provider of type
1469 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
1470 * stopped
1471 */
1472TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
1473 OpenLeAudioInputHardwareProvider) {}
1474
1475/**
1476 * Test whether each provider of type
1477 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
1478 * stopped with Unicast hardware encoding config
1479 */
1480TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
1481 StartAndEndLeAudioInputSessionWithPossibleUnicastConfig) {
1482 if (!IsOffloadInputSupported()) {
1483 return;
1484 }
1485
1486 auto lc3_codec_configs =
1487 GetUnicastLc3SupportedList(true /* decoding */, true /* supported */);
1488 LeAudioConfiguration le_audio_config = {
1489 .codecType = CodecType::LC3,
1490 .peerDelayUs = 0,
1491 };
1492
1493 for (auto& lc3_config : lc3_codec_configs) {
1494 le_audio_config.leAudioCodecConfig
1495 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
1496 DataMQDesc mq_desc;
1497 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001498 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
1499 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001500
1501 ASSERT_TRUE(aidl_retval.isOk());
1502 EXPECT_TRUE(audio_provider_->endSession().isOk());
1503 }
1504}
1505
1506/**
1507 * Test whether each provider of type
1508 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
1509 * stopped with Unicast hardware encoding config
1510 *
1511 * Disabled since offload codec checking is not ready
1512 */
1513TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
1514 DISABLED_StartAndEndLeAudioInputSessionWithInvalidAudioConfiguration) {
1515 if (!IsOffloadInputSupported()) {
1516 return;
1517 }
1518
1519 auto lc3_codec_configs =
1520 GetUnicastLc3SupportedList(true /* decoding */, false /* supported */);
1521 LeAudioConfiguration le_audio_config = {
1522 .codecType = CodecType::LC3,
1523 .peerDelayUs = 0,
1524 };
1525
1526 for (auto& lc3_config : lc3_codec_configs) {
1527 le_audio_config.leAudioCodecConfig
1528 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
1529
1530 DataMQDesc mq_desc;
1531 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001532 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
1533 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001534
1535 // AIDL call should fail on invalid codec
1536 ASSERT_FALSE(aidl_retval.isOk());
1537 EXPECT_TRUE(audio_provider_->endSession().isOk());
1538 }
1539}
1540
1541/**
1542 * openProvider LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH
1543 */
1544class BluetoothAudioProviderLeAudioBroadcastSoftwareAidl
1545 : public BluetoothAudioProviderFactoryAidl {
1546 public:
1547 virtual void SetUp() override {
1548 BluetoothAudioProviderFactoryAidl::SetUp();
1549 GetProviderCapabilitiesHelper(
1550 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
1551 OpenProviderHelper(
1552 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
1553 ASSERT_NE(audio_provider_, nullptr);
1554 }
1555
1556 virtual void TearDown() override {
1557 audio_port_ = nullptr;
1558 audio_provider_ = nullptr;
1559 BluetoothAudioProviderFactoryAidl::TearDown();
1560 }
1561
1562 static constexpr int32_t le_audio_output_sample_rates_[] = {
1563 0, 8000, 16000, 24000, 32000, 44100, 48000,
1564 };
1565 static constexpr int8_t le_audio_output_bits_per_samples_[] = {0, 16, 24};
1566 static constexpr ChannelMode le_audio_output_channel_modes_[] = {
1567 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
1568 static constexpr int32_t le_audio_output_data_interval_us_[] = {
1569 0 /* Invalid */, 10000 /* Valid 10ms */};
1570};
1571
1572/**
1573 * Test whether each provider of type
1574 * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started and
1575 * stopped
1576 */
1577TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
Josh Wu3202eab2022-02-17 18:09:05 -08001578 OpenLeAudioOutputSoftwareProvider) {}
Josh Wu049e2cd2022-01-12 05:42:58 -08001579
1580/**
1581 * Test whether each provider of type
1582 * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started and
1583 * stopped with different PCM config
1584 */
1585TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
Josh Wu3202eab2022-02-17 18:09:05 -08001586 StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001587 for (auto sample_rate : le_audio_output_sample_rates_) {
1588 for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
1589 for (auto channel_mode : le_audio_output_channel_modes_) {
1590 for (auto data_interval_us : le_audio_output_data_interval_us_) {
1591 PcmConfiguration pcm_config{
1592 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08001593 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00001594 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08001595 .dataIntervalUs = data_interval_us,
1596 };
Josh Wu8a1be762022-02-15 09:37:29 -08001597 bool is_codec_config_valid =
1598 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
Josh Wu049e2cd2022-01-12 05:42:58 -08001599 DataMQDesc mq_desc;
1600 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001601 audio_port_, AudioConfiguration(pcm_config), latency_modes,
1602 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001603 DataMQ data_mq(mq_desc);
1604
1605 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
1606 if (is_codec_config_valid) {
1607 EXPECT_TRUE(data_mq.isValid());
1608 }
1609 EXPECT_TRUE(audio_provider_->endSession().isOk());
1610 }
1611 }
1612 }
1613 }
1614}
1615
Alice Kuo336d90c2022-02-16 09:09:59 +08001616/**
1617 * openProvider LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH
1618 */
1619class BluetoothAudioProviderLeAudioBroadcastHardwareAidl
1620 : public BluetoothAudioProviderFactoryAidl {
1621 public:
1622 virtual void SetUp() override {
1623 BluetoothAudioProviderFactoryAidl::SetUp();
1624 GetProviderCapabilitiesHelper(
1625 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
1626 OpenProviderHelper(
1627 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
1628 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
1629 audio_provider_ != nullptr);
1630 }
1631
1632 virtual void TearDown() override {
1633 audio_port_ = nullptr;
1634 audio_provider_ = nullptr;
1635 BluetoothAudioProviderFactoryAidl::TearDown();
1636 }
1637
1638 bool IsBroadcastOffloadSupported() {
1639 for (auto& capability : temp_provider_capabilities_) {
1640 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
1641 continue;
1642 }
1643 auto& le_audio_capability =
1644 capability.get<AudioCapabilities::leAudioCapabilities>();
1645 if (le_audio_capability.broadcastCapability.codecType !=
1646 CodecType::UNKNOWN)
1647 return true;
1648 }
1649 return false;
1650 }
1651
1652 std::vector<Lc3Configuration> GetBroadcastLc3SupportedList(bool supported) {
1653 std::vector<Lc3Configuration> le_audio_codec_configs;
1654 if (!supported) {
shihchienc3ab9f5e2022-09-23 08:18:05 +00001655 Lc3Configuration lc3_config{.pcmBitDepth = 0, .samplingFrequencyHz = 0};
Alice Kuo336d90c2022-02-16 09:09:59 +08001656 le_audio_codec_configs.push_back(lc3_config);
1657 return le_audio_codec_configs;
1658 }
1659
1660 // There might be more than one LeAudioCodecCapabilitiesSetting
1661 std::vector<Lc3Capabilities> lc3_capabilities;
1662 for (auto& capability : temp_provider_capabilities_) {
1663 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
1664 continue;
1665 }
1666 auto& le_audio_capability =
1667 capability.get<AudioCapabilities::leAudioCapabilities>();
1668 auto& broadcast_capability = le_audio_capability.broadcastCapability;
1669 if (broadcast_capability.codecType != CodecType::LC3) {
1670 continue;
1671 }
1672 auto& lc3_capability = broadcast_capability.leAudioCodecCapabilities.get<
1673 BroadcastCapability::LeAudioCodecCapabilities::lc3Capabilities>();
1674 for (int idx = 0; idx < lc3_capability->size(); idx++)
1675 lc3_capabilities.push_back(*lc3_capability->at(idx));
1676 }
1677
1678 // Combine those parameters into one list of LeAudioCodecConfiguration
1679 // This seems horrible, but usually each Lc3Capability only contains a
1680 // single Lc3Configuration, which means every array has a length of 1.
1681 for (auto& lc3_capability : lc3_capabilities) {
1682 for (int32_t samplingFrequencyHz : lc3_capability.samplingFrequencyHz) {
1683 for (int32_t frameDurationUs : lc3_capability.frameDurationUs) {
1684 for (int32_t octetsPerFrame : lc3_capability.octetsPerFrame) {
1685 Lc3Configuration lc3_config = {
1686 .samplingFrequencyHz = samplingFrequencyHz,
1687 .frameDurationUs = frameDurationUs,
1688 .octetsPerFrame = octetsPerFrame,
1689 };
1690 le_audio_codec_configs.push_back(lc3_config);
1691 }
1692 }
1693 }
1694 }
1695
1696 return le_audio_codec_configs;
1697 }
1698
1699 LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
1700};
1701
1702/**
1703 * Test whether each provider of type
1704 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
1705 * started and stopped
1706 */
1707TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
1708 OpenLeAudioOutputHardwareProvider) {}
1709
1710/**
1711 * Test whether each provider of type
1712 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
1713 * started and stopped with broadcast hardware encoding config
1714 */
1715TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
1716 StartAndEndLeAudioBroadcastSessionWithPossibleBroadcastConfig) {
1717 if (!IsBroadcastOffloadSupported()) {
1718 return;
1719 }
1720
1721 auto lc3_codec_configs = GetBroadcastLc3SupportedList(true /* supported */);
1722 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
1723 .codecType = CodecType::LC3,
1724 .streamMap = {},
1725 };
1726
1727 for (auto& lc3_config : lc3_codec_configs) {
Patty Huangac077ef2022-11-23 14:45:15 +08001728 le_audio_broadcast_config.streamMap.resize(1);
Alice Kuo336d90c2022-02-16 09:09:59 +08001729 le_audio_broadcast_config.streamMap[0]
1730 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
1731 lc3_config);
Rongxuan Liuc1aea322023-01-26 17:14:54 +00001732 le_audio_broadcast_config.streamMap[0].streamHandle = 0x0;
1733 le_audio_broadcast_config.streamMap[0].pcmStreamId = 0x0;
1734 le_audio_broadcast_config.streamMap[0].audioChannelAllocation = 0x1 << 0;
1735
Alice Kuo336d90c2022-02-16 09:09:59 +08001736 DataMQDesc mq_desc;
1737 auto aidl_retval = audio_provider_->startSession(
Chen Chen60d52e42022-02-16 12:19:12 -08001738 audio_port_, AudioConfiguration(le_audio_broadcast_config),
1739 latency_modes, &mq_desc);
Alice Kuo336d90c2022-02-16 09:09:59 +08001740
1741 ASSERT_TRUE(aidl_retval.isOk());
1742 EXPECT_TRUE(audio_provider_->endSession().isOk());
1743 }
1744}
1745
1746/**
1747 * Test whether each provider of type
1748 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
1749 * started and stopped with Broadcast hardware encoding config
1750 *
1751 * Disabled since offload codec checking is not ready
1752 */
1753TEST_P(
1754 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
1755 DISABLED_StartAndEndLeAudioBroadcastSessionWithInvalidAudioConfiguration) {
1756 if (!IsBroadcastOffloadSupported()) {
1757 return;
1758 }
1759
1760 auto lc3_codec_configs = GetBroadcastLc3SupportedList(false /* supported */);
1761 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
1762 .codecType = CodecType::LC3,
1763 .streamMap = {},
1764 };
1765
1766 for (auto& lc3_config : lc3_codec_configs) {
1767 le_audio_broadcast_config.streamMap[0]
1768 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
1769 lc3_config);
1770 DataMQDesc mq_desc;
1771 auto aidl_retval = audio_provider_->startSession(
Chen Chen60d52e42022-02-16 12:19:12 -08001772 audio_port_, AudioConfiguration(le_audio_broadcast_config),
1773 latency_modes, &mq_desc);
Alice Kuo336d90c2022-02-16 09:09:59 +08001774
1775 // AIDL call should fail on invalid codec
1776 ASSERT_FALSE(aidl_retval.isOk());
1777 EXPECT_TRUE(audio_provider_->endSession().isOk());
1778 }
1779}
1780
Alice Kuoadcceec2022-03-28 13:28:43 +08001781/**
1782 * openProvider A2DP_SOFTWARE_DECODING_DATAPATH
1783 */
1784class BluetoothAudioProviderA2dpDecodingSoftwareAidl
1785 : public BluetoothAudioProviderFactoryAidl {
1786 public:
1787 virtual void SetUp() override {
1788 BluetoothAudioProviderFactoryAidl::SetUp();
1789 GetProviderCapabilitiesHelper(SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
1790 OpenProviderHelper(SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
1791 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
1792 audio_provider_ != nullptr);
1793 }
1794
1795 virtual void TearDown() override {
1796 audio_port_ = nullptr;
1797 audio_provider_ = nullptr;
1798 BluetoothAudioProviderFactoryAidl::TearDown();
1799 }
1800};
1801
1802/**
1803 * Test whether we can open a provider of type
1804 */
1805TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,
1806 OpenA2dpDecodingSoftwareProvider) {}
1807
1808/**
1809 * Test whether each provider of type
1810 * SessionType::A2DP_SOFTWARE_DECODING_DATAPATH can be started and stopped with
1811 * different PCM config
1812 */
1813TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,
1814 StartAndEndA2dpDecodingSoftwareSessionWithPossiblePcmConfig) {
1815 for (auto sample_rate : a2dp_sample_rates) {
1816 for (auto bits_per_sample : a2dp_bits_per_samples) {
1817 for (auto channel_mode : a2dp_channel_modes) {
1818 PcmConfiguration pcm_config{
1819 .sampleRateHz = sample_rate,
Alice Kuoadcceec2022-03-28 13:28:43 +08001820 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00001821 .bitsPerSample = bits_per_sample,
Alice Kuoadcceec2022-03-28 13:28:43 +08001822 };
1823 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
1824 DataMQDesc mq_desc;
1825 auto aidl_retval = audio_provider_->startSession(
1826 audio_port_, AudioConfiguration(pcm_config), latency_modes,
1827 &mq_desc);
1828 DataMQ data_mq(mq_desc);
1829
1830 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
1831 if (is_codec_config_valid) {
1832 EXPECT_TRUE(data_mq.isValid());
1833 }
1834 EXPECT_TRUE(audio_provider_->endSession().isOk());
1835 }
1836 }
1837 }
1838}
1839
1840/**
1841 * openProvider A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH
1842 */
1843class BluetoothAudioProviderA2dpDecodingHardwareAidl
1844 : public BluetoothAudioProviderFactoryAidl {
1845 public:
1846 virtual void SetUp() override {
1847 BluetoothAudioProviderFactoryAidl::SetUp();
1848 GetProviderCapabilitiesHelper(
1849 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
1850 OpenProviderHelper(SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
1851 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
1852 audio_provider_ != nullptr);
1853 }
1854
1855 virtual void TearDown() override {
1856 audio_port_ = nullptr;
1857 audio_provider_ = nullptr;
1858 BluetoothAudioProviderFactoryAidl::TearDown();
1859 }
1860
1861 bool IsOffloadSupported() { return (temp_provider_capabilities_.size() > 0); }
1862};
1863
1864/**
1865 * Test whether we can open a provider of type
1866 */
1867TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
1868 OpenA2dpDecodingHardwareProvider) {}
1869
1870/**
1871 * Test whether each provider of type
1872 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
1873 * SBC hardware encoding config
1874 */
1875TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
1876 StartAndEndA2dpSbcDecodingHardwareSession) {
1877 if (!IsOffloadSupported()) {
1878 return;
1879 }
1880
1881 CodecConfiguration codec_config = {
1882 .codecType = CodecType::SBC,
1883 .encodedAudioBitrate = 328000,
1884 .peerMtu = 1005,
1885 .isScmstEnabled = false,
1886 };
1887 auto sbc_codec_specifics = GetSbcCodecSpecificSupportedList(true);
1888
1889 for (auto& codec_specific : sbc_codec_specifics) {
1890 copy_codec_specific(codec_config.config, codec_specific);
1891 DataMQDesc mq_desc;
1892 auto aidl_retval = audio_provider_->startSession(
1893 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
1894
1895 ASSERT_TRUE(aidl_retval.isOk());
1896 EXPECT_TRUE(audio_provider_->endSession().isOk());
1897 }
1898}
1899
1900/**
1901 * Test whether each provider of type
1902 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
1903 * AAC hardware encoding config
1904 */
1905TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
1906 StartAndEndA2dpAacDecodingHardwareSession) {
1907 if (!IsOffloadSupported()) {
1908 return;
1909 }
1910
1911 CodecConfiguration codec_config = {
1912 .codecType = CodecType::AAC,
1913 .encodedAudioBitrate = 320000,
1914 .peerMtu = 1005,
1915 .isScmstEnabled = false,
1916 };
1917 auto aac_codec_specifics = GetAacCodecSpecificSupportedList(true);
1918
1919 for (auto& codec_specific : aac_codec_specifics) {
1920 copy_codec_specific(codec_config.config, codec_specific);
1921 DataMQDesc mq_desc;
1922 auto aidl_retval = audio_provider_->startSession(
1923 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
1924
1925 ASSERT_TRUE(aidl_retval.isOk());
1926 EXPECT_TRUE(audio_provider_->endSession().isOk());
1927 }
1928}
1929
1930/**
1931 * Test whether each provider of type
1932 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
1933 * LDAC hardware encoding config
1934 */
1935TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
1936 StartAndEndA2dpLdacDecodingHardwareSession) {
1937 if (!IsOffloadSupported()) {
1938 return;
1939 }
1940
1941 CodecConfiguration codec_config = {
1942 .codecType = CodecType::LDAC,
1943 .encodedAudioBitrate = 990000,
1944 .peerMtu = 1005,
1945 .isScmstEnabled = false,
1946 };
1947 auto ldac_codec_specifics = GetLdacCodecSpecificSupportedList(true);
1948
1949 for (auto& codec_specific : ldac_codec_specifics) {
1950 copy_codec_specific(codec_config.config, codec_specific);
1951 DataMQDesc mq_desc;
1952 auto aidl_retval = audio_provider_->startSession(
1953 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
1954
1955 ASSERT_TRUE(aidl_retval.isOk());
1956 EXPECT_TRUE(audio_provider_->endSession().isOk());
1957 }
1958}
1959
1960/**
1961 * Test whether each provider of type
1962 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
Omer Osmana2587da2022-05-01 03:54:11 +00001963 * Opus hardware encoding config
Alice Kuoadcceec2022-03-28 13:28:43 +08001964 */
1965TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
Omer Osmana2587da2022-05-01 03:54:11 +00001966 StartAndEndA2dpOpusDecodingHardwareSession) {
Alice Kuoadcceec2022-03-28 13:28:43 +08001967 if (!IsOffloadSupported()) {
1968 return;
1969 }
1970
1971 CodecConfiguration codec_config = {
Omer Osmana2587da2022-05-01 03:54:11 +00001972 .codecType = CodecType::OPUS,
Alice Kuoadcceec2022-03-28 13:28:43 +08001973 .encodedAudioBitrate = 990000,
1974 .peerMtu = 1005,
1975 .isScmstEnabled = false,
1976 };
Omer Osmana2587da2022-05-01 03:54:11 +00001977 auto opus_codec_specifics = GetOpusCodecSpecificSupportedList(true);
Alice Kuoadcceec2022-03-28 13:28:43 +08001978
Omer Osmana2587da2022-05-01 03:54:11 +00001979 for (auto& codec_specific : opus_codec_specifics) {
Alice Kuoadcceec2022-03-28 13:28:43 +08001980 copy_codec_specific(codec_config.config, codec_specific);
1981 DataMQDesc mq_desc;
1982 auto aidl_retval = audio_provider_->startSession(
1983 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
1984
1985 ASSERT_TRUE(aidl_retval.isOk());
1986 EXPECT_TRUE(audio_provider_->endSession().isOk());
1987 }
1988}
1989
1990/**
1991 * Test whether each provider of type
1992 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
1993 * AptX hardware encoding config
1994 */
1995TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
1996 StartAndEndA2dpAptxDecodingHardwareSession) {
1997 if (!IsOffloadSupported()) {
1998 return;
1999 }
2000
2001 for (auto codec_type : {CodecType::APTX, CodecType::APTX_HD}) {
2002 CodecConfiguration codec_config = {
2003 .codecType = codec_type,
2004 .encodedAudioBitrate =
2005 (codec_type == CodecType::APTX ? 352000 : 576000),
2006 .peerMtu = 1005,
2007 .isScmstEnabled = false,
2008 };
2009
2010 auto aptx_codec_specifics = GetAptxCodecSpecificSupportedList(
2011 (codec_type == CodecType::APTX_HD ? true : false), true);
2012
2013 for (auto& codec_specific : aptx_codec_specifics) {
2014 copy_codec_specific(codec_config.config, codec_specific);
2015 DataMQDesc mq_desc;
2016 auto aidl_retval = audio_provider_->startSession(
2017 audio_port_, AudioConfiguration(codec_config), latency_modes,
2018 &mq_desc);
2019
2020 ASSERT_TRUE(aidl_retval.isOk());
2021 EXPECT_TRUE(audio_provider_->endSession().isOk());
2022 }
2023 }
2024}
2025
2026/**
2027 * Test whether each provider of type
2028 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
2029 * an invalid codec config
2030 */
2031TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
2032 StartAndEndA2dpDecodingHardwareSessionInvalidCodecConfig) {
2033 if (!IsOffloadSupported()) {
2034 return;
2035 }
2036 ASSERT_NE(audio_provider_, nullptr);
2037
2038 std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
Sagar Verma62df9102022-12-07 17:56:04 +05302039 for (auto codec_type : ndk::enum_range<CodecType>()) {
Alice Kuoadcceec2022-03-28 13:28:43 +08002040 switch (codec_type) {
2041 case CodecType::SBC:
2042 codec_specifics = GetSbcCodecSpecificSupportedList(false);
2043 break;
2044 case CodecType::AAC:
2045 codec_specifics = GetAacCodecSpecificSupportedList(false);
2046 break;
2047 case CodecType::LDAC:
2048 codec_specifics = GetLdacCodecSpecificSupportedList(false);
2049 break;
2050 case CodecType::APTX:
2051 codec_specifics = GetAptxCodecSpecificSupportedList(false, false);
2052 break;
2053 case CodecType::APTX_HD:
2054 codec_specifics = GetAptxCodecSpecificSupportedList(true, false);
2055 break;
Omer Osmana2587da2022-05-01 03:54:11 +00002056 case CodecType::OPUS:
2057 codec_specifics = GetOpusCodecSpecificSupportedList(false);
Alice Kuoadcceec2022-03-28 13:28:43 +08002058 continue;
2059 case CodecType::APTX_ADAPTIVE:
Sagar Verma62df9102022-12-07 17:56:04 +05302060 case CodecType::APTX_ADAPTIVE_LE:
2061 case CodecType::APTX_ADAPTIVE_LEX:
Omer Osmana2587da2022-05-01 03:54:11 +00002062 case CodecType::LC3:
Alice Kuoadcceec2022-03-28 13:28:43 +08002063 case CodecType::VENDOR:
2064 case CodecType::UNKNOWN:
2065 codec_specifics.clear();
2066 break;
2067 }
2068 if (codec_specifics.empty()) {
2069 continue;
2070 }
2071
2072 CodecConfiguration codec_config = {
2073 .codecType = codec_type,
2074 .encodedAudioBitrate = 328000,
2075 .peerMtu = 1005,
2076 .isScmstEnabled = false,
2077 };
2078 for (auto codec_specific : codec_specifics) {
2079 copy_codec_specific(codec_config.config, codec_specific);
2080 DataMQDesc mq_desc;
2081 auto aidl_retval = audio_provider_->startSession(
2082 audio_port_, AudioConfiguration(codec_config), latency_modes,
2083 &mq_desc);
2084
2085 // AIDL call should fail on invalid codec
2086 ASSERT_FALSE(aidl_retval.isOk());
2087 EXPECT_TRUE(audio_provider_->endSession().isOk());
2088 }
2089 }
2090}
2091
Josh Wu049e2cd2022-01-12 05:42:58 -08002092GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
2093 BluetoothAudioProviderFactoryAidl);
2094INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderFactoryAidl,
2095 testing::ValuesIn(android::getAidlHalInstanceNames(
2096 IBluetoothAudioProviderFactory::descriptor)),
2097 android::PrintInstanceNameToString);
2098
2099GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
Alice Kuoadcceec2022-03-28 13:28:43 +08002100 BluetoothAudioProviderA2dpEncodingSoftwareAidl);
2101INSTANTIATE_TEST_SUITE_P(PerInstance,
2102 BluetoothAudioProviderA2dpEncodingSoftwareAidl,
Josh Wu049e2cd2022-01-12 05:42:58 -08002103 testing::ValuesIn(android::getAidlHalInstanceNames(
2104 IBluetoothAudioProviderFactory::descriptor)),
2105 android::PrintInstanceNameToString);
2106
2107GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
Alice Kuoadcceec2022-03-28 13:28:43 +08002108 BluetoothAudioProviderA2dpEncodingHardwareAidl);
2109INSTANTIATE_TEST_SUITE_P(PerInstance,
2110 BluetoothAudioProviderA2dpEncodingHardwareAidl,
Josh Wu049e2cd2022-01-12 05:42:58 -08002111 testing::ValuesIn(android::getAidlHalInstanceNames(
2112 IBluetoothAudioProviderFactory::descriptor)),
2113 android::PrintInstanceNameToString);
2114
2115GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
2116 BluetoothAudioProviderHearingAidSoftwareAidl);
2117INSTANTIATE_TEST_SUITE_P(PerInstance,
2118 BluetoothAudioProviderHearingAidSoftwareAidl,
2119 testing::ValuesIn(android::getAidlHalInstanceNames(
2120 IBluetoothAudioProviderFactory::descriptor)),
2121 android::PrintInstanceNameToString);
2122
2123GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
2124 BluetoothAudioProviderLeAudioOutputSoftwareAidl);
2125INSTANTIATE_TEST_SUITE_P(PerInstance,
2126 BluetoothAudioProviderLeAudioOutputSoftwareAidl,
2127 testing::ValuesIn(android::getAidlHalInstanceNames(
2128 IBluetoothAudioProviderFactory::descriptor)),
2129 android::PrintInstanceNameToString);
2130
2131GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
2132 BluetoothAudioProviderLeAudioInputSoftwareAidl);
2133INSTANTIATE_TEST_SUITE_P(PerInstance,
2134 BluetoothAudioProviderLeAudioInputSoftwareAidl,
2135 testing::ValuesIn(android::getAidlHalInstanceNames(
2136 IBluetoothAudioProviderFactory::descriptor)),
2137 android::PrintInstanceNameToString);
2138
2139GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
2140 BluetoothAudioProviderLeAudioOutputHardwareAidl);
2141INSTANTIATE_TEST_SUITE_P(PerInstance,
2142 BluetoothAudioProviderLeAudioOutputHardwareAidl,
2143 testing::ValuesIn(android::getAidlHalInstanceNames(
2144 IBluetoothAudioProviderFactory::descriptor)),
2145 android::PrintInstanceNameToString);
2146
2147GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
2148 BluetoothAudioProviderLeAudioInputHardwareAidl);
2149INSTANTIATE_TEST_SUITE_P(PerInstance,
2150 BluetoothAudioProviderLeAudioInputHardwareAidl,
2151 testing::ValuesIn(android::getAidlHalInstanceNames(
2152 IBluetoothAudioProviderFactory::descriptor)),
2153 android::PrintInstanceNameToString);
2154
2155GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
2156 BluetoothAudioProviderLeAudioBroadcastSoftwareAidl);
2157INSTANTIATE_TEST_SUITE_P(PerInstance,
2158 BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
2159 testing::ValuesIn(android::getAidlHalInstanceNames(
2160 IBluetoothAudioProviderFactory::descriptor)),
2161 android::PrintInstanceNameToString);
2162
Alice Kuo336d90c2022-02-16 09:09:59 +08002163GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
2164 BluetoothAudioProviderLeAudioBroadcastHardwareAidl);
2165INSTANTIATE_TEST_SUITE_P(PerInstance,
2166 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
2167 testing::ValuesIn(android::getAidlHalInstanceNames(
2168 IBluetoothAudioProviderFactory::descriptor)),
2169 android::PrintInstanceNameToString);
Josh Wu049e2cd2022-01-12 05:42:58 -08002170
Alice Kuoadcceec2022-03-28 13:28:43 +08002171GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
2172 BluetoothAudioProviderA2dpDecodingSoftwareAidl);
2173INSTANTIATE_TEST_SUITE_P(PerInstance,
2174 BluetoothAudioProviderA2dpDecodingSoftwareAidl,
2175 testing::ValuesIn(android::getAidlHalInstanceNames(
2176 IBluetoothAudioProviderFactory::descriptor)),
2177 android::PrintInstanceNameToString);
2178
2179GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
2180 BluetoothAudioProviderA2dpDecodingHardwareAidl);
2181INSTANTIATE_TEST_SUITE_P(PerInstance,
2182 BluetoothAudioProviderA2dpDecodingHardwareAidl,
2183 testing::ValuesIn(android::getAidlHalInstanceNames(
2184 IBluetoothAudioProviderFactory::descriptor)),
2185 android::PrintInstanceNameToString);
2186
Josh Wu049e2cd2022-01-12 05:42:58 -08002187int main(int argc, char** argv) {
2188 ::testing::InitGoogleTest(&argc, argv);
2189 ABinderProcess_setThreadPoolMaxThreadCount(1);
2190 ABinderProcess_startThreadPool();
2191 return RUN_ALL_TESTS();
2192}