blob: 40cd821989c81e9d8119ae76e13d23866c84f3b9 [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;
Antoine SOULIER8c90f1f2023-09-26 18:55:17 +000049using aidl::android::hardware::bluetooth::audio::CodecId;
50using aidl::android::hardware::bluetooth::audio::CodecInfo;
Josh Wu049e2cd2022-01-12 05:42:58 -080051using aidl::android::hardware::bluetooth::audio::CodecType;
52using aidl::android::hardware::bluetooth::audio::IBluetoothAudioPort;
53using aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider;
54using aidl::android::hardware::bluetooth::audio::IBluetoothAudioProviderFactory;
55using aidl::android::hardware::bluetooth::audio::LatencyMode;
56using aidl::android::hardware::bluetooth::audio::Lc3Capabilities;
57using aidl::android::hardware::bluetooth::audio::Lc3Configuration;
58using aidl::android::hardware::bluetooth::audio::LdacCapabilities;
59using aidl::android::hardware::bluetooth::audio::LdacConfiguration;
Alice Kuo336d90c2022-02-16 09:09:59 +080060using aidl::android::hardware::bluetooth::audio::LeAudioBroadcastConfiguration;
Josh Wu049e2cd2022-01-12 05:42:58 -080061using aidl::android::hardware::bluetooth::audio::
62 LeAudioCodecCapabilitiesSetting;
63using aidl::android::hardware::bluetooth::audio::LeAudioCodecConfiguration;
64using aidl::android::hardware::bluetooth::audio::LeAudioConfiguration;
Omer Osmana2587da2022-05-01 03:54:11 +000065using aidl::android::hardware::bluetooth::audio::OpusCapabilities;
66using aidl::android::hardware::bluetooth::audio::OpusConfiguration;
Josh Wu049e2cd2022-01-12 05:42:58 -080067using aidl::android::hardware::bluetooth::audio::PcmConfiguration;
68using aidl::android::hardware::bluetooth::audio::PresentationPosition;
69using aidl::android::hardware::bluetooth::audio::SbcAllocMethod;
70using aidl::android::hardware::bluetooth::audio::SbcCapabilities;
71using aidl::android::hardware::bluetooth::audio::SbcChannelMode;
72using aidl::android::hardware::bluetooth::audio::SbcConfiguration;
73using aidl::android::hardware::bluetooth::audio::SessionType;
74using aidl::android::hardware::bluetooth::audio::UnicastCapability;
75using aidl::android::hardware::common::fmq::MQDescriptor;
76using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
77using android::AidlMessageQueue;
78using android::ProcessState;
79using android::String16;
80using ndk::ScopedAStatus;
81using ndk::SpAIBinder;
82
83using MqDataType = int8_t;
84using MqDataMode = SynchronizedReadWrite;
85using DataMQ = AidlMessageQueue<MqDataType, MqDataMode>;
86using DataMQDesc = MQDescriptor<MqDataType, MqDataMode>;
87
88// Constants
89
90static constexpr int32_t a2dp_sample_rates[] = {0, 44100, 48000, 88200, 96000};
91static constexpr int8_t a2dp_bits_per_samples[] = {0, 16, 24, 32};
92static constexpr ChannelMode a2dp_channel_modes[] = {
93 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
Chen Chenc92270e2022-02-14 18:29:52 -080094static std::vector<LatencyMode> latency_modes = {LatencyMode::FREE};
Josh Wu049e2cd2022-01-12 05:42:58 -080095// Helpers
96
97template <typename T>
98struct identity {
99 typedef T type;
100};
101
102template <class T>
103bool contained_in_vector(const std::vector<T>& vector,
104 const typename identity<T>::type& target) {
105 return std::find(vector.begin(), vector.end(), target) != vector.end();
106}
107
108void copy_codec_specific(CodecConfiguration::CodecSpecific& dst,
109 const CodecConfiguration::CodecSpecific& src) {
110 switch (src.getTag()) {
111 case CodecConfiguration::CodecSpecific::sbcConfig:
112 dst.set<CodecConfiguration::CodecSpecific::sbcConfig>(
113 src.get<CodecConfiguration::CodecSpecific::sbcConfig>());
114 break;
115 case CodecConfiguration::CodecSpecific::aacConfig:
116 dst.set<CodecConfiguration::CodecSpecific::aacConfig>(
117 src.get<CodecConfiguration::CodecSpecific::aacConfig>());
118 break;
119 case CodecConfiguration::CodecSpecific::ldacConfig:
120 dst.set<CodecConfiguration::CodecSpecific::ldacConfig>(
121 src.get<CodecConfiguration::CodecSpecific::ldacConfig>());
122 break;
123 case CodecConfiguration::CodecSpecific::aptxConfig:
124 dst.set<CodecConfiguration::CodecSpecific::aptxConfig>(
125 src.get<CodecConfiguration::CodecSpecific::aptxConfig>());
126 break;
Omer Osmana2587da2022-05-01 03:54:11 +0000127 case CodecConfiguration::CodecSpecific::opusConfig:
128 dst.set<CodecConfiguration::CodecSpecific::opusConfig>(
129 src.get<CodecConfiguration::CodecSpecific::opusConfig>());
Josh Wu049e2cd2022-01-12 05:42:58 -0800130 break;
131 case CodecConfiguration::CodecSpecific::aptxAdaptiveConfig:
132 dst.set<CodecConfiguration::CodecSpecific::aptxAdaptiveConfig>(
133 src.get<CodecConfiguration::CodecSpecific::aptxAdaptiveConfig>());
134 break;
135 default:
136 break;
137 }
138}
139
140class BluetoothAudioPort : public BnBluetoothAudioPort {
141 public:
142 BluetoothAudioPort() {}
143
Chen Chen0a68a922022-02-15 18:43:26 -0800144 ndk::ScopedAStatus startStream(bool) { return ScopedAStatus::ok(); }
Josh Wu049e2cd2022-01-12 05:42:58 -0800145
146 ndk::ScopedAStatus suspendStream() { return ScopedAStatus::ok(); }
147
148 ndk::ScopedAStatus stopStream() { return ScopedAStatus::ok(); }
149
150 ndk::ScopedAStatus getPresentationPosition(PresentationPosition*) {
151 return ScopedAStatus::ok();
152 }
153
154 ndk::ScopedAStatus updateSourceMetadata(const SourceMetadata&) {
155 return ScopedAStatus::ok();
156 }
157
158 ndk::ScopedAStatus updateSinkMetadata(const SinkMetadata&) {
159 return ScopedAStatus::ok();
160 }
161
162 ndk::ScopedAStatus setLatencyMode(const LatencyMode) {
163 return ScopedAStatus::ok();
164 }
165
166 ndk::ScopedAStatus setCodecType(const CodecType) {
167 return ScopedAStatus::ok();
168 }
169
170 protected:
171 virtual ~BluetoothAudioPort() = default;
172};
173
174class BluetoothAudioProviderFactoryAidl
175 : public testing::TestWithParam<std::string> {
176 public:
177 virtual void SetUp() override {
178 provider_factory_ = IBluetoothAudioProviderFactory::fromBinder(
179 SpAIBinder(AServiceManager_getService(GetParam().c_str())));
180 audio_provider_ = nullptr;
181 ASSERT_NE(provider_factory_, nullptr);
182 }
183
184 virtual void TearDown() override { provider_factory_ = nullptr; }
185
186 void GetProviderCapabilitiesHelper(const SessionType& session_type) {
187 temp_provider_capabilities_.clear();
188 auto aidl_retval = provider_factory_->getProviderCapabilities(
189 session_type, &temp_provider_capabilities_);
190 // AIDL calls should not be failed and callback has to be executed
191 ASSERT_TRUE(aidl_retval.isOk());
192 switch (session_type) {
193 case SessionType::UNKNOWN: {
194 ASSERT_TRUE(temp_provider_capabilities_.empty());
195 } break;
196 case SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH:
197 case SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH:
198 case SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH:
199 case SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH:
200 case SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH: {
201 // All software paths are mandatory and must have exact 1
202 // "PcmParameters"
203 ASSERT_EQ(temp_provider_capabilities_.size(), 1);
204 ASSERT_EQ(temp_provider_capabilities_[0].getTag(),
205 AudioCapabilities::pcmCapabilities);
206 } break;
Alice Kuoadcceec2022-03-28 13:28:43 +0800207 case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
208 case SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH: {
Josh Wu049e2cd2022-01-12 05:42:58 -0800209 std::unordered_set<CodecType> codec_types;
210 // empty capability means offload is unsupported
211 for (auto& audio_capability : temp_provider_capabilities_) {
212 ASSERT_EQ(audio_capability.getTag(),
213 AudioCapabilities::a2dpCapabilities);
214 const auto& codec_capabilities =
215 audio_capability.get<AudioCapabilities::a2dpCapabilities>();
216 // Every codec can present once at most
217 ASSERT_EQ(codec_types.count(codec_capabilities.codecType), 0);
218 switch (codec_capabilities.codecType) {
219 case CodecType::SBC:
220 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
221 CodecCapabilities::Capabilities::sbcCapabilities);
222 break;
223 case CodecType::AAC:
224 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
225 CodecCapabilities::Capabilities::aacCapabilities);
226 break;
227 case CodecType::APTX:
228 case CodecType::APTX_HD:
229 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
230 CodecCapabilities::Capabilities::aptxCapabilities);
231 break;
232 case CodecType::LDAC:
233 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
234 CodecCapabilities::Capabilities::ldacCapabilities);
235 break;
Omer Osmana2587da2022-05-01 03:54:11 +0000236 case CodecType::OPUS:
Josh Wu049e2cd2022-01-12 05:42:58 -0800237 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
Omer Osmana2587da2022-05-01 03:54:11 +0000238 CodecCapabilities::Capabilities::opusCapabilities);
Josh Wu049e2cd2022-01-12 05:42:58 -0800239 break;
240 case CodecType::APTX_ADAPTIVE:
Sagar Verma62df9102022-12-07 17:56:04 +0530241 case CodecType::APTX_ADAPTIVE_LE:
242 case CodecType::APTX_ADAPTIVE_LEX:
Omer Osmana2587da2022-05-01 03:54:11 +0000243 case CodecType::LC3:
Josh Wu049e2cd2022-01-12 05:42:58 -0800244 case CodecType::VENDOR:
245 case CodecType::UNKNOWN:
246 break;
247 }
248 codec_types.insert(codec_capabilities.codecType);
249 }
250 } break;
251 case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
252 case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
253 case SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH: {
shihchienc3ab9f5e2022-09-23 08:18:05 +0000254 // empty capability means offload is unsupported since capabilities are
255 // not hardcoded
Josh Wu049e2cd2022-01-12 05:42:58 -0800256 for (auto audio_capability : temp_provider_capabilities_) {
257 ASSERT_EQ(audio_capability.getTag(),
258 AudioCapabilities::leAudioCapabilities);
259 }
260 } break;
Alice Kuoadcceec2022-03-28 13:28:43 +0800261 case SessionType::A2DP_SOFTWARE_DECODING_DATAPATH: {
262 if (!temp_provider_capabilities_.empty()) {
263 ASSERT_EQ(temp_provider_capabilities_.size(), 1);
264 ASSERT_EQ(temp_provider_capabilities_[0].getTag(),
265 AudioCapabilities::pcmCapabilities);
266 }
267 } break;
268 default: {
269 ASSERT_TRUE(temp_provider_capabilities_.empty());
270 }
Josh Wu049e2cd2022-01-12 05:42:58 -0800271 }
272 }
273
274 /***
275 * This helps to open the specified provider and check the openProvider()
276 * has corruct return values. BUT, to keep it simple, it does not consider
277 * the capability, and please do so at the SetUp of each session's test.
278 ***/
279 void OpenProviderHelper(const SessionType& session_type) {
280 auto aidl_retval =
281 provider_factory_->openProvider(session_type, &audio_provider_);
282 if (aidl_retval.isOk()) {
283 ASSERT_NE(session_type, SessionType::UNKNOWN);
284 ASSERT_NE(audio_provider_, nullptr);
285 audio_port_ = ndk::SharedRefBase::make<BluetoothAudioPort>();
286 } else {
Alice Kuoadcceec2022-03-28 13:28:43 +0800287 // optional session type
Josh Wu049e2cd2022-01-12 05:42:58 -0800288 ASSERT_TRUE(
289 session_type == SessionType::UNKNOWN ||
290 session_type ==
291 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
292 session_type ==
293 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
294 session_type ==
295 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
296 session_type ==
297 SessionType::
Alice Kuoadcceec2022-03-28 13:28:43 +0800298 LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
299 session_type ==
300 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
301 session_type == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
Josh Wu049e2cd2022-01-12 05:42:58 -0800302 ASSERT_EQ(audio_provider_, nullptr);
303 }
304 }
305
Josh Wu049e2cd2022-01-12 05:42:58 -0800306 void GetA2dpOffloadCapabilityHelper(const CodecType& codec_type) {
307 temp_codec_capabilities_ = nullptr;
Josh Wu4d2938f2022-02-15 09:21:10 -0800308 for (auto& codec_capability : temp_provider_capabilities_) {
Josh Wu049e2cd2022-01-12 05:42:58 -0800309 auto& a2dp_capabilities =
310 codec_capability.get<AudioCapabilities::a2dpCapabilities>();
311 if (a2dp_capabilities.codecType != codec_type) {
312 continue;
313 }
314 temp_codec_capabilities_ = &a2dp_capabilities;
315 }
316 }
317
318 std::vector<CodecConfiguration::CodecSpecific>
319 GetSbcCodecSpecificSupportedList(bool supported) {
320 std::vector<CodecConfiguration::CodecSpecific> sbc_codec_specifics;
321 if (!supported) {
322 SbcConfiguration sbc_config{.sampleRateHz = 0, .bitsPerSample = 0};
323 sbc_codec_specifics.push_back(
324 CodecConfiguration::CodecSpecific(sbc_config));
325 return sbc_codec_specifics;
326 }
327 GetA2dpOffloadCapabilityHelper(CodecType::SBC);
328 if (temp_codec_capabilities_ == nullptr ||
329 temp_codec_capabilities_->codecType != CodecType::SBC) {
330 return sbc_codec_specifics;
331 }
332 // parse the capability
333 auto& sbc_capability =
334 temp_codec_capabilities_->capabilities
335 .get<CodecCapabilities::Capabilities::sbcCapabilities>();
336 if (sbc_capability.minBitpool > sbc_capability.maxBitpool) {
337 return sbc_codec_specifics;
338 }
339
340 // combine those parameters into one list of
341 // CodecConfiguration::CodecSpecific
342 for (int32_t sample_rate : sbc_capability.sampleRateHz) {
343 for (int8_t block_length : sbc_capability.blockLength) {
344 for (int8_t num_subbands : sbc_capability.numSubbands) {
345 for (int8_t bits_per_sample : sbc_capability.bitsPerSample) {
346 for (auto channel_mode : sbc_capability.channelMode) {
347 for (auto alloc_method : sbc_capability.allocMethod) {
348 SbcConfiguration sbc_data = {
349 .sampleRateHz = sample_rate,
350 .channelMode = channel_mode,
351 .blockLength = block_length,
352 .numSubbands = num_subbands,
353 .allocMethod = alloc_method,
354 .bitsPerSample = bits_per_sample,
355 .minBitpool = sbc_capability.minBitpool,
356 .maxBitpool = sbc_capability.maxBitpool};
357 sbc_codec_specifics.push_back(
358 CodecConfiguration::CodecSpecific(sbc_data));
359 }
360 }
361 }
362 }
363 }
364 }
365 return sbc_codec_specifics;
366 }
367
368 std::vector<CodecConfiguration::CodecSpecific>
369 GetAacCodecSpecificSupportedList(bool supported) {
370 std::vector<CodecConfiguration::CodecSpecific> aac_codec_specifics;
371 if (!supported) {
372 AacConfiguration aac_config{.sampleRateHz = 0, .bitsPerSample = 0};
373 aac_codec_specifics.push_back(
374 CodecConfiguration::CodecSpecific(aac_config));
375 return aac_codec_specifics;
376 }
377 GetA2dpOffloadCapabilityHelper(CodecType::AAC);
378 if (temp_codec_capabilities_ == nullptr ||
379 temp_codec_capabilities_->codecType != CodecType::AAC) {
380 return aac_codec_specifics;
381 }
382 // parse the capability
383 auto& aac_capability =
384 temp_codec_capabilities_->capabilities
385 .get<CodecCapabilities::Capabilities::aacCapabilities>();
386
387 std::vector<bool> variable_bit_rate_enableds = {false};
388 if (aac_capability.variableBitRateSupported) {
389 variable_bit_rate_enableds.push_back(true);
390 }
391
Sagar Verma62df9102022-12-07 17:56:04 +0530392 std::vector<bool> adaptive_bit_rate_supporteds = {false};
393 if (aac_capability.adaptiveBitRateSupported) {
394 adaptive_bit_rate_supporteds.push_back(true);
395 }
396
Josh Wu049e2cd2022-01-12 05:42:58 -0800397 // combine those parameters into one list of
398 // CodecConfiguration::CodecSpecific
399 for (auto object_type : aac_capability.objectType) {
400 for (int32_t sample_rate : aac_capability.sampleRateHz) {
401 for (auto channel_mode : aac_capability.channelMode) {
402 for (int8_t bits_per_sample : aac_capability.bitsPerSample) {
403 for (auto variable_bit_rate_enabled : variable_bit_rate_enableds) {
Sagar Verma62df9102022-12-07 17:56:04 +0530404 for (auto adaptive_bit_rate_supported :
405 adaptive_bit_rate_supporteds) {
406 AacConfiguration aac_data{
407 .objectType = object_type,
408 .sampleRateHz = sample_rate,
409 .channelMode = channel_mode,
410 .variableBitRateEnabled = variable_bit_rate_enabled,
411 .bitsPerSample = bits_per_sample,
412 .adaptiveBitRateSupported = adaptive_bit_rate_supported};
413 aac_codec_specifics.push_back(
414 CodecConfiguration::CodecSpecific(aac_data));
415 }
Josh Wu049e2cd2022-01-12 05:42:58 -0800416 }
417 }
418 }
419 }
420 }
421 return aac_codec_specifics;
422 }
423
424 std::vector<CodecConfiguration::CodecSpecific>
425 GetLdacCodecSpecificSupportedList(bool supported) {
426 std::vector<CodecConfiguration::CodecSpecific> ldac_codec_specifics;
427 if (!supported) {
428 LdacConfiguration ldac_config{.sampleRateHz = 0, .bitsPerSample = 0};
429 ldac_codec_specifics.push_back(
430 CodecConfiguration::CodecSpecific(ldac_config));
431 return ldac_codec_specifics;
432 }
433 GetA2dpOffloadCapabilityHelper(CodecType::LDAC);
434 if (temp_codec_capabilities_ == nullptr ||
435 temp_codec_capabilities_->codecType != CodecType::LDAC) {
436 return ldac_codec_specifics;
437 }
438 // parse the capability
439 auto& ldac_capability =
440 temp_codec_capabilities_->capabilities
441 .get<CodecCapabilities::Capabilities::ldacCapabilities>();
442
443 // combine those parameters into one list of
444 // CodecConfiguration::CodecSpecific
445 for (int32_t sample_rate : ldac_capability.sampleRateHz) {
446 for (int8_t bits_per_sample : ldac_capability.bitsPerSample) {
447 for (auto channel_mode : ldac_capability.channelMode) {
448 for (auto quality_index : ldac_capability.qualityIndex) {
449 LdacConfiguration ldac_data{.sampleRateHz = sample_rate,
450 .channelMode = channel_mode,
451 .qualityIndex = quality_index,
452 .bitsPerSample = bits_per_sample};
453 ldac_codec_specifics.push_back(
454 CodecConfiguration::CodecSpecific(ldac_data));
455 }
456 }
457 }
458 }
459 return ldac_codec_specifics;
460 }
461
462 std::vector<CodecConfiguration::CodecSpecific>
463 GetAptxCodecSpecificSupportedList(bool is_hd, bool supported) {
464 std::vector<CodecConfiguration::CodecSpecific> aptx_codec_specifics;
465 if (!supported) {
466 AptxConfiguration aptx_config{.sampleRateHz = 0, .bitsPerSample = 0};
467 aptx_codec_specifics.push_back(
468 CodecConfiguration::CodecSpecific(aptx_config));
469 return aptx_codec_specifics;
470 }
471 GetA2dpOffloadCapabilityHelper(
472 (is_hd ? CodecType::APTX_HD : CodecType::APTX));
473 if (temp_codec_capabilities_ == nullptr) {
474 return aptx_codec_specifics;
475 }
476 if ((is_hd && temp_codec_capabilities_->codecType != CodecType::APTX_HD) ||
477 (!is_hd && temp_codec_capabilities_->codecType != CodecType::APTX)) {
478 return aptx_codec_specifics;
479 }
480
481 // parse the capability
482 auto& aptx_capability =
483 temp_codec_capabilities_->capabilities
484 .get<CodecCapabilities::Capabilities::aptxCapabilities>();
485
486 // combine those parameters into one list of
487 // CodecConfiguration::CodecSpecific
488 for (int8_t bits_per_sample : aptx_capability.bitsPerSample) {
489 for (int32_t sample_rate : aptx_capability.sampleRateHz) {
490 for (auto channel_mode : aptx_capability.channelMode) {
491 AptxConfiguration aptx_data{.sampleRateHz = sample_rate,
492 .channelMode = channel_mode,
493 .bitsPerSample = bits_per_sample};
494 aptx_codec_specifics.push_back(
495 CodecConfiguration::CodecSpecific(aptx_data));
496 }
497 }
498 }
499 return aptx_codec_specifics;
500 }
501
502 std::vector<CodecConfiguration::CodecSpecific>
Omer Osmana2587da2022-05-01 03:54:11 +0000503 GetOpusCodecSpecificSupportedList(bool supported) {
504 std::vector<CodecConfiguration::CodecSpecific> opus_codec_specifics;
Josh Wu049e2cd2022-01-12 05:42:58 -0800505 if (!supported) {
Omer Osmana2587da2022-05-01 03:54:11 +0000506 OpusConfiguration opus_config{.samplingFrequencyHz = 0,
507 .frameDurationUs = 0};
508 opus_codec_specifics.push_back(
509 CodecConfiguration::CodecSpecific(opus_config));
510 return opus_codec_specifics;
Josh Wu049e2cd2022-01-12 05:42:58 -0800511 }
Omer Osmana2587da2022-05-01 03:54:11 +0000512 GetA2dpOffloadCapabilityHelper(CodecType::OPUS);
Josh Wu049e2cd2022-01-12 05:42:58 -0800513 if (temp_codec_capabilities_ == nullptr ||
Omer Osmana2587da2022-05-01 03:54:11 +0000514 temp_codec_capabilities_->codecType != CodecType::OPUS) {
515 return opus_codec_specifics;
Josh Wu049e2cd2022-01-12 05:42:58 -0800516 }
517 // parse the capability
Omer Osmana2587da2022-05-01 03:54:11 +0000518 auto& opus_capability =
Josh Wu049e2cd2022-01-12 05:42:58 -0800519 temp_codec_capabilities_->capabilities
Omer Osmana2587da2022-05-01 03:54:11 +0000520 .get<CodecCapabilities::Capabilities::opusCapabilities>();
Josh Wu049e2cd2022-01-12 05:42:58 -0800521
522 // combine those parameters into one list of
523 // CodecConfiguration::CodecSpecific
Omer Osmana2587da2022-05-01 03:54:11 +0000524 for (int32_t samplingFrequencyHz : opus_capability->samplingFrequencyHz) {
525 for (int32_t frameDurationUs : opus_capability->frameDurationUs) {
526 for (auto channel_mode : opus_capability->channelMode) {
527 OpusConfiguration opus_data{
528 .samplingFrequencyHz = samplingFrequencyHz,
shihchienc3ab9f5e2022-09-23 08:18:05 +0000529 .frameDurationUs = frameDurationUs,
Omer Osmana2587da2022-05-01 03:54:11 +0000530 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +0000531 };
Omer Osmana2587da2022-05-01 03:54:11 +0000532 opus_codec_specifics.push_back(
533 CodecConfiguration::CodecSpecific(opus_data));
Josh Wu049e2cd2022-01-12 05:42:58 -0800534 }
535 }
536 }
Omer Osmana2587da2022-05-01 03:54:11 +0000537 return opus_codec_specifics;
Josh Wu049e2cd2022-01-12 05:42:58 -0800538 }
539
Alice Kuoadcceec2022-03-28 13:28:43 +0800540 bool IsPcmConfigSupported(const PcmConfiguration& pcm_config) {
541 if (temp_provider_capabilities_.size() != 1 ||
542 temp_provider_capabilities_[0].getTag() !=
543 AudioCapabilities::pcmCapabilities) {
544 return false;
545 }
546 auto pcm_capability = temp_provider_capabilities_[0]
547 .get<AudioCapabilities::pcmCapabilities>();
548 return (contained_in_vector(pcm_capability.channelMode,
549 pcm_config.channelMode) &&
550 contained_in_vector(pcm_capability.sampleRateHz,
551 pcm_config.sampleRateHz) &&
552 contained_in_vector(pcm_capability.bitsPerSample,
553 pcm_config.bitsPerSample));
554 }
555
556 std::shared_ptr<IBluetoothAudioProviderFactory> provider_factory_;
557 std::shared_ptr<IBluetoothAudioProvider> audio_provider_;
558 std::shared_ptr<IBluetoothAudioPort> audio_port_;
559 std::vector<AudioCapabilities> temp_provider_capabilities_;
560
Josh Wu049e2cd2022-01-12 05:42:58 -0800561 // temp storage saves the specified codec capability by
562 // GetOffloadCodecCapabilityHelper()
563 CodecCapabilities* temp_codec_capabilities_;
Alice Kuoadcceec2022-03-28 13:28:43 +0800564
565 static constexpr SessionType kSessionTypes[] = {
566 SessionType::UNKNOWN,
567 SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
568 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
569 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
570 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
571 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
572 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
573 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
574 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
575 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
576 SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
577 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
578 };
579};
580
581/**
582 * Test whether we can get the FactoryService from HIDL
583 */
584TEST_P(BluetoothAudioProviderFactoryAidl, GetProviderFactoryService) {}
585
586/**
587 * Test whether we can open a provider for each provider returned by
588 * getProviderCapabilities() with non-empty capabalities
589 */
590TEST_P(BluetoothAudioProviderFactoryAidl,
591 OpenProviderAndCheckCapabilitiesBySession) {
592 for (auto session_type : kSessionTypes) {
593 GetProviderCapabilitiesHelper(session_type);
594 OpenProviderHelper(session_type);
595 // We must be able to open a provider if its getProviderCapabilities()
596 // returns non-empty list.
597 EXPECT_TRUE(temp_provider_capabilities_.empty() ||
598 audio_provider_ != nullptr);
599 }
600}
601
602/**
Antoine SOULIER8c90f1f2023-09-26 18:55:17 +0000603 * Test that getProviderInfo, when implemented,
604 * returns empty information for session types for
605 * software data paths.
606 */
607TEST_P(BluetoothAudioProviderFactoryAidl, getProviderInfo_invalidSessionTypes) {
608 static constexpr SessionType kInvalidSessionTypes[]{
609 SessionType::UNKNOWN,
610 SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
611 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
612 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
613 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
614 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
615 SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
616 };
617
618 for (auto session_type : kInvalidSessionTypes) {
619 std::optional<IBluetoothAudioProviderFactory::ProviderInfo> provider_info =
620 std::nullopt;
621 auto aidl_retval =
622 provider_factory_->getProviderInfo(session_type, &provider_info);
623 if (!aidl_retval.isOk()) {
624 continue;
625 }
626
627 // If getProviderInfo is supported, the provider info
628 // must be empty for software session types.
629 ASSERT_FALSE(provider_info.has_value());
630 }
631}
632
633/**
634 * Test that getProviderInfo, when implemented,
635 * returns valid information for session types for
636 * a2dp hardware data paths.
637 */
638TEST_P(BluetoothAudioProviderFactoryAidl, getProviderInfo_a2dpSessionTypes) {
639 static constexpr SessionType kA2dpSessionTypes[]{
640 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
641 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
642 };
643
644 for (auto session_type : kA2dpSessionTypes) {
645 std::optional<IBluetoothAudioProviderFactory::ProviderInfo> provider_info =
646 std::nullopt;
647 auto aidl_retval =
648 provider_factory_->getProviderInfo(session_type, &provider_info);
649 if (!aidl_retval.isOk() || !provider_info.has_value()) {
650 continue;
651 }
652
653 for (auto const& codec_info : provider_info->codecInfos) {
654 // The codec id must not be core.
655 ASSERT_NE(codec_info.id.getTag(), CodecId::core);
656 // The codec info must contain the information
657 // for a2dp transport.
658 ASSERT_EQ(codec_info.transport.getTag(), CodecInfo::Transport::a2dp);
659 }
660 }
661}
662
663/**
664 * Test that getProviderInfo, when implemented,
665 * returns valid information for session types for
666 * le audio hardware data paths.
667 */
668TEST_P(BluetoothAudioProviderFactoryAidl, getProviderInfo_leAudioSessionTypes) {
669 static constexpr SessionType kLeAudioSessionTypes[]{
670 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
671 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
672 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
673 };
674
675 for (auto session_type : kLeAudioSessionTypes) {
676 std::optional<IBluetoothAudioProviderFactory::ProviderInfo> provider_info =
677 std::nullopt;
678 auto aidl_retval =
679 provider_factory_->getProviderInfo(session_type, &provider_info);
680 if (!aidl_retval.isOk() || !provider_info.has_value()) {
681 continue;
682 }
683
684 for (auto const& codec_info : provider_info->codecInfos) {
685 // The codec id must not be a2dp.
686 ASSERT_NE(codec_info.id.getTag(), CodecId::a2dp);
687 // The codec info must contain the information
688 // for le audio transport.
689 // ASSERT_EQ(codec_info.transport.getTag(),
690 // CodecInfo::Transport::le_audio);
691 }
692 }
693}
694
695/**
Alice Kuoadcceec2022-03-28 13:28:43 +0800696 * openProvider A2DP_SOFTWARE_ENCODING_DATAPATH
697 */
698class BluetoothAudioProviderA2dpEncodingSoftwareAidl
699 : public BluetoothAudioProviderFactoryAidl {
700 public:
701 virtual void SetUp() override {
702 BluetoothAudioProviderFactoryAidl::SetUp();
703 GetProviderCapabilitiesHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
704 OpenProviderHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
705 ASSERT_NE(audio_provider_, nullptr);
706 }
707
708 virtual void TearDown() override {
709 audio_port_ = nullptr;
710 audio_provider_ = nullptr;
711 BluetoothAudioProviderFactoryAidl::TearDown();
712 }
Josh Wu049e2cd2022-01-12 05:42:58 -0800713};
714
715/**
716 * Test whether we can open a provider of type
717 */
Alice Kuoadcceec2022-03-28 13:28:43 +0800718TEST_P(BluetoothAudioProviderA2dpEncodingSoftwareAidl,
719 OpenA2dpEncodingSoftwareProvider) {}
720
721/**
722 * Test whether each provider of type
723 * SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH can be started and stopped with
724 * different PCM config
725 */
726TEST_P(BluetoothAudioProviderA2dpEncodingSoftwareAidl,
727 StartAndEndA2dpEncodingSoftwareSessionWithPossiblePcmConfig) {
728 for (auto sample_rate : a2dp_sample_rates) {
729 for (auto bits_per_sample : a2dp_bits_per_samples) {
730 for (auto channel_mode : a2dp_channel_modes) {
731 PcmConfiguration pcm_config{
732 .sampleRateHz = sample_rate,
Alice Kuoadcceec2022-03-28 13:28:43 +0800733 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +0000734 .bitsPerSample = bits_per_sample,
Alice Kuoadcceec2022-03-28 13:28:43 +0800735 };
736 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
737 DataMQDesc mq_desc;
738 auto aidl_retval = audio_provider_->startSession(
739 audio_port_, AudioConfiguration(pcm_config), latency_modes,
740 &mq_desc);
741 DataMQ data_mq(mq_desc);
742
743 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
744 if (is_codec_config_valid) {
745 EXPECT_TRUE(data_mq.isValid());
746 }
747 EXPECT_TRUE(audio_provider_->endSession().isOk());
748 }
749 }
750 }
751}
752
753/**
754 * openProvider A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH
755 */
756class BluetoothAudioProviderA2dpEncodingHardwareAidl
757 : public BluetoothAudioProviderFactoryAidl {
758 public:
759 virtual void SetUp() override {
760 BluetoothAudioProviderFactoryAidl::SetUp();
761 GetProviderCapabilitiesHelper(
762 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
763 OpenProviderHelper(SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
764 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
765 audio_provider_ != nullptr);
766 }
767
768 virtual void TearDown() override {
769 audio_port_ = nullptr;
770 audio_provider_ = nullptr;
771 BluetoothAudioProviderFactoryAidl::TearDown();
772 }
773
774 bool IsOffloadSupported() { return (temp_provider_capabilities_.size() > 0); }
775};
776
777/**
778 * Test whether we can open a provider of type
779 */
780TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
781 OpenA2dpEncodingHardwareProvider) {}
Josh Wu049e2cd2022-01-12 05:42:58 -0800782
783/**
784 * Test whether each provider of type
785 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
786 * SBC hardware encoding config
787 */
Alice Kuoadcceec2022-03-28 13:28:43 +0800788TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
789 StartAndEndA2dpSbcEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -0800790 if (!IsOffloadSupported()) {
791 return;
792 }
793
794 CodecConfiguration codec_config = {
795 .codecType = CodecType::SBC,
796 .encodedAudioBitrate = 328000,
797 .peerMtu = 1005,
798 .isScmstEnabled = false,
799 };
800 auto sbc_codec_specifics = GetSbcCodecSpecificSupportedList(true);
801
802 for (auto& codec_specific : sbc_codec_specifics) {
803 copy_codec_specific(codec_config.config, codec_specific);
804 DataMQDesc mq_desc;
805 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -0800806 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -0800807
808 ASSERT_TRUE(aidl_retval.isOk());
809 EXPECT_TRUE(audio_provider_->endSession().isOk());
810 }
811}
812
813/**
814 * Test whether each provider of type
815 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
816 * AAC hardware encoding config
817 */
Alice Kuoadcceec2022-03-28 13:28:43 +0800818TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
819 StartAndEndA2dpAacEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -0800820 if (!IsOffloadSupported()) {
821 return;
822 }
823
824 CodecConfiguration codec_config = {
825 .codecType = CodecType::AAC,
826 .encodedAudioBitrate = 320000,
827 .peerMtu = 1005,
828 .isScmstEnabled = false,
829 };
830 auto aac_codec_specifics = GetAacCodecSpecificSupportedList(true);
831
832 for (auto& codec_specific : aac_codec_specifics) {
833 copy_codec_specific(codec_config.config, codec_specific);
834 DataMQDesc mq_desc;
835 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -0800836 audio_port_, AudioConfiguration(codec_config), latency_modes, &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 * Test whether each provider of type
845 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
846 * LDAC hardware encoding config
847 */
Alice Kuoadcceec2022-03-28 13:28:43 +0800848TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
849 StartAndEndA2dpLdacEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -0800850 if (!IsOffloadSupported()) {
851 return;
852 }
853
854 CodecConfiguration codec_config = {
855 .codecType = CodecType::LDAC,
856 .encodedAudioBitrate = 990000,
857 .peerMtu = 1005,
858 .isScmstEnabled = false,
859 };
860 auto ldac_codec_specifics = GetLdacCodecSpecificSupportedList(true);
861
862 for (auto& codec_specific : ldac_codec_specifics) {
863 copy_codec_specific(codec_config.config, codec_specific);
864 DataMQDesc mq_desc;
865 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -0800866 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -0800867
868 ASSERT_TRUE(aidl_retval.isOk());
869 EXPECT_TRUE(audio_provider_->endSession().isOk());
870 }
871}
872
873/**
874 * Test whether each provider of type
875 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
Omer Osmana2587da2022-05-01 03:54:11 +0000876 * Opus hardware encoding config
Josh Wu049e2cd2022-01-12 05:42:58 -0800877 */
Alice Kuoadcceec2022-03-28 13:28:43 +0800878TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
Omer Osmana2587da2022-05-01 03:54:11 +0000879 StartAndEndA2dpOpusEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -0800880 if (!IsOffloadSupported()) {
881 return;
882 }
883
884 CodecConfiguration codec_config = {
Omer Osmana2587da2022-05-01 03:54:11 +0000885 .codecType = CodecType::OPUS,
Josh Wu049e2cd2022-01-12 05:42:58 -0800886 .encodedAudioBitrate = 990000,
887 .peerMtu = 1005,
888 .isScmstEnabled = false,
889 };
Omer Osmana2587da2022-05-01 03:54:11 +0000890 auto opus_codec_specifics = GetOpusCodecSpecificSupportedList(true);
Josh Wu049e2cd2022-01-12 05:42:58 -0800891
Omer Osmana2587da2022-05-01 03:54:11 +0000892 for (auto& codec_specific : opus_codec_specifics) {
Josh Wu049e2cd2022-01-12 05:42:58 -0800893 copy_codec_specific(codec_config.config, codec_specific);
894 DataMQDesc mq_desc;
895 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -0800896 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -0800897
898 ASSERT_TRUE(aidl_retval.isOk());
899 EXPECT_TRUE(audio_provider_->endSession().isOk());
900 }
901}
902
903/**
904 * Test whether each provider of type
905 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
906 * AptX hardware encoding config
907 */
Alice Kuoadcceec2022-03-28 13:28:43 +0800908TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
909 StartAndEndA2dpAptxEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -0800910 if (!IsOffloadSupported()) {
911 return;
912 }
913
914 for (auto codec_type : {CodecType::APTX, CodecType::APTX_HD}) {
915 CodecConfiguration codec_config = {
916 .codecType = codec_type,
917 .encodedAudioBitrate =
918 (codec_type == CodecType::APTX ? 352000 : 576000),
919 .peerMtu = 1005,
920 .isScmstEnabled = false,
921 };
922
923 auto aptx_codec_specifics = GetAptxCodecSpecificSupportedList(
924 (codec_type == CodecType::APTX_HD ? true : false), true);
925
926 for (auto& codec_specific : aptx_codec_specifics) {
927 copy_codec_specific(codec_config.config, codec_specific);
928 DataMQDesc mq_desc;
929 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -0800930 audio_port_, AudioConfiguration(codec_config), latency_modes,
931 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -0800932
933 ASSERT_TRUE(aidl_retval.isOk());
934 EXPECT_TRUE(audio_provider_->endSession().isOk());
935 }
936 }
937}
938
939/**
940 * Test whether each provider of type
941 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
942 * an invalid codec config
943 */
Alice Kuoadcceec2022-03-28 13:28:43 +0800944TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
945 StartAndEndA2dpEncodingHardwareSessionInvalidCodecConfig) {
Josh Wu049e2cd2022-01-12 05:42:58 -0800946 if (!IsOffloadSupported()) {
947 return;
948 }
949 ASSERT_NE(audio_provider_, nullptr);
950
951 std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
Sagar Verma62df9102022-12-07 17:56:04 +0530952 for (auto codec_type : ndk::enum_range<CodecType>()) {
Josh Wu049e2cd2022-01-12 05:42:58 -0800953 switch (codec_type) {
954 case CodecType::SBC:
955 codec_specifics = GetSbcCodecSpecificSupportedList(false);
956 break;
957 case CodecType::AAC:
958 codec_specifics = GetAacCodecSpecificSupportedList(false);
959 break;
960 case CodecType::LDAC:
961 codec_specifics = GetLdacCodecSpecificSupportedList(false);
962 break;
963 case CodecType::APTX:
964 codec_specifics = GetAptxCodecSpecificSupportedList(false, false);
965 break;
966 case CodecType::APTX_HD:
967 codec_specifics = GetAptxCodecSpecificSupportedList(true, false);
968 break;
Omer Osmana2587da2022-05-01 03:54:11 +0000969 case CodecType::OPUS:
970 codec_specifics = GetOpusCodecSpecificSupportedList(false);
Josh Wu049e2cd2022-01-12 05:42:58 -0800971 continue;
972 case CodecType::APTX_ADAPTIVE:
Sagar Verma62df9102022-12-07 17:56:04 +0530973 case CodecType::APTX_ADAPTIVE_LE:
974 case CodecType::APTX_ADAPTIVE_LEX:
Omer Osmana2587da2022-05-01 03:54:11 +0000975 case CodecType::LC3:
Josh Wu049e2cd2022-01-12 05:42:58 -0800976 case CodecType::VENDOR:
977 case CodecType::UNKNOWN:
978 codec_specifics.clear();
979 break;
980 }
981 if (codec_specifics.empty()) {
982 continue;
983 }
984
985 CodecConfiguration codec_config = {
986 .codecType = codec_type,
987 .encodedAudioBitrate = 328000,
988 .peerMtu = 1005,
989 .isScmstEnabled = false,
990 };
991 for (auto codec_specific : codec_specifics) {
992 copy_codec_specific(codec_config.config, codec_specific);
993 DataMQDesc mq_desc;
994 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -0800995 audio_port_, AudioConfiguration(codec_config), latency_modes,
996 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -0800997
998 // AIDL call should fail on invalid codec
999 ASSERT_FALSE(aidl_retval.isOk());
1000 EXPECT_TRUE(audio_provider_->endSession().isOk());
1001 }
1002 }
1003}
1004
1005/**
1006 * openProvider HEARING_AID_SOFTWARE_ENCODING_DATAPATH
1007 */
1008class BluetoothAudioProviderHearingAidSoftwareAidl
1009 : public BluetoothAudioProviderFactoryAidl {
1010 public:
1011 virtual void SetUp() override {
1012 BluetoothAudioProviderFactoryAidl::SetUp();
1013 GetProviderCapabilitiesHelper(
1014 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
1015 OpenProviderHelper(SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
1016 ASSERT_NE(audio_provider_, nullptr);
1017 }
1018
1019 virtual void TearDown() override {
1020 audio_port_ = nullptr;
1021 audio_provider_ = nullptr;
1022 BluetoothAudioProviderFactoryAidl::TearDown();
1023 }
1024
1025 static constexpr int32_t hearing_aid_sample_rates_[] = {0, 16000, 24000};
1026 static constexpr int8_t hearing_aid_bits_per_samples_[] = {0, 16, 24};
1027 static constexpr ChannelMode hearing_aid_channel_modes_[] = {
1028 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
1029};
1030
1031/**
1032 * Test whether we can open a provider of type
1033 */
1034TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl,
1035 OpenHearingAidSoftwareProvider) {}
1036
1037/**
1038 * Test whether each provider of type
1039 * SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH can be started and
1040 * stopped with different PCM config
1041 */
1042TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl,
1043 StartAndEndHearingAidSessionWithPossiblePcmConfig) {
1044 for (int32_t sample_rate : hearing_aid_sample_rates_) {
1045 for (int8_t bits_per_sample : hearing_aid_bits_per_samples_) {
1046 for (auto channel_mode : hearing_aid_channel_modes_) {
1047 PcmConfiguration pcm_config{
1048 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08001049 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00001050 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08001051 };
1052 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
1053 DataMQDesc mq_desc;
1054 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001055 audio_port_, AudioConfiguration(pcm_config), latency_modes,
1056 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001057 DataMQ data_mq(mq_desc);
1058
1059 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
1060 if (is_codec_config_valid) {
1061 EXPECT_TRUE(data_mq.isValid());
1062 }
1063 EXPECT_TRUE(audio_provider_->endSession().isOk());
1064 }
1065 }
1066 }
1067}
1068
1069/**
1070 * openProvider LE_AUDIO_SOFTWARE_ENCODING_DATAPATH
1071 */
1072class BluetoothAudioProviderLeAudioOutputSoftwareAidl
1073 : public BluetoothAudioProviderFactoryAidl {
1074 public:
1075 virtual void SetUp() override {
1076 BluetoothAudioProviderFactoryAidl::SetUp();
1077 GetProviderCapabilitiesHelper(
1078 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
1079 OpenProviderHelper(SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
1080 ASSERT_NE(audio_provider_, nullptr);
1081 }
1082
1083 virtual void TearDown() override {
1084 audio_port_ = nullptr;
1085 audio_provider_ = nullptr;
1086 BluetoothAudioProviderFactoryAidl::TearDown();
1087 }
1088
1089 static constexpr int32_t le_audio_output_sample_rates_[] = {
1090 0, 8000, 16000, 24000, 32000, 44100, 48000,
1091 };
1092 static constexpr int8_t le_audio_output_bits_per_samples_[] = {0, 16, 24};
1093 static constexpr ChannelMode le_audio_output_channel_modes_[] = {
1094 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
1095 static constexpr int32_t le_audio_output_data_interval_us_[] = {
1096 0 /* Invalid */, 10000 /* Valid 10ms */};
1097};
1098
1099/**
1100 * Test whether each provider of type
1101 * SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH can be started and
1102 * stopped
1103 */
1104TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl,
1105 OpenLeAudioOutputSoftwareProvider) {}
1106
1107/**
1108 * Test whether each provider of type
1109 * SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH can be started and
1110 * stopped with different PCM config
1111 */
1112TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl,
1113 StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
1114 for (auto sample_rate : le_audio_output_sample_rates_) {
1115 for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
1116 for (auto channel_mode : le_audio_output_channel_modes_) {
1117 for (auto data_interval_us : le_audio_output_data_interval_us_) {
1118 PcmConfiguration pcm_config{
1119 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08001120 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00001121 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08001122 .dataIntervalUs = data_interval_us,
1123 };
Josh Wu8a1be762022-02-15 09:37:29 -08001124 bool is_codec_config_valid =
1125 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
Josh Wu049e2cd2022-01-12 05:42:58 -08001126 DataMQDesc mq_desc;
1127 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001128 audio_port_, AudioConfiguration(pcm_config), latency_modes,
1129 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001130 DataMQ data_mq(mq_desc);
1131
1132 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
1133 if (is_codec_config_valid) {
1134 EXPECT_TRUE(data_mq.isValid());
1135 }
1136 EXPECT_TRUE(audio_provider_->endSession().isOk());
1137 }
1138 }
1139 }
1140 }
1141}
1142
1143/**
Alice Kuo04a399a2022-02-16 09:19:56 +08001144 * openProvider LE_AUDIO_SOFTWARE_DECODING_DATAPATH
Josh Wu049e2cd2022-01-12 05:42:58 -08001145 */
1146class BluetoothAudioProviderLeAudioInputSoftwareAidl
1147 : public BluetoothAudioProviderFactoryAidl {
1148 public:
1149 virtual void SetUp() override {
1150 BluetoothAudioProviderFactoryAidl::SetUp();
1151 GetProviderCapabilitiesHelper(
1152 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH);
1153 OpenProviderHelper(SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH);
1154 ASSERT_NE(audio_provider_, nullptr);
1155 }
1156
1157 virtual void TearDown() override {
1158 audio_port_ = nullptr;
1159 audio_provider_ = nullptr;
1160 BluetoothAudioProviderFactoryAidl::TearDown();
1161 }
1162
1163 static constexpr int32_t le_audio_input_sample_rates_[] = {
1164 0, 8000, 16000, 24000, 32000, 44100, 48000};
1165 static constexpr int8_t le_audio_input_bits_per_samples_[] = {0, 16, 24};
1166 static constexpr ChannelMode le_audio_input_channel_modes_[] = {
1167 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
1168 static constexpr int32_t le_audio_input_data_interval_us_[] = {
1169 0 /* Invalid */, 10000 /* Valid 10ms */};
1170};
1171
1172/**
1173 * Test whether each provider of type
Alice Kuo04a399a2022-02-16 09:19:56 +08001174 * SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08001175 * stopped
1176 */
1177TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl,
1178 OpenLeAudioInputSoftwareProvider) {}
1179
1180/**
1181 * Test whether each provider of type
Alice Kuo04a399a2022-02-16 09:19:56 +08001182 * SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08001183 * stopped with different PCM config
1184 */
1185TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl,
1186 StartAndEndLeAudioInputSessionWithPossiblePcmConfig) {
1187 for (auto sample_rate : le_audio_input_sample_rates_) {
1188 for (auto bits_per_sample : le_audio_input_bits_per_samples_) {
1189 for (auto channel_mode : le_audio_input_channel_modes_) {
1190 for (auto data_interval_us : le_audio_input_data_interval_us_) {
1191 PcmConfiguration pcm_config{
1192 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08001193 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00001194 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08001195 .dataIntervalUs = data_interval_us,
1196 };
Josh Wu8a1be762022-02-15 09:37:29 -08001197 bool is_codec_config_valid =
1198 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
Josh Wu049e2cd2022-01-12 05:42:58 -08001199 DataMQDesc mq_desc;
1200 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001201 audio_port_, AudioConfiguration(pcm_config), latency_modes,
1202 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001203 DataMQ data_mq(mq_desc);
1204
1205 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
1206 if (is_codec_config_valid) {
1207 EXPECT_TRUE(data_mq.isValid());
1208 }
1209 EXPECT_TRUE(audio_provider_->endSession().isOk());
1210 }
1211 }
1212 }
1213 }
1214}
1215
1216/**
Alice Kuo04a399a2022-02-16 09:19:56 +08001217 * openProvider LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH
Josh Wu049e2cd2022-01-12 05:42:58 -08001218 */
1219class BluetoothAudioProviderLeAudioOutputHardwareAidl
1220 : public BluetoothAudioProviderFactoryAidl {
1221 public:
1222 virtual void SetUp() override {
1223 BluetoothAudioProviderFactoryAidl::SetUp();
1224 GetProviderCapabilitiesHelper(
1225 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
1226 OpenProviderHelper(
1227 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
1228 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
1229 audio_provider_ != nullptr);
1230 }
1231
1232 virtual void TearDown() override {
1233 audio_port_ = nullptr;
1234 audio_provider_ = nullptr;
1235 BluetoothAudioProviderFactoryAidl::TearDown();
1236 }
1237
1238 bool IsOffloadOutputSupported() {
1239 for (auto& capability : temp_provider_capabilities_) {
1240 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
1241 continue;
1242 }
1243 auto& le_audio_capability =
1244 capability.get<AudioCapabilities::leAudioCapabilities>();
1245 if (le_audio_capability.unicastEncodeCapability.codecType !=
1246 CodecType::UNKNOWN)
1247 return true;
1248 }
1249 return false;
1250 }
1251
1252 std::vector<Lc3Configuration> GetUnicastLc3SupportedList(bool decoding,
1253 bool supported) {
1254 std::vector<Lc3Configuration> le_audio_codec_configs;
1255 if (!supported) {
shihchienc3ab9f5e2022-09-23 08:18:05 +00001256 Lc3Configuration lc3_config{.pcmBitDepth = 0, .samplingFrequencyHz = 0};
Josh Wu049e2cd2022-01-12 05:42:58 -08001257 le_audio_codec_configs.push_back(lc3_config);
1258 return le_audio_codec_configs;
1259 }
1260
1261 // There might be more than one LeAudioCodecCapabilitiesSetting
1262 std::vector<Lc3Capabilities> lc3_capabilities;
1263 for (auto& capability : temp_provider_capabilities_) {
1264 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
1265 continue;
1266 }
1267 auto& le_audio_capability =
1268 capability.get<AudioCapabilities::leAudioCapabilities>();
1269 auto& unicast_capability =
1270 decoding ? le_audio_capability.unicastDecodeCapability
1271 : le_audio_capability.unicastEncodeCapability;
1272 if (unicast_capability.codecType != CodecType::LC3) {
1273 continue;
1274 }
1275 auto& lc3_capability = unicast_capability.leAudioCodecCapabilities.get<
1276 UnicastCapability::LeAudioCodecCapabilities::lc3Capabilities>();
1277 lc3_capabilities.push_back(lc3_capability);
1278 }
1279
1280 // Combine those parameters into one list of LeAudioCodecConfiguration
1281 // This seems horrible, but usually each Lc3Capability only contains a
1282 // single Lc3Configuration, which means every array has a length of 1.
1283 for (auto& lc3_capability : lc3_capabilities) {
1284 for (int32_t samplingFrequencyHz : lc3_capability.samplingFrequencyHz) {
1285 for (int32_t frameDurationUs : lc3_capability.frameDurationUs) {
1286 for (int32_t octetsPerFrame : lc3_capability.octetsPerFrame) {
1287 Lc3Configuration lc3_config = {
1288 .samplingFrequencyHz = samplingFrequencyHz,
1289 .frameDurationUs = frameDurationUs,
1290 .octetsPerFrame = octetsPerFrame,
1291 };
1292 le_audio_codec_configs.push_back(lc3_config);
1293 }
1294 }
1295 }
1296 }
1297
1298 return le_audio_codec_configs;
1299 }
1300
Sagar Verma62df9102022-12-07 17:56:04 +05301301 static constexpr int32_t apx_adaptive_le_config_codec_modes[] = {0, 1, 2, 3};
1302
1303 std::vector<AptxAdaptiveLeConfiguration>
1304 GetUnicastAptxAdaptiveLeSupportedList(bool decoding, bool supported,
1305 bool is_le_extended) {
1306 std::vector<AptxAdaptiveLeConfiguration> le_audio_codec_configs;
1307 if (!supported) {
1308 AptxAdaptiveLeConfiguration aptx_adaptive_le_config{
1309 .pcmBitDepth = 0, .samplingFrequencyHz = 0};
1310 le_audio_codec_configs.push_back(aptx_adaptive_le_config);
1311 return le_audio_codec_configs;
1312 }
1313
1314 // There might be more than one LeAudioCodecCapabilitiesSetting
1315 std::vector<AptxAdaptiveLeCapabilities> aptx_adaptive_le_capabilities;
1316 for (auto& capability : temp_provider_capabilities_) {
1317 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
1318 continue;
1319 }
1320 auto& le_audio_capability =
1321 capability.get<AudioCapabilities::leAudioCapabilities>();
1322 auto& unicast_capability =
1323 decoding ? le_audio_capability.unicastDecodeCapability
1324 : le_audio_capability.unicastEncodeCapability;
1325 if ((!is_le_extended &&
1326 unicast_capability.codecType != CodecType::APTX_ADAPTIVE_LE) ||
1327 (is_le_extended &&
1328 unicast_capability.codecType != CodecType::APTX_ADAPTIVE_LEX)) {
1329 continue;
1330 }
1331
1332 auto& aptx_adaptive_le_capability =
1333 unicast_capability.leAudioCodecCapabilities
1334 .get<UnicastCapability::LeAudioCodecCapabilities::
1335 aptxAdaptiveLeCapabilities>();
1336
1337 aptx_adaptive_le_capabilities.push_back(aptx_adaptive_le_capability);
1338 }
1339
1340 for (auto& aptx_adaptive_le_capability : aptx_adaptive_le_capabilities) {
1341 for (int32_t samplingFrequencyHz :
1342 aptx_adaptive_le_capability.samplingFrequencyHz) {
1343 for (int32_t frameDurationUs :
1344 aptx_adaptive_le_capability.frameDurationUs) {
1345 for (int32_t octetsPerFrame :
1346 aptx_adaptive_le_capability.octetsPerFrame) {
1347 for (int8_t blocksPerSdu :
1348 aptx_adaptive_le_capability.blocksPerSdu) {
1349 for (int32_t codecMode : apx_adaptive_le_config_codec_modes) {
1350 AptxAdaptiveLeConfiguration aptx_adaptive_le_config = {
1351 .samplingFrequencyHz = samplingFrequencyHz,
1352 .frameDurationUs = frameDurationUs,
1353 .octetsPerFrame = octetsPerFrame,
1354 .blocksPerSdu = blocksPerSdu,
1355 .codecMode = codecMode,
1356 };
1357 le_audio_codec_configs.push_back(aptx_adaptive_le_config);
1358 }
1359 }
1360 }
1361 }
1362 }
1363 }
1364
1365 return le_audio_codec_configs;
1366 }
1367
Josh Wu049e2cd2022-01-12 05:42:58 -08001368 LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
1369};
1370
1371/**
1372 * Test whether each provider of type
1373 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
1374 * stopped
1375 */
1376TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
1377 OpenLeAudioOutputHardwareProvider) {}
1378
1379/**
1380 * Test whether each provider of type
1381 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
1382 * stopped with Unicast hardware encoding config
1383 */
1384TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
1385 StartAndEndLeAudioOutputSessionWithPossibleUnicastConfig) {
1386 if (!IsOffloadOutputSupported()) {
1387 return;
1388 }
1389
1390 auto lc3_codec_configs =
1391 GetUnicastLc3SupportedList(false /* decoding */, true /* supported */);
1392 LeAudioConfiguration le_audio_config = {
1393 .codecType = CodecType::LC3,
1394 .peerDelayUs = 0,
1395 };
1396
1397 for (auto& lc3_config : lc3_codec_configs) {
1398 le_audio_config.leAudioCodecConfig
1399 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
1400 DataMQDesc mq_desc;
1401 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001402 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
1403 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001404
1405 ASSERT_TRUE(aidl_retval.isOk());
1406 EXPECT_TRUE(audio_provider_->endSession().isOk());
1407 }
1408}
1409
1410/**
1411 * Test whether each provider of type
1412 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
1413 * stopped with Unicast hardware encoding config
1414 *
1415 * Disabled since offload codec checking is not ready
1416 */
1417TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
1418 DISABLED_StartAndEndLeAudioOutputSessionWithInvalidAudioConfiguration) {
1419 if (!IsOffloadOutputSupported()) {
1420 return;
1421 }
1422
1423 auto lc3_codec_configs =
1424 GetUnicastLc3SupportedList(false /* decoding */, false /* supported */);
1425 LeAudioConfiguration le_audio_config = {
1426 .codecType = CodecType::LC3,
1427 .peerDelayUs = 0,
1428 };
1429
1430 for (auto& lc3_config : lc3_codec_configs) {
1431 le_audio_config.leAudioCodecConfig
1432 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
1433 DataMQDesc mq_desc;
1434 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001435 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
1436 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001437
1438 // AIDL call should fail on invalid codec
1439 ASSERT_FALSE(aidl_retval.isOk());
1440 EXPECT_TRUE(audio_provider_->endSession().isOk());
1441 }
1442}
1443
Sagar Verma62df9102022-12-07 17:56:04 +05301444static std::vector<uint8_t> vendorMetadata = {0x0B, // Length
1445 0xFF, // Type: Vendor-specific
1446 0x0A, 0x00, // Company_ID
1447 0x01, 0x02, 0x03, 0x04, // Data
1448 0x05, 0x06, 0x07, 0x08};
1449
1450/**
1451 * Test whether each provider of type
1452 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
1453 * stopped with Unicast hardware encoding config
1454 */
1455TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
1456 StartAndEndLeAudioOutputSessionWithAptxAdaptiveLeUnicastConfig) {
1457 if (!IsOffloadOutputSupported()) {
1458 return;
1459 }
1460 for (auto codec_type :
1461 {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
1462 bool is_le_extended = (codec_type == CodecType::APTX_ADAPTIVE_LEX);
1463 auto aptx_adaptive_le_codec_configs =
1464 GetUnicastAptxAdaptiveLeSupportedList(false, true, is_le_extended);
1465 LeAudioConfiguration le_audio_config = {
1466 .codecType = codec_type,
1467 .peerDelayUs = 0,
1468 .vendorSpecificMetadata = vendorMetadata,
1469 };
1470
1471 for (auto& aptx_adaptive_le_config : aptx_adaptive_le_codec_configs) {
1472 le_audio_config.leAudioCodecConfig
1473 .set<LeAudioCodecConfiguration::aptxAdaptiveLeConfig>(
1474 aptx_adaptive_le_config);
1475 DataMQDesc mq_desc;
1476 auto aidl_retval = audio_provider_->startSession(
1477 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
1478 &mq_desc);
1479
1480 ASSERT_TRUE(aidl_retval.isOk());
1481 EXPECT_TRUE(audio_provider_->endSession().isOk());
1482 }
1483 }
1484}
1485
1486/**
1487 * Test whether each provider of type
1488 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
1489 * stopped with Unicast hardware encoding config
1490 */
1491TEST_P(
1492 BluetoothAudioProviderLeAudioOutputHardwareAidl,
1493 BluetoothAudioProviderLeAudioOutputHardwareAidl_StartAndEndLeAudioOutputSessionWithInvalidAptxAdaptiveLeAudioConfiguration) {
1494 if (!IsOffloadOutputSupported()) {
1495 return;
1496 }
1497
1498 for (auto codec_type :
1499 {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
1500 bool is_le_extended = (codec_type == CodecType::APTX_ADAPTIVE_LEX);
1501 auto aptx_adaptive_le_codec_configs =
1502 GetUnicastAptxAdaptiveLeSupportedList(false, true, is_le_extended);
1503 LeAudioConfiguration le_audio_config = {
1504 .codecType = codec_type,
1505 .peerDelayUs = 0,
1506 .vendorSpecificMetadata = vendorMetadata,
1507 };
1508
1509 for (auto& aptx_adaptive_le_config : aptx_adaptive_le_codec_configs) {
1510 le_audio_config.leAudioCodecConfig
1511 .set<LeAudioCodecConfiguration::aptxAdaptiveLeConfig>(
1512 aptx_adaptive_le_config);
1513 DataMQDesc mq_desc;
1514 auto aidl_retval = audio_provider_->startSession(
1515 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
1516 &mq_desc);
1517
1518 // AIDL call should fail on invalid codec
1519 ASSERT_FALSE(aidl_retval.isOk());
1520 EXPECT_TRUE(audio_provider_->endSession().isOk());
1521 }
1522 }
1523}
1524
Josh Wu049e2cd2022-01-12 05:42:58 -08001525/**
1526 * openProvider LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH
1527 */
1528class BluetoothAudioProviderLeAudioInputHardwareAidl
1529 : public BluetoothAudioProviderLeAudioOutputHardwareAidl {
1530 public:
1531 virtual void SetUp() override {
1532 BluetoothAudioProviderFactoryAidl::SetUp();
1533 GetProviderCapabilitiesHelper(
1534 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
1535 OpenProviderHelper(
1536 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
1537 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
1538 audio_provider_ != nullptr);
1539 }
1540
1541 bool IsOffloadInputSupported() {
1542 for (auto& capability : temp_provider_capabilities_) {
1543 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
1544 continue;
1545 }
1546 auto& le_audio_capability =
1547 capability.get<AudioCapabilities::leAudioCapabilities>();
1548 if (le_audio_capability.unicastDecodeCapability.codecType !=
1549 CodecType::UNKNOWN)
1550 return true;
1551 }
1552 return false;
1553 }
1554
1555 virtual void TearDown() override {
1556 audio_port_ = nullptr;
1557 audio_provider_ = nullptr;
1558 BluetoothAudioProviderFactoryAidl::TearDown();
1559 }
1560};
1561
1562/**
1563 * Test whether each provider of type
1564 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
1565 * stopped
1566 */
1567TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
1568 OpenLeAudioInputHardwareProvider) {}
1569
1570/**
1571 * Test whether each provider of type
1572 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
1573 * stopped with Unicast hardware encoding config
1574 */
1575TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
1576 StartAndEndLeAudioInputSessionWithPossibleUnicastConfig) {
1577 if (!IsOffloadInputSupported()) {
1578 return;
1579 }
1580
1581 auto lc3_codec_configs =
1582 GetUnicastLc3SupportedList(true /* decoding */, true /* supported */);
1583 LeAudioConfiguration le_audio_config = {
1584 .codecType = CodecType::LC3,
1585 .peerDelayUs = 0,
1586 };
1587
1588 for (auto& lc3_config : lc3_codec_configs) {
1589 le_audio_config.leAudioCodecConfig
1590 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
1591 DataMQDesc mq_desc;
1592 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001593 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
1594 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001595
1596 ASSERT_TRUE(aidl_retval.isOk());
1597 EXPECT_TRUE(audio_provider_->endSession().isOk());
1598 }
1599}
1600
1601/**
1602 * Test whether each provider of type
1603 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
1604 * stopped with Unicast hardware encoding config
1605 *
1606 * Disabled since offload codec checking is not ready
1607 */
1608TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
1609 DISABLED_StartAndEndLeAudioInputSessionWithInvalidAudioConfiguration) {
1610 if (!IsOffloadInputSupported()) {
1611 return;
1612 }
1613
1614 auto lc3_codec_configs =
1615 GetUnicastLc3SupportedList(true /* decoding */, false /* supported */);
1616 LeAudioConfiguration le_audio_config = {
1617 .codecType = CodecType::LC3,
1618 .peerDelayUs = 0,
1619 };
1620
1621 for (auto& lc3_config : lc3_codec_configs) {
1622 le_audio_config.leAudioCodecConfig
1623 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
1624
1625 DataMQDesc mq_desc;
1626 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001627 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
1628 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001629
1630 // AIDL call should fail on invalid codec
1631 ASSERT_FALSE(aidl_retval.isOk());
1632 EXPECT_TRUE(audio_provider_->endSession().isOk());
1633 }
1634}
1635
1636/**
1637 * openProvider LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH
1638 */
1639class BluetoothAudioProviderLeAudioBroadcastSoftwareAidl
1640 : public BluetoothAudioProviderFactoryAidl {
1641 public:
1642 virtual void SetUp() override {
1643 BluetoothAudioProviderFactoryAidl::SetUp();
1644 GetProviderCapabilitiesHelper(
1645 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
1646 OpenProviderHelper(
1647 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
1648 ASSERT_NE(audio_provider_, nullptr);
1649 }
1650
1651 virtual void TearDown() override {
1652 audio_port_ = nullptr;
1653 audio_provider_ = nullptr;
1654 BluetoothAudioProviderFactoryAidl::TearDown();
1655 }
1656
1657 static constexpr int32_t le_audio_output_sample_rates_[] = {
1658 0, 8000, 16000, 24000, 32000, 44100, 48000,
1659 };
1660 static constexpr int8_t le_audio_output_bits_per_samples_[] = {0, 16, 24};
1661 static constexpr ChannelMode le_audio_output_channel_modes_[] = {
1662 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
1663 static constexpr int32_t le_audio_output_data_interval_us_[] = {
1664 0 /* Invalid */, 10000 /* Valid 10ms */};
1665};
1666
1667/**
1668 * Test whether each provider of type
1669 * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started and
1670 * stopped
1671 */
1672TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
Josh Wu3202eab2022-02-17 18:09:05 -08001673 OpenLeAudioOutputSoftwareProvider) {}
Josh Wu049e2cd2022-01-12 05:42:58 -08001674
1675/**
1676 * Test whether each provider of type
1677 * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started and
1678 * stopped with different PCM config
1679 */
1680TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
Josh Wu3202eab2022-02-17 18:09:05 -08001681 StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001682 for (auto sample_rate : le_audio_output_sample_rates_) {
1683 for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
1684 for (auto channel_mode : le_audio_output_channel_modes_) {
1685 for (auto data_interval_us : le_audio_output_data_interval_us_) {
1686 PcmConfiguration pcm_config{
1687 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08001688 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00001689 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08001690 .dataIntervalUs = data_interval_us,
1691 };
Josh Wu8a1be762022-02-15 09:37:29 -08001692 bool is_codec_config_valid =
1693 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
Josh Wu049e2cd2022-01-12 05:42:58 -08001694 DataMQDesc mq_desc;
1695 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001696 audio_port_, AudioConfiguration(pcm_config), latency_modes,
1697 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001698 DataMQ data_mq(mq_desc);
1699
1700 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
1701 if (is_codec_config_valid) {
1702 EXPECT_TRUE(data_mq.isValid());
1703 }
1704 EXPECT_TRUE(audio_provider_->endSession().isOk());
1705 }
1706 }
1707 }
1708 }
1709}
1710
Alice Kuo336d90c2022-02-16 09:09:59 +08001711/**
1712 * openProvider LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH
1713 */
1714class BluetoothAudioProviderLeAudioBroadcastHardwareAidl
1715 : public BluetoothAudioProviderFactoryAidl {
1716 public:
1717 virtual void SetUp() override {
1718 BluetoothAudioProviderFactoryAidl::SetUp();
1719 GetProviderCapabilitiesHelper(
1720 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
1721 OpenProviderHelper(
1722 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
1723 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
1724 audio_provider_ != nullptr);
1725 }
1726
1727 virtual void TearDown() override {
1728 audio_port_ = nullptr;
1729 audio_provider_ = nullptr;
1730 BluetoothAudioProviderFactoryAidl::TearDown();
1731 }
1732
1733 bool IsBroadcastOffloadSupported() {
1734 for (auto& capability : temp_provider_capabilities_) {
1735 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
1736 continue;
1737 }
1738 auto& le_audio_capability =
1739 capability.get<AudioCapabilities::leAudioCapabilities>();
1740 if (le_audio_capability.broadcastCapability.codecType !=
1741 CodecType::UNKNOWN)
1742 return true;
1743 }
1744 return false;
1745 }
1746
1747 std::vector<Lc3Configuration> GetBroadcastLc3SupportedList(bool supported) {
1748 std::vector<Lc3Configuration> le_audio_codec_configs;
1749 if (!supported) {
shihchienc3ab9f5e2022-09-23 08:18:05 +00001750 Lc3Configuration lc3_config{.pcmBitDepth = 0, .samplingFrequencyHz = 0};
Alice Kuo336d90c2022-02-16 09:09:59 +08001751 le_audio_codec_configs.push_back(lc3_config);
1752 return le_audio_codec_configs;
1753 }
1754
1755 // There might be more than one LeAudioCodecCapabilitiesSetting
1756 std::vector<Lc3Capabilities> lc3_capabilities;
1757 for (auto& capability : temp_provider_capabilities_) {
1758 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
1759 continue;
1760 }
1761 auto& le_audio_capability =
1762 capability.get<AudioCapabilities::leAudioCapabilities>();
1763 auto& broadcast_capability = le_audio_capability.broadcastCapability;
1764 if (broadcast_capability.codecType != CodecType::LC3) {
1765 continue;
1766 }
1767 auto& lc3_capability = broadcast_capability.leAudioCodecCapabilities.get<
1768 BroadcastCapability::LeAudioCodecCapabilities::lc3Capabilities>();
1769 for (int idx = 0; idx < lc3_capability->size(); idx++)
1770 lc3_capabilities.push_back(*lc3_capability->at(idx));
1771 }
1772
1773 // Combine those parameters into one list of LeAudioCodecConfiguration
1774 // This seems horrible, but usually each Lc3Capability only contains a
1775 // single Lc3Configuration, which means every array has a length of 1.
1776 for (auto& lc3_capability : lc3_capabilities) {
1777 for (int32_t samplingFrequencyHz : lc3_capability.samplingFrequencyHz) {
1778 for (int32_t frameDurationUs : lc3_capability.frameDurationUs) {
1779 for (int32_t octetsPerFrame : lc3_capability.octetsPerFrame) {
1780 Lc3Configuration lc3_config = {
1781 .samplingFrequencyHz = samplingFrequencyHz,
1782 .frameDurationUs = frameDurationUs,
1783 .octetsPerFrame = octetsPerFrame,
1784 };
1785 le_audio_codec_configs.push_back(lc3_config);
1786 }
1787 }
1788 }
1789 }
1790
1791 return le_audio_codec_configs;
1792 }
1793
1794 LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
1795};
1796
1797/**
1798 * Test whether each provider of type
1799 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
1800 * started and stopped
1801 */
1802TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
1803 OpenLeAudioOutputHardwareProvider) {}
1804
1805/**
1806 * Test whether each provider of type
1807 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
1808 * started and stopped with broadcast hardware encoding config
1809 */
1810TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
1811 StartAndEndLeAudioBroadcastSessionWithPossibleBroadcastConfig) {
1812 if (!IsBroadcastOffloadSupported()) {
1813 return;
1814 }
1815
1816 auto lc3_codec_configs = GetBroadcastLc3SupportedList(true /* supported */);
1817 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
1818 .codecType = CodecType::LC3,
1819 .streamMap = {},
1820 };
1821
1822 for (auto& lc3_config : lc3_codec_configs) {
Patty Huangac077ef2022-11-23 14:45:15 +08001823 le_audio_broadcast_config.streamMap.resize(1);
Alice Kuo336d90c2022-02-16 09:09:59 +08001824 le_audio_broadcast_config.streamMap[0]
1825 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
1826 lc3_config);
Rongxuan Liuc1aea322023-01-26 17:14:54 +00001827 le_audio_broadcast_config.streamMap[0].streamHandle = 0x0;
1828 le_audio_broadcast_config.streamMap[0].pcmStreamId = 0x0;
1829 le_audio_broadcast_config.streamMap[0].audioChannelAllocation = 0x1 << 0;
1830
Alice Kuo336d90c2022-02-16 09:09:59 +08001831 DataMQDesc mq_desc;
1832 auto aidl_retval = audio_provider_->startSession(
Chen Chen60d52e42022-02-16 12:19:12 -08001833 audio_port_, AudioConfiguration(le_audio_broadcast_config),
1834 latency_modes, &mq_desc);
Alice Kuo336d90c2022-02-16 09:09:59 +08001835
1836 ASSERT_TRUE(aidl_retval.isOk());
1837 EXPECT_TRUE(audio_provider_->endSession().isOk());
1838 }
1839}
1840
1841/**
1842 * Test whether each provider of type
1843 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
1844 * started and stopped with Broadcast hardware encoding config
1845 *
1846 * Disabled since offload codec checking is not ready
1847 */
1848TEST_P(
1849 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
1850 DISABLED_StartAndEndLeAudioBroadcastSessionWithInvalidAudioConfiguration) {
1851 if (!IsBroadcastOffloadSupported()) {
1852 return;
1853 }
1854
1855 auto lc3_codec_configs = GetBroadcastLc3SupportedList(false /* supported */);
1856 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
1857 .codecType = CodecType::LC3,
1858 .streamMap = {},
1859 };
1860
1861 for (auto& lc3_config : lc3_codec_configs) {
1862 le_audio_broadcast_config.streamMap[0]
1863 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
1864 lc3_config);
1865 DataMQDesc mq_desc;
1866 auto aidl_retval = audio_provider_->startSession(
Chen Chen60d52e42022-02-16 12:19:12 -08001867 audio_port_, AudioConfiguration(le_audio_broadcast_config),
1868 latency_modes, &mq_desc);
Alice Kuo336d90c2022-02-16 09:09:59 +08001869
1870 // AIDL call should fail on invalid codec
1871 ASSERT_FALSE(aidl_retval.isOk());
1872 EXPECT_TRUE(audio_provider_->endSession().isOk());
1873 }
1874}
1875
Alice Kuoadcceec2022-03-28 13:28:43 +08001876/**
1877 * openProvider A2DP_SOFTWARE_DECODING_DATAPATH
1878 */
1879class BluetoothAudioProviderA2dpDecodingSoftwareAidl
1880 : public BluetoothAudioProviderFactoryAidl {
1881 public:
1882 virtual void SetUp() override {
1883 BluetoothAudioProviderFactoryAidl::SetUp();
1884 GetProviderCapabilitiesHelper(SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
1885 OpenProviderHelper(SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
1886 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
1887 audio_provider_ != nullptr);
1888 }
1889
1890 virtual void TearDown() override {
1891 audio_port_ = nullptr;
1892 audio_provider_ = nullptr;
1893 BluetoothAudioProviderFactoryAidl::TearDown();
1894 }
1895};
1896
1897/**
1898 * Test whether we can open a provider of type
1899 */
1900TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,
1901 OpenA2dpDecodingSoftwareProvider) {}
1902
1903/**
1904 * Test whether each provider of type
1905 * SessionType::A2DP_SOFTWARE_DECODING_DATAPATH can be started and stopped with
1906 * different PCM config
1907 */
1908TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,
1909 StartAndEndA2dpDecodingSoftwareSessionWithPossiblePcmConfig) {
1910 for (auto sample_rate : a2dp_sample_rates) {
1911 for (auto bits_per_sample : a2dp_bits_per_samples) {
1912 for (auto channel_mode : a2dp_channel_modes) {
1913 PcmConfiguration pcm_config{
1914 .sampleRateHz = sample_rate,
Alice Kuoadcceec2022-03-28 13:28:43 +08001915 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00001916 .bitsPerSample = bits_per_sample,
Alice Kuoadcceec2022-03-28 13:28:43 +08001917 };
1918 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
1919 DataMQDesc mq_desc;
1920 auto aidl_retval = audio_provider_->startSession(
1921 audio_port_, AudioConfiguration(pcm_config), latency_modes,
1922 &mq_desc);
1923 DataMQ data_mq(mq_desc);
1924
1925 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
1926 if (is_codec_config_valid) {
1927 EXPECT_TRUE(data_mq.isValid());
1928 }
1929 EXPECT_TRUE(audio_provider_->endSession().isOk());
1930 }
1931 }
1932 }
1933}
1934
1935/**
1936 * openProvider A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH
1937 */
1938class BluetoothAudioProviderA2dpDecodingHardwareAidl
1939 : public BluetoothAudioProviderFactoryAidl {
1940 public:
1941 virtual void SetUp() override {
1942 BluetoothAudioProviderFactoryAidl::SetUp();
1943 GetProviderCapabilitiesHelper(
1944 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
1945 OpenProviderHelper(SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
1946 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
1947 audio_provider_ != nullptr);
1948 }
1949
1950 virtual void TearDown() override {
1951 audio_port_ = nullptr;
1952 audio_provider_ = nullptr;
1953 BluetoothAudioProviderFactoryAidl::TearDown();
1954 }
1955
1956 bool IsOffloadSupported() { return (temp_provider_capabilities_.size() > 0); }
1957};
1958
1959/**
1960 * Test whether we can open a provider of type
1961 */
1962TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
1963 OpenA2dpDecodingHardwareProvider) {}
1964
1965/**
1966 * Test whether each provider of type
1967 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
1968 * SBC hardware encoding config
1969 */
1970TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
1971 StartAndEndA2dpSbcDecodingHardwareSession) {
1972 if (!IsOffloadSupported()) {
1973 return;
1974 }
1975
1976 CodecConfiguration codec_config = {
1977 .codecType = CodecType::SBC,
1978 .encodedAudioBitrate = 328000,
1979 .peerMtu = 1005,
1980 .isScmstEnabled = false,
1981 };
1982 auto sbc_codec_specifics = GetSbcCodecSpecificSupportedList(true);
1983
1984 for (auto& codec_specific : sbc_codec_specifics) {
1985 copy_codec_specific(codec_config.config, codec_specific);
1986 DataMQDesc mq_desc;
1987 auto aidl_retval = audio_provider_->startSession(
1988 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
1989
1990 ASSERT_TRUE(aidl_retval.isOk());
1991 EXPECT_TRUE(audio_provider_->endSession().isOk());
1992 }
1993}
1994
1995/**
1996 * Test whether each provider of type
1997 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
1998 * AAC hardware encoding config
1999 */
2000TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
2001 StartAndEndA2dpAacDecodingHardwareSession) {
2002 if (!IsOffloadSupported()) {
2003 return;
2004 }
2005
2006 CodecConfiguration codec_config = {
2007 .codecType = CodecType::AAC,
2008 .encodedAudioBitrate = 320000,
2009 .peerMtu = 1005,
2010 .isScmstEnabled = false,
2011 };
2012 auto aac_codec_specifics = GetAacCodecSpecificSupportedList(true);
2013
2014 for (auto& codec_specific : aac_codec_specifics) {
2015 copy_codec_specific(codec_config.config, codec_specific);
2016 DataMQDesc mq_desc;
2017 auto aidl_retval = audio_provider_->startSession(
2018 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
2019
2020 ASSERT_TRUE(aidl_retval.isOk());
2021 EXPECT_TRUE(audio_provider_->endSession().isOk());
2022 }
2023}
2024
2025/**
2026 * Test whether each provider of type
2027 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
2028 * LDAC hardware encoding config
2029 */
2030TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
2031 StartAndEndA2dpLdacDecodingHardwareSession) {
2032 if (!IsOffloadSupported()) {
2033 return;
2034 }
2035
2036 CodecConfiguration codec_config = {
2037 .codecType = CodecType::LDAC,
2038 .encodedAudioBitrate = 990000,
2039 .peerMtu = 1005,
2040 .isScmstEnabled = false,
2041 };
2042 auto ldac_codec_specifics = GetLdacCodecSpecificSupportedList(true);
2043
2044 for (auto& codec_specific : ldac_codec_specifics) {
2045 copy_codec_specific(codec_config.config, codec_specific);
2046 DataMQDesc mq_desc;
2047 auto aidl_retval = audio_provider_->startSession(
2048 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
2049
2050 ASSERT_TRUE(aidl_retval.isOk());
2051 EXPECT_TRUE(audio_provider_->endSession().isOk());
2052 }
2053}
2054
2055/**
2056 * Test whether each provider of type
2057 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
Omer Osmana2587da2022-05-01 03:54:11 +00002058 * Opus hardware encoding config
Alice Kuoadcceec2022-03-28 13:28:43 +08002059 */
2060TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
Omer Osmana2587da2022-05-01 03:54:11 +00002061 StartAndEndA2dpOpusDecodingHardwareSession) {
Alice Kuoadcceec2022-03-28 13:28:43 +08002062 if (!IsOffloadSupported()) {
2063 return;
2064 }
2065
2066 CodecConfiguration codec_config = {
Omer Osmana2587da2022-05-01 03:54:11 +00002067 .codecType = CodecType::OPUS,
Alice Kuoadcceec2022-03-28 13:28:43 +08002068 .encodedAudioBitrate = 990000,
2069 .peerMtu = 1005,
2070 .isScmstEnabled = false,
2071 };
Omer Osmana2587da2022-05-01 03:54:11 +00002072 auto opus_codec_specifics = GetOpusCodecSpecificSupportedList(true);
Alice Kuoadcceec2022-03-28 13:28:43 +08002073
Omer Osmana2587da2022-05-01 03:54:11 +00002074 for (auto& codec_specific : opus_codec_specifics) {
Alice Kuoadcceec2022-03-28 13:28:43 +08002075 copy_codec_specific(codec_config.config, codec_specific);
2076 DataMQDesc mq_desc;
2077 auto aidl_retval = audio_provider_->startSession(
2078 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
2079
2080 ASSERT_TRUE(aidl_retval.isOk());
2081 EXPECT_TRUE(audio_provider_->endSession().isOk());
2082 }
2083}
2084
2085/**
2086 * Test whether each provider of type
2087 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
2088 * AptX hardware encoding config
2089 */
2090TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
2091 StartAndEndA2dpAptxDecodingHardwareSession) {
2092 if (!IsOffloadSupported()) {
2093 return;
2094 }
2095
2096 for (auto codec_type : {CodecType::APTX, CodecType::APTX_HD}) {
2097 CodecConfiguration codec_config = {
2098 .codecType = codec_type,
2099 .encodedAudioBitrate =
2100 (codec_type == CodecType::APTX ? 352000 : 576000),
2101 .peerMtu = 1005,
2102 .isScmstEnabled = false,
2103 };
2104
2105 auto aptx_codec_specifics = GetAptxCodecSpecificSupportedList(
2106 (codec_type == CodecType::APTX_HD ? true : false), true);
2107
2108 for (auto& codec_specific : aptx_codec_specifics) {
2109 copy_codec_specific(codec_config.config, codec_specific);
2110 DataMQDesc mq_desc;
2111 auto aidl_retval = audio_provider_->startSession(
2112 audio_port_, AudioConfiguration(codec_config), latency_modes,
2113 &mq_desc);
2114
2115 ASSERT_TRUE(aidl_retval.isOk());
2116 EXPECT_TRUE(audio_provider_->endSession().isOk());
2117 }
2118 }
2119}
2120
2121/**
2122 * Test whether each provider of type
2123 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
2124 * an invalid codec config
2125 */
2126TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
2127 StartAndEndA2dpDecodingHardwareSessionInvalidCodecConfig) {
2128 if (!IsOffloadSupported()) {
2129 return;
2130 }
2131 ASSERT_NE(audio_provider_, nullptr);
2132
2133 std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
Sagar Verma62df9102022-12-07 17:56:04 +05302134 for (auto codec_type : ndk::enum_range<CodecType>()) {
Alice Kuoadcceec2022-03-28 13:28:43 +08002135 switch (codec_type) {
2136 case CodecType::SBC:
2137 codec_specifics = GetSbcCodecSpecificSupportedList(false);
2138 break;
2139 case CodecType::AAC:
2140 codec_specifics = GetAacCodecSpecificSupportedList(false);
2141 break;
2142 case CodecType::LDAC:
2143 codec_specifics = GetLdacCodecSpecificSupportedList(false);
2144 break;
2145 case CodecType::APTX:
2146 codec_specifics = GetAptxCodecSpecificSupportedList(false, false);
2147 break;
2148 case CodecType::APTX_HD:
2149 codec_specifics = GetAptxCodecSpecificSupportedList(true, false);
2150 break;
Omer Osmana2587da2022-05-01 03:54:11 +00002151 case CodecType::OPUS:
2152 codec_specifics = GetOpusCodecSpecificSupportedList(false);
Alice Kuoadcceec2022-03-28 13:28:43 +08002153 continue;
2154 case CodecType::APTX_ADAPTIVE:
Sagar Verma62df9102022-12-07 17:56:04 +05302155 case CodecType::APTX_ADAPTIVE_LE:
2156 case CodecType::APTX_ADAPTIVE_LEX:
Omer Osmana2587da2022-05-01 03:54:11 +00002157 case CodecType::LC3:
Alice Kuoadcceec2022-03-28 13:28:43 +08002158 case CodecType::VENDOR:
2159 case CodecType::UNKNOWN:
2160 codec_specifics.clear();
2161 break;
2162 }
2163 if (codec_specifics.empty()) {
2164 continue;
2165 }
2166
2167 CodecConfiguration codec_config = {
2168 .codecType = codec_type,
2169 .encodedAudioBitrate = 328000,
2170 .peerMtu = 1005,
2171 .isScmstEnabled = false,
2172 };
2173 for (auto codec_specific : codec_specifics) {
2174 copy_codec_specific(codec_config.config, codec_specific);
2175 DataMQDesc mq_desc;
2176 auto aidl_retval = audio_provider_->startSession(
2177 audio_port_, AudioConfiguration(codec_config), latency_modes,
2178 &mq_desc);
2179
2180 // AIDL call should fail on invalid codec
2181 ASSERT_FALSE(aidl_retval.isOk());
2182 EXPECT_TRUE(audio_provider_->endSession().isOk());
2183 }
2184 }
2185}
2186
Josh Wu049e2cd2022-01-12 05:42:58 -08002187GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
2188 BluetoothAudioProviderFactoryAidl);
2189INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderFactoryAidl,
2190 testing::ValuesIn(android::getAidlHalInstanceNames(
2191 IBluetoothAudioProviderFactory::descriptor)),
2192 android::PrintInstanceNameToString);
2193
2194GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
Alice Kuoadcceec2022-03-28 13:28:43 +08002195 BluetoothAudioProviderA2dpEncodingSoftwareAidl);
2196INSTANTIATE_TEST_SUITE_P(PerInstance,
2197 BluetoothAudioProviderA2dpEncodingSoftwareAidl,
Josh Wu049e2cd2022-01-12 05:42:58 -08002198 testing::ValuesIn(android::getAidlHalInstanceNames(
2199 IBluetoothAudioProviderFactory::descriptor)),
2200 android::PrintInstanceNameToString);
2201
2202GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
Alice Kuoadcceec2022-03-28 13:28:43 +08002203 BluetoothAudioProviderA2dpEncodingHardwareAidl);
2204INSTANTIATE_TEST_SUITE_P(PerInstance,
2205 BluetoothAudioProviderA2dpEncodingHardwareAidl,
Josh Wu049e2cd2022-01-12 05:42:58 -08002206 testing::ValuesIn(android::getAidlHalInstanceNames(
2207 IBluetoothAudioProviderFactory::descriptor)),
2208 android::PrintInstanceNameToString);
2209
2210GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
2211 BluetoothAudioProviderHearingAidSoftwareAidl);
2212INSTANTIATE_TEST_SUITE_P(PerInstance,
2213 BluetoothAudioProviderHearingAidSoftwareAidl,
2214 testing::ValuesIn(android::getAidlHalInstanceNames(
2215 IBluetoothAudioProviderFactory::descriptor)),
2216 android::PrintInstanceNameToString);
2217
2218GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
2219 BluetoothAudioProviderLeAudioOutputSoftwareAidl);
2220INSTANTIATE_TEST_SUITE_P(PerInstance,
2221 BluetoothAudioProviderLeAudioOutputSoftwareAidl,
2222 testing::ValuesIn(android::getAidlHalInstanceNames(
2223 IBluetoothAudioProviderFactory::descriptor)),
2224 android::PrintInstanceNameToString);
2225
2226GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
2227 BluetoothAudioProviderLeAudioInputSoftwareAidl);
2228INSTANTIATE_TEST_SUITE_P(PerInstance,
2229 BluetoothAudioProviderLeAudioInputSoftwareAidl,
2230 testing::ValuesIn(android::getAidlHalInstanceNames(
2231 IBluetoothAudioProviderFactory::descriptor)),
2232 android::PrintInstanceNameToString);
2233
2234GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
2235 BluetoothAudioProviderLeAudioOutputHardwareAidl);
2236INSTANTIATE_TEST_SUITE_P(PerInstance,
2237 BluetoothAudioProviderLeAudioOutputHardwareAidl,
2238 testing::ValuesIn(android::getAidlHalInstanceNames(
2239 IBluetoothAudioProviderFactory::descriptor)),
2240 android::PrintInstanceNameToString);
2241
2242GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
2243 BluetoothAudioProviderLeAudioInputHardwareAidl);
2244INSTANTIATE_TEST_SUITE_P(PerInstance,
2245 BluetoothAudioProviderLeAudioInputHardwareAidl,
2246 testing::ValuesIn(android::getAidlHalInstanceNames(
2247 IBluetoothAudioProviderFactory::descriptor)),
2248 android::PrintInstanceNameToString);
2249
2250GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
2251 BluetoothAudioProviderLeAudioBroadcastSoftwareAidl);
2252INSTANTIATE_TEST_SUITE_P(PerInstance,
2253 BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
2254 testing::ValuesIn(android::getAidlHalInstanceNames(
2255 IBluetoothAudioProviderFactory::descriptor)),
2256 android::PrintInstanceNameToString);
2257
Alice Kuo336d90c2022-02-16 09:09:59 +08002258GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
2259 BluetoothAudioProviderLeAudioBroadcastHardwareAidl);
2260INSTANTIATE_TEST_SUITE_P(PerInstance,
2261 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
2262 testing::ValuesIn(android::getAidlHalInstanceNames(
2263 IBluetoothAudioProviderFactory::descriptor)),
2264 android::PrintInstanceNameToString);
Josh Wu049e2cd2022-01-12 05:42:58 -08002265
Alice Kuoadcceec2022-03-28 13:28:43 +08002266GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
2267 BluetoothAudioProviderA2dpDecodingSoftwareAidl);
2268INSTANTIATE_TEST_SUITE_P(PerInstance,
2269 BluetoothAudioProviderA2dpDecodingSoftwareAidl,
2270 testing::ValuesIn(android::getAidlHalInstanceNames(
2271 IBluetoothAudioProviderFactory::descriptor)),
2272 android::PrintInstanceNameToString);
2273
2274GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
2275 BluetoothAudioProviderA2dpDecodingHardwareAidl);
2276INSTANTIATE_TEST_SUITE_P(PerInstance,
2277 BluetoothAudioProviderA2dpDecodingHardwareAidl,
2278 testing::ValuesIn(android::getAidlHalInstanceNames(
2279 IBluetoothAudioProviderFactory::descriptor)),
2280 android::PrintInstanceNameToString);
2281
Josh Wu049e2cd2022-01-12 05:42:58 -08002282int main(int argc, char** argv) {
2283 ::testing::InitGoogleTest(&argc, argv);
2284 ABinderProcess_setThreadPoolMaxThreadCount(1);
2285 ABinderProcess_startThreadPool();
2286 return RUN_ALL_TESTS();
2287}