blob: 17be7be9d7c04922ff59fb40d80593704d4d955d [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;
Antoine SOULIER33c4e5a2023-09-28 21:59:19 +000036using aidl::android::hardware::bluetooth::audio::A2dpConfiguration;
37using aidl::android::hardware::bluetooth::audio::A2dpConfigurationHint;
38using aidl::android::hardware::bluetooth::audio::A2dpRemoteCapabilities;
39using aidl::android::hardware::bluetooth::audio::A2dpStatus;
40using aidl::android::hardware::bluetooth::audio::A2dpStreamConfiguration;
Josh Wu049e2cd2022-01-12 05:42:58 -080041using aidl::android::hardware::bluetooth::audio::AacCapabilities;
42using aidl::android::hardware::bluetooth::audio::AacConfiguration;
Sagar Verma62df9102022-12-07 17:56:04 +053043using aidl::android::hardware::bluetooth::audio::AptxAdaptiveLeCapabilities;
44using aidl::android::hardware::bluetooth::audio::AptxAdaptiveLeConfiguration;
Josh Wu049e2cd2022-01-12 05:42:58 -080045using aidl::android::hardware::bluetooth::audio::AptxCapabilities;
46using aidl::android::hardware::bluetooth::audio::AptxConfiguration;
47using aidl::android::hardware::bluetooth::audio::AudioCapabilities;
48using aidl::android::hardware::bluetooth::audio::AudioConfiguration;
49using aidl::android::hardware::bluetooth::audio::BnBluetoothAudioPort;
Alice Kuo336d90c2022-02-16 09:09:59 +080050using aidl::android::hardware::bluetooth::audio::BroadcastCapability;
Josh Wu049e2cd2022-01-12 05:42:58 -080051using aidl::android::hardware::bluetooth::audio::ChannelMode;
52using aidl::android::hardware::bluetooth::audio::CodecCapabilities;
53using aidl::android::hardware::bluetooth::audio::CodecConfiguration;
Antoine SOULIER8c90f1f2023-09-26 18:55:17 +000054using aidl::android::hardware::bluetooth::audio::CodecId;
55using aidl::android::hardware::bluetooth::audio::CodecInfo;
Antoine SOULIER33c4e5a2023-09-28 21:59:19 +000056using aidl::android::hardware::bluetooth::audio::CodecParameters;
Josh Wu049e2cd2022-01-12 05:42:58 -080057using aidl::android::hardware::bluetooth::audio::CodecType;
Bao Do72399432023-11-09 08:13:05 +000058using aidl::android::hardware::bluetooth::audio::HfpConfiguration;
Josh Wu049e2cd2022-01-12 05:42:58 -080059using aidl::android::hardware::bluetooth::audio::IBluetoothAudioPort;
60using aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider;
61using aidl::android::hardware::bluetooth::audio::IBluetoothAudioProviderFactory;
62using aidl::android::hardware::bluetooth::audio::LatencyMode;
63using aidl::android::hardware::bluetooth::audio::Lc3Capabilities;
64using aidl::android::hardware::bluetooth::audio::Lc3Configuration;
65using aidl::android::hardware::bluetooth::audio::LdacCapabilities;
66using aidl::android::hardware::bluetooth::audio::LdacConfiguration;
Alice Kuo336d90c2022-02-16 09:09:59 +080067using aidl::android::hardware::bluetooth::audio::LeAudioBroadcastConfiguration;
Josh Wu049e2cd2022-01-12 05:42:58 -080068using aidl::android::hardware::bluetooth::audio::
69 LeAudioCodecCapabilitiesSetting;
70using aidl::android::hardware::bluetooth::audio::LeAudioCodecConfiguration;
71using aidl::android::hardware::bluetooth::audio::LeAudioConfiguration;
Omer Osmana2587da2022-05-01 03:54:11 +000072using aidl::android::hardware::bluetooth::audio::OpusCapabilities;
73using aidl::android::hardware::bluetooth::audio::OpusConfiguration;
Josh Wu049e2cd2022-01-12 05:42:58 -080074using aidl::android::hardware::bluetooth::audio::PcmConfiguration;
75using aidl::android::hardware::bluetooth::audio::PresentationPosition;
76using aidl::android::hardware::bluetooth::audio::SbcAllocMethod;
77using aidl::android::hardware::bluetooth::audio::SbcCapabilities;
78using aidl::android::hardware::bluetooth::audio::SbcChannelMode;
79using aidl::android::hardware::bluetooth::audio::SbcConfiguration;
80using aidl::android::hardware::bluetooth::audio::SessionType;
81using aidl::android::hardware::bluetooth::audio::UnicastCapability;
82using aidl::android::hardware::common::fmq::MQDescriptor;
83using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
84using android::AidlMessageQueue;
85using android::ProcessState;
86using android::String16;
87using ndk::ScopedAStatus;
88using ndk::SpAIBinder;
89
90using MqDataType = int8_t;
91using MqDataMode = SynchronizedReadWrite;
92using DataMQ = AidlMessageQueue<MqDataType, MqDataMode>;
93using DataMQDesc = MQDescriptor<MqDataType, MqDataMode>;
94
95// Constants
96
97static constexpr int32_t a2dp_sample_rates[] = {0, 44100, 48000, 88200, 96000};
98static constexpr int8_t a2dp_bits_per_samples[] = {0, 16, 24, 32};
99static constexpr ChannelMode a2dp_channel_modes[] = {
100 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
Chen Chenc92270e2022-02-14 18:29:52 -0800101static std::vector<LatencyMode> latency_modes = {LatencyMode::FREE};
Bao Do72399432023-11-09 08:13:05 +0000102
103// Some valid configs for HFP PCM configuration (software sessions)
104static constexpr int32_t hfp_sample_rates_[] = {8000, 16000, 32000};
105static constexpr int8_t hfp_bits_per_samples_[] = {16};
106static constexpr ChannelMode hfp_channel_modes_[] = {ChannelMode::MONO};
107static constexpr int32_t hfp_data_interval_us_[] = {7500};
108
Josh Wu049e2cd2022-01-12 05:42:58 -0800109// Helpers
110
111template <typename T>
112struct identity {
113 typedef T type;
114};
115
116template <class T>
117bool contained_in_vector(const std::vector<T>& vector,
118 const typename identity<T>::type& target) {
119 return std::find(vector.begin(), vector.end(), target) != vector.end();
120}
121
122void copy_codec_specific(CodecConfiguration::CodecSpecific& dst,
123 const CodecConfiguration::CodecSpecific& src) {
124 switch (src.getTag()) {
125 case CodecConfiguration::CodecSpecific::sbcConfig:
126 dst.set<CodecConfiguration::CodecSpecific::sbcConfig>(
127 src.get<CodecConfiguration::CodecSpecific::sbcConfig>());
128 break;
129 case CodecConfiguration::CodecSpecific::aacConfig:
130 dst.set<CodecConfiguration::CodecSpecific::aacConfig>(
131 src.get<CodecConfiguration::CodecSpecific::aacConfig>());
132 break;
133 case CodecConfiguration::CodecSpecific::ldacConfig:
134 dst.set<CodecConfiguration::CodecSpecific::ldacConfig>(
135 src.get<CodecConfiguration::CodecSpecific::ldacConfig>());
136 break;
137 case CodecConfiguration::CodecSpecific::aptxConfig:
138 dst.set<CodecConfiguration::CodecSpecific::aptxConfig>(
139 src.get<CodecConfiguration::CodecSpecific::aptxConfig>());
140 break;
Omer Osmana2587da2022-05-01 03:54:11 +0000141 case CodecConfiguration::CodecSpecific::opusConfig:
142 dst.set<CodecConfiguration::CodecSpecific::opusConfig>(
143 src.get<CodecConfiguration::CodecSpecific::opusConfig>());
Josh Wu049e2cd2022-01-12 05:42:58 -0800144 break;
145 case CodecConfiguration::CodecSpecific::aptxAdaptiveConfig:
146 dst.set<CodecConfiguration::CodecSpecific::aptxAdaptiveConfig>(
147 src.get<CodecConfiguration::CodecSpecific::aptxAdaptiveConfig>());
148 break;
149 default:
150 break;
151 }
152}
153
154class BluetoothAudioPort : public BnBluetoothAudioPort {
155 public:
156 BluetoothAudioPort() {}
157
Chen Chen0a68a922022-02-15 18:43:26 -0800158 ndk::ScopedAStatus startStream(bool) { return ScopedAStatus::ok(); }
Josh Wu049e2cd2022-01-12 05:42:58 -0800159
160 ndk::ScopedAStatus suspendStream() { return ScopedAStatus::ok(); }
161
162 ndk::ScopedAStatus stopStream() { return ScopedAStatus::ok(); }
163
164 ndk::ScopedAStatus getPresentationPosition(PresentationPosition*) {
165 return ScopedAStatus::ok();
166 }
167
168 ndk::ScopedAStatus updateSourceMetadata(const SourceMetadata&) {
169 return ScopedAStatus::ok();
170 }
171
172 ndk::ScopedAStatus updateSinkMetadata(const SinkMetadata&) {
173 return ScopedAStatus::ok();
174 }
175
176 ndk::ScopedAStatus setLatencyMode(const LatencyMode) {
177 return ScopedAStatus::ok();
178 }
179
180 ndk::ScopedAStatus setCodecType(const CodecType) {
181 return ScopedAStatus::ok();
182 }
183
184 protected:
185 virtual ~BluetoothAudioPort() = default;
186};
187
188class BluetoothAudioProviderFactoryAidl
189 : public testing::TestWithParam<std::string> {
190 public:
191 virtual void SetUp() override {
192 provider_factory_ = IBluetoothAudioProviderFactory::fromBinder(
193 SpAIBinder(AServiceManager_getService(GetParam().c_str())));
194 audio_provider_ = nullptr;
195 ASSERT_NE(provider_factory_, nullptr);
196 }
197
198 virtual void TearDown() override { provider_factory_ = nullptr; }
199
200 void GetProviderCapabilitiesHelper(const SessionType& session_type) {
201 temp_provider_capabilities_.clear();
202 auto aidl_retval = provider_factory_->getProviderCapabilities(
203 session_type, &temp_provider_capabilities_);
204 // AIDL calls should not be failed and callback has to be executed
205 ASSERT_TRUE(aidl_retval.isOk());
206 switch (session_type) {
207 case SessionType::UNKNOWN: {
208 ASSERT_TRUE(temp_provider_capabilities_.empty());
209 } break;
210 case SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH:
211 case SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH:
212 case SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH:
213 case SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH:
Bao Do72399432023-11-09 08:13:05 +0000214 case SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH:
215 case SessionType::HFP_SOFTWARE_ENCODING_DATAPATH: {
Josh Wu049e2cd2022-01-12 05:42:58 -0800216 // All software paths are mandatory and must have exact 1
217 // "PcmParameters"
218 ASSERT_EQ(temp_provider_capabilities_.size(), 1);
219 ASSERT_EQ(temp_provider_capabilities_[0].getTag(),
220 AudioCapabilities::pcmCapabilities);
221 } break;
Alice Kuoadcceec2022-03-28 13:28:43 +0800222 case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
223 case SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH: {
Josh Wu049e2cd2022-01-12 05:42:58 -0800224 std::unordered_set<CodecType> codec_types;
225 // empty capability means offload is unsupported
226 for (auto& audio_capability : temp_provider_capabilities_) {
227 ASSERT_EQ(audio_capability.getTag(),
228 AudioCapabilities::a2dpCapabilities);
229 const auto& codec_capabilities =
230 audio_capability.get<AudioCapabilities::a2dpCapabilities>();
231 // Every codec can present once at most
232 ASSERT_EQ(codec_types.count(codec_capabilities.codecType), 0);
233 switch (codec_capabilities.codecType) {
234 case CodecType::SBC:
235 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
236 CodecCapabilities::Capabilities::sbcCapabilities);
237 break;
238 case CodecType::AAC:
239 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
240 CodecCapabilities::Capabilities::aacCapabilities);
241 break;
242 case CodecType::APTX:
243 case CodecType::APTX_HD:
244 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
245 CodecCapabilities::Capabilities::aptxCapabilities);
246 break;
247 case CodecType::LDAC:
248 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
249 CodecCapabilities::Capabilities::ldacCapabilities);
250 break;
Omer Osmana2587da2022-05-01 03:54:11 +0000251 case CodecType::OPUS:
Josh Wu049e2cd2022-01-12 05:42:58 -0800252 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
Omer Osmana2587da2022-05-01 03:54:11 +0000253 CodecCapabilities::Capabilities::opusCapabilities);
Josh Wu049e2cd2022-01-12 05:42:58 -0800254 break;
255 case CodecType::APTX_ADAPTIVE:
Sagar Verma62df9102022-12-07 17:56:04 +0530256 case CodecType::APTX_ADAPTIVE_LE:
257 case CodecType::APTX_ADAPTIVE_LEX:
Omer Osmana2587da2022-05-01 03:54:11 +0000258 case CodecType::LC3:
Josh Wu049e2cd2022-01-12 05:42:58 -0800259 case CodecType::VENDOR:
260 case CodecType::UNKNOWN:
261 break;
262 }
263 codec_types.insert(codec_capabilities.codecType);
264 }
265 } break;
266 case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
267 case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
268 case SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH: {
shihchienc3ab9f5e2022-09-23 08:18:05 +0000269 // empty capability means offload is unsupported since capabilities are
270 // not hardcoded
Josh Wu049e2cd2022-01-12 05:42:58 -0800271 for (auto audio_capability : temp_provider_capabilities_) {
272 ASSERT_EQ(audio_capability.getTag(),
273 AudioCapabilities::leAudioCapabilities);
274 }
275 } break;
Bao Do72399432023-11-09 08:13:05 +0000276 case SessionType::A2DP_SOFTWARE_DECODING_DATAPATH:
277 case SessionType::HFP_SOFTWARE_DECODING_DATAPATH: {
Alice Kuoadcceec2022-03-28 13:28:43 +0800278 if (!temp_provider_capabilities_.empty()) {
279 ASSERT_EQ(temp_provider_capabilities_.size(), 1);
280 ASSERT_EQ(temp_provider_capabilities_[0].getTag(),
281 AudioCapabilities::pcmCapabilities);
282 }
283 } break;
284 default: {
285 ASSERT_TRUE(temp_provider_capabilities_.empty());
286 }
Josh Wu049e2cd2022-01-12 05:42:58 -0800287 }
288 }
289
290 /***
291 * This helps to open the specified provider and check the openProvider()
292 * has corruct return values. BUT, to keep it simple, it does not consider
293 * the capability, and please do so at the SetUp of each session's test.
294 ***/
295 void OpenProviderHelper(const SessionType& session_type) {
296 auto aidl_retval =
297 provider_factory_->openProvider(session_type, &audio_provider_);
298 if (aidl_retval.isOk()) {
299 ASSERT_NE(session_type, SessionType::UNKNOWN);
300 ASSERT_NE(audio_provider_, nullptr);
301 audio_port_ = ndk::SharedRefBase::make<BluetoothAudioPort>();
302 } else {
Alice Kuoadcceec2022-03-28 13:28:43 +0800303 // optional session type
Josh Wu049e2cd2022-01-12 05:42:58 -0800304 ASSERT_TRUE(
305 session_type == SessionType::UNKNOWN ||
306 session_type ==
307 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
308 session_type ==
309 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
310 session_type ==
311 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
312 session_type ==
313 SessionType::
Alice Kuoadcceec2022-03-28 13:28:43 +0800314 LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
315 session_type ==
316 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
Bao Do72399432023-11-09 08:13:05 +0000317 session_type == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH ||
318 session_type == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH ||
319 session_type == SessionType::HFP_SOFTWARE_DECODING_DATAPATH ||
320 session_type == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH);
Josh Wu049e2cd2022-01-12 05:42:58 -0800321 ASSERT_EQ(audio_provider_, nullptr);
322 }
323 }
324
Josh Wu049e2cd2022-01-12 05:42:58 -0800325 void GetA2dpOffloadCapabilityHelper(const CodecType& codec_type) {
326 temp_codec_capabilities_ = nullptr;
Josh Wu4d2938f2022-02-15 09:21:10 -0800327 for (auto& codec_capability : temp_provider_capabilities_) {
Josh Wu049e2cd2022-01-12 05:42:58 -0800328 auto& a2dp_capabilities =
329 codec_capability.get<AudioCapabilities::a2dpCapabilities>();
330 if (a2dp_capabilities.codecType != codec_type) {
331 continue;
332 }
333 temp_codec_capabilities_ = &a2dp_capabilities;
334 }
335 }
336
337 std::vector<CodecConfiguration::CodecSpecific>
338 GetSbcCodecSpecificSupportedList(bool supported) {
339 std::vector<CodecConfiguration::CodecSpecific> sbc_codec_specifics;
340 if (!supported) {
341 SbcConfiguration sbc_config{.sampleRateHz = 0, .bitsPerSample = 0};
342 sbc_codec_specifics.push_back(
343 CodecConfiguration::CodecSpecific(sbc_config));
344 return sbc_codec_specifics;
345 }
346 GetA2dpOffloadCapabilityHelper(CodecType::SBC);
347 if (temp_codec_capabilities_ == nullptr ||
348 temp_codec_capabilities_->codecType != CodecType::SBC) {
349 return sbc_codec_specifics;
350 }
351 // parse the capability
352 auto& sbc_capability =
353 temp_codec_capabilities_->capabilities
354 .get<CodecCapabilities::Capabilities::sbcCapabilities>();
355 if (sbc_capability.minBitpool > sbc_capability.maxBitpool) {
356 return sbc_codec_specifics;
357 }
358
359 // combine those parameters into one list of
360 // CodecConfiguration::CodecSpecific
361 for (int32_t sample_rate : sbc_capability.sampleRateHz) {
362 for (int8_t block_length : sbc_capability.blockLength) {
363 for (int8_t num_subbands : sbc_capability.numSubbands) {
364 for (int8_t bits_per_sample : sbc_capability.bitsPerSample) {
365 for (auto channel_mode : sbc_capability.channelMode) {
366 for (auto alloc_method : sbc_capability.allocMethod) {
367 SbcConfiguration sbc_data = {
368 .sampleRateHz = sample_rate,
369 .channelMode = channel_mode,
370 .blockLength = block_length,
371 .numSubbands = num_subbands,
372 .allocMethod = alloc_method,
373 .bitsPerSample = bits_per_sample,
374 .minBitpool = sbc_capability.minBitpool,
375 .maxBitpool = sbc_capability.maxBitpool};
376 sbc_codec_specifics.push_back(
377 CodecConfiguration::CodecSpecific(sbc_data));
378 }
379 }
380 }
381 }
382 }
383 }
384 return sbc_codec_specifics;
385 }
386
387 std::vector<CodecConfiguration::CodecSpecific>
388 GetAacCodecSpecificSupportedList(bool supported) {
389 std::vector<CodecConfiguration::CodecSpecific> aac_codec_specifics;
390 if (!supported) {
391 AacConfiguration aac_config{.sampleRateHz = 0, .bitsPerSample = 0};
392 aac_codec_specifics.push_back(
393 CodecConfiguration::CodecSpecific(aac_config));
394 return aac_codec_specifics;
395 }
396 GetA2dpOffloadCapabilityHelper(CodecType::AAC);
397 if (temp_codec_capabilities_ == nullptr ||
398 temp_codec_capabilities_->codecType != CodecType::AAC) {
399 return aac_codec_specifics;
400 }
401 // parse the capability
402 auto& aac_capability =
403 temp_codec_capabilities_->capabilities
404 .get<CodecCapabilities::Capabilities::aacCapabilities>();
405
406 std::vector<bool> variable_bit_rate_enableds = {false};
407 if (aac_capability.variableBitRateSupported) {
408 variable_bit_rate_enableds.push_back(true);
409 }
410
Sagar Verma62df9102022-12-07 17:56:04 +0530411 std::vector<bool> adaptive_bit_rate_supporteds = {false};
412 if (aac_capability.adaptiveBitRateSupported) {
413 adaptive_bit_rate_supporteds.push_back(true);
414 }
415
Josh Wu049e2cd2022-01-12 05:42:58 -0800416 // combine those parameters into one list of
417 // CodecConfiguration::CodecSpecific
418 for (auto object_type : aac_capability.objectType) {
419 for (int32_t sample_rate : aac_capability.sampleRateHz) {
420 for (auto channel_mode : aac_capability.channelMode) {
421 for (int8_t bits_per_sample : aac_capability.bitsPerSample) {
422 for (auto variable_bit_rate_enabled : variable_bit_rate_enableds) {
Sagar Verma62df9102022-12-07 17:56:04 +0530423 for (auto adaptive_bit_rate_supported :
424 adaptive_bit_rate_supporteds) {
425 AacConfiguration aac_data{
426 .objectType = object_type,
427 .sampleRateHz = sample_rate,
428 .channelMode = channel_mode,
429 .variableBitRateEnabled = variable_bit_rate_enabled,
430 .bitsPerSample = bits_per_sample,
431 .adaptiveBitRateSupported = adaptive_bit_rate_supported};
432 aac_codec_specifics.push_back(
433 CodecConfiguration::CodecSpecific(aac_data));
434 }
Josh Wu049e2cd2022-01-12 05:42:58 -0800435 }
436 }
437 }
438 }
439 }
440 return aac_codec_specifics;
441 }
442
443 std::vector<CodecConfiguration::CodecSpecific>
444 GetLdacCodecSpecificSupportedList(bool supported) {
445 std::vector<CodecConfiguration::CodecSpecific> ldac_codec_specifics;
446 if (!supported) {
447 LdacConfiguration ldac_config{.sampleRateHz = 0, .bitsPerSample = 0};
448 ldac_codec_specifics.push_back(
449 CodecConfiguration::CodecSpecific(ldac_config));
450 return ldac_codec_specifics;
451 }
452 GetA2dpOffloadCapabilityHelper(CodecType::LDAC);
453 if (temp_codec_capabilities_ == nullptr ||
454 temp_codec_capabilities_->codecType != CodecType::LDAC) {
455 return ldac_codec_specifics;
456 }
457 // parse the capability
458 auto& ldac_capability =
459 temp_codec_capabilities_->capabilities
460 .get<CodecCapabilities::Capabilities::ldacCapabilities>();
461
462 // combine those parameters into one list of
463 // CodecConfiguration::CodecSpecific
464 for (int32_t sample_rate : ldac_capability.sampleRateHz) {
465 for (int8_t bits_per_sample : ldac_capability.bitsPerSample) {
466 for (auto channel_mode : ldac_capability.channelMode) {
467 for (auto quality_index : ldac_capability.qualityIndex) {
468 LdacConfiguration ldac_data{.sampleRateHz = sample_rate,
469 .channelMode = channel_mode,
470 .qualityIndex = quality_index,
471 .bitsPerSample = bits_per_sample};
472 ldac_codec_specifics.push_back(
473 CodecConfiguration::CodecSpecific(ldac_data));
474 }
475 }
476 }
477 }
478 return ldac_codec_specifics;
479 }
480
481 std::vector<CodecConfiguration::CodecSpecific>
482 GetAptxCodecSpecificSupportedList(bool is_hd, bool supported) {
483 std::vector<CodecConfiguration::CodecSpecific> aptx_codec_specifics;
484 if (!supported) {
485 AptxConfiguration aptx_config{.sampleRateHz = 0, .bitsPerSample = 0};
486 aptx_codec_specifics.push_back(
487 CodecConfiguration::CodecSpecific(aptx_config));
488 return aptx_codec_specifics;
489 }
490 GetA2dpOffloadCapabilityHelper(
491 (is_hd ? CodecType::APTX_HD : CodecType::APTX));
492 if (temp_codec_capabilities_ == nullptr) {
493 return aptx_codec_specifics;
494 }
495 if ((is_hd && temp_codec_capabilities_->codecType != CodecType::APTX_HD) ||
496 (!is_hd && temp_codec_capabilities_->codecType != CodecType::APTX)) {
497 return aptx_codec_specifics;
498 }
499
500 // parse the capability
501 auto& aptx_capability =
502 temp_codec_capabilities_->capabilities
503 .get<CodecCapabilities::Capabilities::aptxCapabilities>();
504
505 // combine those parameters into one list of
506 // CodecConfiguration::CodecSpecific
507 for (int8_t bits_per_sample : aptx_capability.bitsPerSample) {
508 for (int32_t sample_rate : aptx_capability.sampleRateHz) {
509 for (auto channel_mode : aptx_capability.channelMode) {
510 AptxConfiguration aptx_data{.sampleRateHz = sample_rate,
511 .channelMode = channel_mode,
512 .bitsPerSample = bits_per_sample};
513 aptx_codec_specifics.push_back(
514 CodecConfiguration::CodecSpecific(aptx_data));
515 }
516 }
517 }
518 return aptx_codec_specifics;
519 }
520
521 std::vector<CodecConfiguration::CodecSpecific>
Omer Osmana2587da2022-05-01 03:54:11 +0000522 GetOpusCodecSpecificSupportedList(bool supported) {
523 std::vector<CodecConfiguration::CodecSpecific> opus_codec_specifics;
Josh Wu049e2cd2022-01-12 05:42:58 -0800524 if (!supported) {
Omer Osmana2587da2022-05-01 03:54:11 +0000525 OpusConfiguration opus_config{.samplingFrequencyHz = 0,
526 .frameDurationUs = 0};
527 opus_codec_specifics.push_back(
528 CodecConfiguration::CodecSpecific(opus_config));
529 return opus_codec_specifics;
Josh Wu049e2cd2022-01-12 05:42:58 -0800530 }
Omer Osmana2587da2022-05-01 03:54:11 +0000531 GetA2dpOffloadCapabilityHelper(CodecType::OPUS);
Josh Wu049e2cd2022-01-12 05:42:58 -0800532 if (temp_codec_capabilities_ == nullptr ||
Omer Osmana2587da2022-05-01 03:54:11 +0000533 temp_codec_capabilities_->codecType != CodecType::OPUS) {
534 return opus_codec_specifics;
Josh Wu049e2cd2022-01-12 05:42:58 -0800535 }
536 // parse the capability
Omer Osmana2587da2022-05-01 03:54:11 +0000537 auto& opus_capability =
Josh Wu049e2cd2022-01-12 05:42:58 -0800538 temp_codec_capabilities_->capabilities
Omer Osmana2587da2022-05-01 03:54:11 +0000539 .get<CodecCapabilities::Capabilities::opusCapabilities>();
Josh Wu049e2cd2022-01-12 05:42:58 -0800540
541 // combine those parameters into one list of
542 // CodecConfiguration::CodecSpecific
Omer Osmana2587da2022-05-01 03:54:11 +0000543 for (int32_t samplingFrequencyHz : opus_capability->samplingFrequencyHz) {
544 for (int32_t frameDurationUs : opus_capability->frameDurationUs) {
545 for (auto channel_mode : opus_capability->channelMode) {
546 OpusConfiguration opus_data{
547 .samplingFrequencyHz = samplingFrequencyHz,
shihchienc3ab9f5e2022-09-23 08:18:05 +0000548 .frameDurationUs = frameDurationUs,
Omer Osmana2587da2022-05-01 03:54:11 +0000549 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +0000550 };
Omer Osmana2587da2022-05-01 03:54:11 +0000551 opus_codec_specifics.push_back(
552 CodecConfiguration::CodecSpecific(opus_data));
Josh Wu049e2cd2022-01-12 05:42:58 -0800553 }
554 }
555 }
Omer Osmana2587da2022-05-01 03:54:11 +0000556 return opus_codec_specifics;
Josh Wu049e2cd2022-01-12 05:42:58 -0800557 }
558
Alice Kuoadcceec2022-03-28 13:28:43 +0800559 bool IsPcmConfigSupported(const PcmConfiguration& pcm_config) {
560 if (temp_provider_capabilities_.size() != 1 ||
561 temp_provider_capabilities_[0].getTag() !=
562 AudioCapabilities::pcmCapabilities) {
563 return false;
564 }
565 auto pcm_capability = temp_provider_capabilities_[0]
566 .get<AudioCapabilities::pcmCapabilities>();
567 return (contained_in_vector(pcm_capability.channelMode,
568 pcm_config.channelMode) &&
569 contained_in_vector(pcm_capability.sampleRateHz,
570 pcm_config.sampleRateHz) &&
571 contained_in_vector(pcm_capability.bitsPerSample,
572 pcm_config.bitsPerSample));
573 }
574
575 std::shared_ptr<IBluetoothAudioProviderFactory> provider_factory_;
576 std::shared_ptr<IBluetoothAudioProvider> audio_provider_;
577 std::shared_ptr<IBluetoothAudioPort> audio_port_;
578 std::vector<AudioCapabilities> temp_provider_capabilities_;
579
Josh Wu049e2cd2022-01-12 05:42:58 -0800580 // temp storage saves the specified codec capability by
581 // GetOffloadCodecCapabilityHelper()
582 CodecCapabilities* temp_codec_capabilities_;
Alice Kuoadcceec2022-03-28 13:28:43 +0800583
584 static constexpr SessionType kSessionTypes[] = {
585 SessionType::UNKNOWN,
586 SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
587 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
588 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
589 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
590 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
591 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
592 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
593 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
594 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
595 SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
596 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
Bao Do72399432023-11-09 08:13:05 +0000597 SessionType::HFP_SOFTWARE_ENCODING_DATAPATH,
598 SessionType::HFP_SOFTWARE_DECODING_DATAPATH,
Alice Kuoadcceec2022-03-28 13:28:43 +0800599 };
600};
601
602/**
603 * Test whether we can get the FactoryService from HIDL
604 */
605TEST_P(BluetoothAudioProviderFactoryAidl, GetProviderFactoryService) {}
606
607/**
608 * Test whether we can open a provider for each provider returned by
609 * getProviderCapabilities() with non-empty capabalities
610 */
611TEST_P(BluetoothAudioProviderFactoryAidl,
612 OpenProviderAndCheckCapabilitiesBySession) {
613 for (auto session_type : kSessionTypes) {
614 GetProviderCapabilitiesHelper(session_type);
615 OpenProviderHelper(session_type);
616 // We must be able to open a provider if its getProviderCapabilities()
617 // returns non-empty list.
618 EXPECT_TRUE(temp_provider_capabilities_.empty() ||
619 audio_provider_ != nullptr);
620 }
621}
622
623/**
Antoine SOULIER8c90f1f2023-09-26 18:55:17 +0000624 * Test that getProviderInfo, when implemented,
625 * returns empty information for session types for
626 * software data paths.
627 */
628TEST_P(BluetoothAudioProviderFactoryAidl, getProviderInfo_invalidSessionTypes) {
629 static constexpr SessionType kInvalidSessionTypes[]{
630 SessionType::UNKNOWN,
631 SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
632 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
633 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
634 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
635 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
636 SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
637 };
638
639 for (auto session_type : kInvalidSessionTypes) {
640 std::optional<IBluetoothAudioProviderFactory::ProviderInfo> provider_info =
641 std::nullopt;
642 auto aidl_retval =
643 provider_factory_->getProviderInfo(session_type, &provider_info);
644 if (!aidl_retval.isOk()) {
645 continue;
646 }
647
648 // If getProviderInfo is supported, the provider info
649 // must be empty for software session types.
650 ASSERT_FALSE(provider_info.has_value());
651 }
652}
653
654/**
655 * Test that getProviderInfo, when implemented,
656 * returns valid information for session types for
657 * a2dp hardware data paths.
658 */
659TEST_P(BluetoothAudioProviderFactoryAidl, getProviderInfo_a2dpSessionTypes) {
660 static constexpr SessionType kA2dpSessionTypes[]{
661 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
662 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
663 };
664
665 for (auto session_type : kA2dpSessionTypes) {
666 std::optional<IBluetoothAudioProviderFactory::ProviderInfo> provider_info =
667 std::nullopt;
668 auto aidl_retval =
669 provider_factory_->getProviderInfo(session_type, &provider_info);
670 if (!aidl_retval.isOk() || !provider_info.has_value()) {
671 continue;
672 }
673
674 for (auto const& codec_info : provider_info->codecInfos) {
675 // The codec id must not be core.
676 ASSERT_NE(codec_info.id.getTag(), CodecId::core);
677 // The codec info must contain the information
678 // for a2dp transport.
679 ASSERT_EQ(codec_info.transport.getTag(), CodecInfo::Transport::a2dp);
680 }
681 }
682}
683
684/**
685 * Test that getProviderInfo, when implemented,
686 * returns valid information for session types for
687 * le audio hardware data paths.
688 */
689TEST_P(BluetoothAudioProviderFactoryAidl, getProviderInfo_leAudioSessionTypes) {
690 static constexpr SessionType kLeAudioSessionTypes[]{
691 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
692 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
693 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
694 };
695
696 for (auto session_type : kLeAudioSessionTypes) {
697 std::optional<IBluetoothAudioProviderFactory::ProviderInfo> provider_info =
698 std::nullopt;
699 auto aidl_retval =
700 provider_factory_->getProviderInfo(session_type, &provider_info);
701 if (!aidl_retval.isOk() || !provider_info.has_value()) {
702 continue;
703 }
704
705 for (auto const& codec_info : provider_info->codecInfos) {
706 // The codec id must not be a2dp.
707 ASSERT_NE(codec_info.id.getTag(), CodecId::a2dp);
708 // The codec info must contain the information
709 // for le audio transport.
710 // ASSERT_EQ(codec_info.transport.getTag(),
711 // CodecInfo::Transport::le_audio);
712 }
713 }
714}
715
Antoine SOULIER33c4e5a2023-09-28 21:59:19 +0000716class BluetoothAudioProviderAidl : public BluetoothAudioProviderFactoryAidl {
717 protected:
718 std::optional<IBluetoothAudioProviderFactory::ProviderInfo>
719 a2dp_encoding_provider_info_{};
720 std::optional<IBluetoothAudioProviderFactory::ProviderInfo>
721 a2dp_decoding_provider_info_{};
722 std::shared_ptr<IBluetoothAudioProvider> a2dp_encoding_provider_{nullptr};
723 std::shared_ptr<IBluetoothAudioProvider> a2dp_decoding_provider_{nullptr};
724
725 public:
726 void SetUp() override {
727 BluetoothAudioProviderFactoryAidl::SetUp();
728 audio_port_ = ndk::SharedRefBase::make<BluetoothAudioPort>();
729
730 (void)provider_factory_->getProviderInfo(
731 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
732 &a2dp_encoding_provider_info_);
733
734 (void)provider_factory_->getProviderInfo(
735 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
736 &a2dp_decoding_provider_info_);
737
738 (void)provider_factory_->openProvider(
739 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
740 &a2dp_encoding_provider_);
741
742 (void)provider_factory_->openProvider(
743 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
744 &a2dp_decoding_provider_);
745 }
746};
747
748/**
749 * Calling parseA2dpConfiguration on a session of a different type than
750 * A2DP_HARDWARE_OFFLOAD_(ENCODING|DECODING)_DATAPATH must fail.
751 */
752TEST_P(BluetoothAudioProviderAidl, parseA2dpConfiguration_invalidSessionType) {
753 static constexpr SessionType kInvalidSessionTypes[] = {
754 SessionType::UNKNOWN,
755 SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
756 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
757 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
758 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
759 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
760 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
761 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
762 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
763 SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
764 };
765
766 for (auto session_type : kInvalidSessionTypes) {
767 // Open a BluetoothAudioProvider instance of the selected session type.
768 // Skip validation if the provider cannot be opened.
769 std::shared_ptr<IBluetoothAudioProvider> provider{nullptr};
770 (void)provider_factory_->openProvider(session_type, &provider);
771 if (provider == nullptr) {
772 continue;
773 }
774
775 // parseA2dpConfiguration must fail without returning an A2dpStatus.
776 CodecId codec_id(CodecId::A2dp::SBC);
777 CodecParameters codec_parameters;
778 A2dpStatus a2dp_status = A2dpStatus::OK;
779 auto aidl_retval = provider->parseA2dpConfiguration(
780 codec_id, std::vector<uint8_t>{}, &codec_parameters, &a2dp_status);
781 EXPECT_FALSE(aidl_retval.isOk());
782 }
783}
784
785/**
786 * Calling parseA2dpConfiguration with an unknown codec must fail
787 * with the A2dpStatus code INVALID_CODEC_TYPE or NOT_SUPPORTED_CODEC_TYPE.
788 */
789TEST_P(BluetoothAudioProviderAidl,
790 parseA2dpConfiguration_unsupportedCodecType) {
791 CodecId unsupported_core_id(CodecId::Core::CVSD);
792 CodecId unsupported_vendor_id(
793 CodecId::Vendor(0xFCB1, 0x42)); // Google Codec #42
794
795 for (auto& provider : {a2dp_encoding_provider_, a2dp_decoding_provider_}) {
796 if (provider == nullptr) {
797 continue;
798 }
799
800 CodecParameters codec_parameters;
801 A2dpStatus a2dp_status = A2dpStatus::OK;
802 ::ndk::ScopedAStatus aidl_retval;
803
804 // Test with two invalid codec identifiers: vendor or core.
805 aidl_retval = provider->parseA2dpConfiguration(
806 unsupported_core_id, std::vector<uint8_t>{}, &codec_parameters,
807 &a2dp_status);
808 EXPECT_TRUE(!aidl_retval.isOk() ||
809 a2dp_status == A2dpStatus::NOT_SUPPORTED_CODEC_TYPE);
810
811 aidl_retval = provider->parseA2dpConfiguration(
812 unsupported_vendor_id, std::vector<uint8_t>{}, &codec_parameters,
813 &a2dp_status);
814 EXPECT_TRUE(!aidl_retval.isOk() ||
815 a2dp_status == A2dpStatus::NOT_SUPPORTED_CODEC_TYPE);
816 }
817}
818
819/**
820 * Calling parseA2dpConfiguration with a known codec and invalid configuration
821 * must fail with an A2dpStatus code different from INVALID_CODEC_TYPE or
822 * NOT_SUPPORTED_CODEC_TYPE.
823 */
824TEST_P(BluetoothAudioProviderAidl,
825 parseA2dpConfiguration_invalidConfiguration) {
826 for (auto& [provider, provider_info] :
827 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
828 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
829 if (provider == nullptr || !provider_info.has_value() ||
830 provider_info->codecInfos.empty()) {
831 continue;
832 }
833
834 CodecParameters codec_parameters;
835 A2dpStatus a2dp_status = A2dpStatus::OK;
836 ::ndk::ScopedAStatus aidl_retval;
837
838 // Test with the first available codec in the provider info for testing.
839 // The test runs with an empty parameters array, anything more specific
840 // would need understanding the codec.
841 aidl_retval = provider->parseA2dpConfiguration(
842 provider_info->codecInfos[0].id, std::vector<uint8_t>{},
843 &codec_parameters, &a2dp_status);
844 ASSERT_TRUE(aidl_retval.isOk());
845 EXPECT_TRUE(a2dp_status != A2dpStatus::OK &&
846 a2dp_status != A2dpStatus::NOT_SUPPORTED_CODEC_TYPE &&
847 a2dp_status != A2dpStatus::INVALID_CODEC_TYPE);
848 }
849}
850
851/**
852 * Calling parseA2dpConfiguration with a known codec and valid parameters
853 * must return with A2dpStatus OK.
854 */
855TEST_P(BluetoothAudioProviderAidl, parseA2dpConfiguration_valid) {
856 for (auto& [provider, provider_info] :
857 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
858 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
859 if (provider == nullptr || !provider_info.has_value() ||
860 provider_info->codecInfos.empty()) {
861 continue;
862 }
863
864 CodecParameters codec_parameters;
865 A2dpStatus a2dp_status = A2dpStatus::OK;
866 ::ndk::ScopedAStatus aidl_retval;
867
868 // Test with the first available codec in the provider info for testing.
869 // To get a valid configuration (the capabilities array in the provider
870 // info is not a selection), getA2dpConfiguration is used with the
871 // selected codec parameters as input.
872 auto const& codec_info = provider_info->codecInfos[0];
873 auto transport = codec_info.transport.get<CodecInfo::Transport::a2dp>();
874 A2dpRemoteCapabilities remote_capabilities(/*seid*/ 0, codec_info.id,
875 transport.capabilities);
876 std::optional<A2dpConfiguration> configuration;
877 aidl_retval = provider->getA2dpConfiguration(
878 std::vector<A2dpRemoteCapabilities>{remote_capabilities},
879 A2dpConfigurationHint(), &configuration);
880 ASSERT_TRUE(aidl_retval.isOk());
881 ASSERT_TRUE(configuration.has_value());
882
883 aidl_retval = provider->parseA2dpConfiguration(
884 configuration->id, configuration->configuration, &codec_parameters,
885 &a2dp_status);
886 ASSERT_TRUE(aidl_retval.isOk());
887 EXPECT_TRUE(a2dp_status == A2dpStatus::OK);
888 EXPECT_EQ(codec_parameters, configuration->parameters);
889 }
890}
891
892/**
893 * Calling getA2dpConfiguration on a session of a different type than
894 * A2DP_HARDWARE_OFFLOAD_(ENCODING|DECODING)_DATAPATH must fail.
895 */
896TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_invalidSessionType) {
897 static constexpr SessionType kInvalidSessionTypes[] = {
898 SessionType::UNKNOWN,
899 SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
900 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
901 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
902 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
903 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
904 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
905 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
906 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
907 SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
908 };
909
910 for (auto session_type : kInvalidSessionTypes) {
911 // Open a BluetoothAudioProvider instance of the selected session type.
912 // Skip validation if the provider cannot be opened.
913 std::shared_ptr<IBluetoothAudioProvider> provider{nullptr};
914 auto aidl_retval = provider_factory_->openProvider(session_type, &provider);
915 if (provider == nullptr) {
916 continue;
917 }
918
919 // getA2dpConfiguration must fail without returning a configuration.
920 std::optional<A2dpConfiguration> configuration;
921 aidl_retval =
922 provider->getA2dpConfiguration(std::vector<A2dpRemoteCapabilities>{},
923 A2dpConfigurationHint(), &configuration);
924 EXPECT_FALSE(aidl_retval.isOk());
925 }
926}
927
928/**
929 * Calling getA2dpConfiguration with empty or unknown remote capabilities
930 * must return an empty configuration.
931 */
932TEST_P(BluetoothAudioProviderAidl,
933 getA2dpConfiguration_unknownRemoteCapabilities) {
934 for (auto& [provider, provider_info] :
935 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
936 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
937 if (provider == nullptr || !provider_info.has_value() ||
938 provider_info->codecInfos.empty()) {
939 continue;
940 }
941
942 std::optional<A2dpConfiguration> configuration;
943 ::ndk::ScopedAStatus aidl_retval;
944
945 // Test with empty remote capabilities.
946 aidl_retval =
947 provider->getA2dpConfiguration(std::vector<A2dpRemoteCapabilities>{},
948 A2dpConfigurationHint(), &configuration);
949 ASSERT_TRUE(aidl_retval.isOk());
950 EXPECT_FALSE(configuration.has_value());
951
952 // Test with unknown remote capabilities.
953 A2dpRemoteCapabilities unknown_core_remote_capabilities(
954 /*seid*/ 0, CodecId::Core::CVSD, std::vector<uint8_t>{1, 2, 3});
955 A2dpRemoteCapabilities unknown_vendor_remote_capabilities(
956 /*seid*/ 1,
957 /* Google Codec #42 */ CodecId::Vendor(0xFCB1, 0x42),
958 std::vector<uint8_t>{1, 2, 3});
959 aidl_retval = provider->getA2dpConfiguration(
960 std::vector<A2dpRemoteCapabilities>{
961 unknown_core_remote_capabilities,
962 unknown_vendor_remote_capabilities,
963 },
964 A2dpConfigurationHint(), &configuration);
965 ASSERT_TRUE(aidl_retval.isOk());
966 EXPECT_FALSE(configuration.has_value());
967 }
968}
969
970/**
971 * Calling getA2dpConfiguration with invalid remote capabilities
972 * must return an empty configuration.
973 */
974TEST_P(BluetoothAudioProviderAidl,
975 getA2dpConfiguration_invalidRemoteCapabilities) {
976 for (auto& [provider, provider_info] :
977 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
978 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
979 if (provider == nullptr || !provider_info.has_value() ||
980 provider_info->codecInfos.empty()) {
981 continue;
982 }
983
984 std::optional<A2dpConfiguration> configuration;
985 ::ndk::ScopedAStatus aidl_retval;
986
987 // Use the first available codec in the provider info for testing.
988 // The capabilities are modified to make them invalid.
989 auto const& codec_info = provider_info->codecInfos[0];
990 auto transport = codec_info.transport.get<CodecInfo::Transport::a2dp>();
991 std::vector<uint8_t> invalid_capabilities = transport.capabilities;
992 invalid_capabilities.push_back(0x42); // adding bytes should be invalid.
993 aidl_retval = provider->getA2dpConfiguration(
994 std::vector<A2dpRemoteCapabilities>{
995 A2dpRemoteCapabilities(/*seid*/ 0, codec_info.id,
996 std::vector<uint8_t>()),
997 A2dpRemoteCapabilities(/*seid*/ 1, codec_info.id,
998 invalid_capabilities),
999 },
1000 A2dpConfigurationHint(), &configuration);
1001 ASSERT_TRUE(aidl_retval.isOk());
1002 EXPECT_FALSE(configuration.has_value());
1003 }
1004}
1005
1006/**
1007 * Calling getA2dpConfiguration with valid remote capabilities
1008 * must return a valid configuration. The selected parameters must
1009 * be contained in the original capabilities. The returned configuration
1010 * must match the returned parameters. The returned SEID must match the
1011 * input SEID.
1012 */
1013TEST_P(BluetoothAudioProviderAidl,
1014 getA2dpConfiguration_validRemoteCapabilities) {
1015 for (auto& [provider, provider_info] :
1016 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1017 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1018 if (provider == nullptr || !provider_info.has_value() ||
1019 provider_info->codecInfos.empty()) {
1020 continue;
1021 }
1022
1023 // Test with all available codecs in the provider info.
1024 for (auto const& codec_info : provider_info->codecInfos) {
1025 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1026 std::optional<A2dpConfiguration> configuration{};
1027 ::ndk::ScopedAStatus aidl_retval;
1028
1029 aidl_retval = provider->getA2dpConfiguration(
1030 std::vector<A2dpRemoteCapabilities>{
1031 A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
1032 a2dp_info.capabilities),
1033 },
1034 A2dpConfigurationHint(), &configuration);
1035
1036 ASSERT_TRUE(aidl_retval.isOk());
1037 ASSERT_TRUE(configuration.has_value());
1038
1039 // Returned configuration must have the same codec id
1040 // as the remote capability.
1041 EXPECT_EQ(configuration->id, codec_info.id);
1042
1043 // Returned configuration must have the same SEID
1044 // as the remote capability.
1045 EXPECT_EQ(configuration->remoteSeid, 42);
1046
1047 // Returned codec parameters must be in the range of input
1048 // parameters.
1049 EXPECT_NE(
1050 std::find(a2dp_info.channelMode.begin(), a2dp_info.channelMode.end(),
1051 configuration->parameters.channelMode),
1052 a2dp_info.channelMode.end());
1053 EXPECT_NE(std::find(a2dp_info.samplingFrequencyHz.begin(),
1054 a2dp_info.samplingFrequencyHz.end(),
1055 configuration->parameters.samplingFrequencyHz),
1056 a2dp_info.samplingFrequencyHz.end());
1057 EXPECT_NE(std::find(a2dp_info.bitdepth.begin(), a2dp_info.bitdepth.end(),
1058 configuration->parameters.bitdepth),
1059 a2dp_info.bitdepth.end());
1060 EXPECT_EQ(a2dp_info.lossless, configuration->parameters.lossless);
1061 EXPECT_TRUE(configuration->parameters.minBitrate <=
1062 configuration->parameters.maxBitrate);
1063
1064 // Returned configuration must be parsable by parseA2dpParameters
1065 // and match the codec parameters.
1066 CodecParameters codec_parameters;
1067 A2dpStatus a2dp_status = A2dpStatus::OK;
1068 aidl_retval = provider->parseA2dpConfiguration(
1069 configuration->id, configuration->configuration, &codec_parameters,
1070 &a2dp_status);
1071 ASSERT_TRUE(aidl_retval.isOk());
1072 EXPECT_TRUE(a2dp_status == A2dpStatus::OK);
1073 EXPECT_EQ(codec_parameters, configuration->parameters);
1074 }
1075 }
1076}
1077
1078/**
1079 * Calling getA2dpConfiguration with valid remote capabilities
1080 * with various hinted codec ids.
1081 */
1082TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_hintCodecId) {
1083 for (auto& [provider, provider_info] :
1084 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1085 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1086 if (provider == nullptr || !provider_info.has_value() ||
1087 provider_info->codecInfos.empty()) {
1088 continue;
1089 }
1090
1091 // Build the remote capabilities with all supported codecs.
1092 std::vector<A2dpRemoteCapabilities> remote_capabilities;
1093 for (size_t n = 0; n < provider_info->codecInfos.size(); n++) {
1094 auto const& codec_info = provider_info->codecInfos[n];
1095 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1096 remote_capabilities.push_back(A2dpRemoteCapabilities(
1097 /*seid*/ n, codec_info.id, a2dp_info.capabilities));
1098 }
1099
1100 // Test with all supported codec identifiers,
1101 for (auto const& codec_info : provider_info->codecInfos) {
1102 std::optional<A2dpConfiguration> configuration{};
1103 ::ndk::ScopedAStatus aidl_retval;
1104
1105 A2dpConfigurationHint hint;
1106 hint.codecId = codec_info.id;
1107
1108 aidl_retval = provider->getA2dpConfiguration(remote_capabilities, hint,
1109 &configuration);
1110
1111 ASSERT_TRUE(aidl_retval.isOk());
1112 ASSERT_TRUE(configuration.has_value());
1113 EXPECT_EQ(configuration->id, codec_info.id);
1114 }
1115
1116 // Test with unknown codec identifiers: either core or vendor.
1117 for (auto& codec_id :
1118 {CodecId(CodecId::Core::CVSD),
1119 CodecId(CodecId::Vendor(0xFCB1, 0x42)) /*Google Codec #42*/}) {
1120 std::optional<A2dpConfiguration> configuration{};
1121 ::ndk::ScopedAStatus aidl_retval;
1122
1123 A2dpConfigurationHint hint;
1124 hint.codecId = codec_id;
1125
1126 aidl_retval = provider->getA2dpConfiguration(remote_capabilities, hint,
1127 &configuration);
1128
1129 ASSERT_TRUE(aidl_retval.isOk());
1130 ASSERT_TRUE(configuration.has_value());
1131 EXPECT_NE(configuration->id, codec_id);
1132 }
1133 }
1134}
1135
1136/**
1137 * Calling getA2dpConfiguration with valid remote capabilities
1138 * with various hinted channel modes.
1139 */
1140TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_hintChannelMode) {
1141 for (auto& [provider, provider_info] :
1142 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1143 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1144 if (provider == nullptr || !provider_info.has_value() ||
1145 provider_info->codecInfos.empty()) {
1146 continue;
1147 }
1148
1149 // Test with all available codecs in the provider info.
1150 for (auto const& codec_info : provider_info->codecInfos) {
1151 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1152 std::optional<A2dpConfiguration> configuration{};
1153 ::ndk::ScopedAStatus aidl_retval;
1154
1155 for (auto& channel_mode :
1156 {ChannelMode::STEREO, ChannelMode::MONO, ChannelMode::DUALMONO}) {
1157 // Add the hint for the channel mode.
1158 A2dpConfigurationHint hint;
1159 auto& codec_parameters = hint.codecParameters.emplace();
1160 codec_parameters.channelMode = channel_mode;
1161
1162 aidl_retval = provider->getA2dpConfiguration(
1163 std::vector<A2dpRemoteCapabilities>{
1164 A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
1165 a2dp_info.capabilities),
1166 },
1167 hint, &configuration);
1168
1169 ASSERT_TRUE(aidl_retval.isOk());
1170 ASSERT_TRUE(configuration.has_value());
1171
1172 // The hint must be ignored if the channel mode is not supported
1173 // by the codec, and applied otherwise.
1174 ASSERT_EQ(configuration->parameters.channelMode == channel_mode,
1175 std::find(a2dp_info.channelMode.begin(),
1176 a2dp_info.channelMode.end(),
1177 channel_mode) != a2dp_info.channelMode.end());
1178 }
1179 }
1180 }
1181}
1182
1183/**
1184 * Calling getA2dpConfiguration with valid remote capabilities
1185 * with various hinted sampling frequencies.
1186 */
1187TEST_P(BluetoothAudioProviderAidl,
1188 getA2dpConfiguration_hintSamplingFrequencyHz) {
1189 for (auto& [provider, provider_info] :
1190 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1191 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1192 if (provider == nullptr || !provider_info.has_value() ||
1193 provider_info->codecInfos.empty()) {
1194 continue;
1195 }
1196
1197 // Test with all available codecs in the provider info.
1198 for (auto const& codec_info : provider_info->codecInfos) {
1199 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1200 std::optional<A2dpConfiguration> configuration{};
1201 ::ndk::ScopedAStatus aidl_retval;
1202
1203 for (auto& sampling_frequency_hz : {
1204 0,
1205 1,
1206 8000,
1207 16000,
1208 24000,
1209 32000,
1210 44100,
1211 48000,
1212 88200,
1213 96000,
1214 176400,
1215 192000,
1216 }) {
1217 // Add the hint for the sampling frequency.
1218 A2dpConfigurationHint hint;
1219 auto& codec_parameters = hint.codecParameters.emplace();
1220 codec_parameters.samplingFrequencyHz = sampling_frequency_hz;
1221
1222 aidl_retval = provider->getA2dpConfiguration(
1223 std::vector<A2dpRemoteCapabilities>{
1224 A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
1225 a2dp_info.capabilities),
1226 },
1227 hint, &configuration);
1228
1229 ASSERT_TRUE(aidl_retval.isOk());
1230 ASSERT_TRUE(configuration.has_value());
1231
1232 // The hint must be ignored if the sampling frequency is not supported
1233 // by the codec, and applied otherwise.
1234 ASSERT_EQ(configuration->parameters.samplingFrequencyHz ==
1235 sampling_frequency_hz,
1236 std::find(a2dp_info.samplingFrequencyHz.begin(),
1237 a2dp_info.samplingFrequencyHz.end(),
1238 sampling_frequency_hz) !=
1239 a2dp_info.samplingFrequencyHz.end());
1240 }
1241 }
1242 }
1243}
1244
1245/**
1246 * Calling getA2dpConfiguration with valid remote capabilities
1247 * with various hinted sampling bit-depths.
1248 */
1249TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_hintBitdepth) {
1250 for (auto& [provider, provider_info] :
1251 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1252 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1253 if (provider == nullptr || !provider_info.has_value() ||
1254 provider_info->codecInfos.empty()) {
1255 continue;
1256 }
1257
1258 // Test with all available codecs in the provider info.
1259 for (auto const& codec_info : provider_info->codecInfos) {
1260 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1261 std::optional<A2dpConfiguration> configuration{};
1262 ::ndk::ScopedAStatus aidl_retval;
1263
1264 for (auto& bitdepth : {0, 1, 16, 24, 32}) {
1265 // Add the hint for the bit depth.
1266 A2dpConfigurationHint hint;
1267 auto& codec_parameters = hint.codecParameters.emplace();
1268 codec_parameters.bitdepth = bitdepth;
1269
1270 aidl_retval = provider->getA2dpConfiguration(
1271 std::vector<A2dpRemoteCapabilities>{
1272 A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
1273 a2dp_info.capabilities),
1274 },
1275 hint, &configuration);
1276
1277 ASSERT_TRUE(aidl_retval.isOk());
1278 ASSERT_TRUE(configuration.has_value());
1279
1280 // The hint must be ignored if the bitdepth is not supported
1281 // by the codec, and applied otherwise.
1282 ASSERT_EQ(
1283 configuration->parameters.bitdepth == bitdepth,
1284 std::find(a2dp_info.bitdepth.begin(), a2dp_info.bitdepth.end(),
1285 bitdepth) != a2dp_info.bitdepth.end());
1286 }
1287 }
1288 }
1289}
1290
1291/**
1292 * Calling startSession with an unknown codec id must fail.
1293 */
1294TEST_P(BluetoothAudioProviderAidl, startSession_unknownCodecId) {
1295 for (auto& [provider, provider_info] :
1296 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1297 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1298 if (provider == nullptr || !provider_info.has_value() ||
1299 provider_info->codecInfos.empty()) {
1300 continue;
1301 }
1302
1303 for (auto& codec_id :
1304 {CodecId(CodecId::Core::CVSD),
1305 CodecId(CodecId::Vendor(0xFCB1, 0x42) /*Google Codec #42*/)}) {
1306 A2dpStreamConfiguration a2dp_config;
1307 DataMQDesc data_mq_desc;
1308
1309 a2dp_config.codecId = codec_id;
1310 a2dp_config.configuration = std::vector<uint8_t>{1, 2, 3};
1311
1312 auto aidl_retval =
1313 provider->startSession(audio_port_, AudioConfiguration(a2dp_config),
1314 std::vector<LatencyMode>{}, &data_mq_desc);
1315
1316 EXPECT_FALSE(aidl_retval.isOk());
1317 }
1318 }
1319}
1320
1321/**
1322 * Calling startSession with a known codec and a valid configuration
1323 * must succeed.
1324 */
1325TEST_P(BluetoothAudioProviderAidl, startSession_valid) {
1326 for (auto& [provider, provider_info] :
1327 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1328 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1329 if (provider == nullptr || !provider_info.has_value() ||
1330 provider_info->codecInfos.empty()) {
1331 continue;
1332 }
1333
1334 // Use the first available codec in the provider info for testing.
1335 // To get a valid configuration (the capabilities array in the provider
1336 // info is not a selection), getA2dpConfiguration is used with the
1337 // selected codec parameters as input.
1338 auto const& codec_info = provider_info->codecInfos[0];
1339 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1340 ::ndk::ScopedAStatus aidl_retval;
1341 A2dpRemoteCapabilities remote_capabilities(/*seid*/ 0, codec_info.id,
1342 a2dp_info.capabilities);
1343 std::optional<A2dpConfiguration> configuration;
1344 aidl_retval = provider->getA2dpConfiguration(
1345 std::vector<A2dpRemoteCapabilities>{remote_capabilities},
1346 A2dpConfigurationHint(), &configuration);
1347 ASSERT_TRUE(aidl_retval.isOk());
1348 ASSERT_TRUE(configuration.has_value());
1349
1350 // Build the stream configuration.
1351 A2dpStreamConfiguration a2dp_config;
1352 DataMQDesc data_mq_desc;
1353
1354 a2dp_config.codecId = codec_info.id;
1355 a2dp_config.configuration = configuration->configuration;
1356
1357 aidl_retval =
1358 provider->startSession(audio_port_, AudioConfiguration(a2dp_config),
1359 std::vector<LatencyMode>{}, &data_mq_desc);
1360
1361 EXPECT_TRUE(aidl_retval.isOk());
1362 }
1363}
1364
1365/**
1366 * Calling startSession with a known codec but an invalid configuration
1367 * must fail.
1368 */
1369TEST_P(BluetoothAudioProviderAidl, startSession_invalidConfiguration) {
1370 for (auto& [provider, provider_info] :
1371 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1372 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1373 if (provider == nullptr || !provider_info.has_value() ||
1374 provider_info->codecInfos.empty()) {
1375 continue;
1376 }
1377
1378 // Use the first available codec in the provider info for testing.
1379 // To get a valid configuration (the capabilities array in the provider
1380 // info is not a selection), getA2dpConfiguration is used with the
1381 // selected codec parameters as input.
1382 ::ndk::ScopedAStatus aidl_retval;
1383 auto const& codec_info = provider_info->codecInfos[0];
1384 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1385 A2dpRemoteCapabilities remote_capabilities(/*seid*/ 0, codec_info.id,
1386 a2dp_info.capabilities);
1387 std::optional<A2dpConfiguration> configuration;
1388 aidl_retval = provider->getA2dpConfiguration(
1389 std::vector<A2dpRemoteCapabilities>{remote_capabilities},
1390 A2dpConfigurationHint(), &configuration);
1391 ASSERT_TRUE(aidl_retval.isOk());
1392 ASSERT_TRUE(configuration.has_value());
1393
1394 // Build the stream configuration but edit the configuration bytes
1395 // to make it invalid.
1396 A2dpStreamConfiguration a2dp_config;
1397 DataMQDesc data_mq_desc;
1398
1399 a2dp_config.codecId = codec_info.id;
1400 a2dp_config.configuration = configuration->configuration;
1401 a2dp_config.configuration.push_back(42);
1402
1403 aidl_retval =
1404 provider->startSession(audio_port_, AudioConfiguration(a2dp_config),
1405 std::vector<LatencyMode>{}, &data_mq_desc);
1406
1407 EXPECT_FALSE(aidl_retval.isOk());
1408 }
1409}
1410
Antoine SOULIER8c90f1f2023-09-26 18:55:17 +00001411/**
Alice Kuoadcceec2022-03-28 13:28:43 +08001412 * openProvider A2DP_SOFTWARE_ENCODING_DATAPATH
1413 */
1414class BluetoothAudioProviderA2dpEncodingSoftwareAidl
1415 : public BluetoothAudioProviderFactoryAidl {
1416 public:
1417 virtual void SetUp() override {
1418 BluetoothAudioProviderFactoryAidl::SetUp();
1419 GetProviderCapabilitiesHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
1420 OpenProviderHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
1421 ASSERT_NE(audio_provider_, nullptr);
1422 }
1423
1424 virtual void TearDown() override {
1425 audio_port_ = nullptr;
1426 audio_provider_ = nullptr;
1427 BluetoothAudioProviderFactoryAidl::TearDown();
1428 }
Josh Wu049e2cd2022-01-12 05:42:58 -08001429};
1430
1431/**
1432 * Test whether we can open a provider of type
1433 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001434TEST_P(BluetoothAudioProviderA2dpEncodingSoftwareAidl,
1435 OpenA2dpEncodingSoftwareProvider) {}
1436
1437/**
1438 * Test whether each provider of type
1439 * SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH can be started and stopped with
1440 * different PCM config
1441 */
1442TEST_P(BluetoothAudioProviderA2dpEncodingSoftwareAidl,
1443 StartAndEndA2dpEncodingSoftwareSessionWithPossiblePcmConfig) {
1444 for (auto sample_rate : a2dp_sample_rates) {
1445 for (auto bits_per_sample : a2dp_bits_per_samples) {
1446 for (auto channel_mode : a2dp_channel_modes) {
1447 PcmConfiguration pcm_config{
1448 .sampleRateHz = sample_rate,
Alice Kuoadcceec2022-03-28 13:28:43 +08001449 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00001450 .bitsPerSample = bits_per_sample,
Alice Kuoadcceec2022-03-28 13:28:43 +08001451 };
1452 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
1453 DataMQDesc mq_desc;
1454 auto aidl_retval = audio_provider_->startSession(
1455 audio_port_, AudioConfiguration(pcm_config), latency_modes,
1456 &mq_desc);
1457 DataMQ data_mq(mq_desc);
1458
1459 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
1460 if (is_codec_config_valid) {
1461 EXPECT_TRUE(data_mq.isValid());
1462 }
1463 EXPECT_TRUE(audio_provider_->endSession().isOk());
1464 }
1465 }
1466 }
1467}
1468
1469/**
Bao Do72399432023-11-09 08:13:05 +00001470 * openProvider HFP_SOFTWARE_ENCODING_DATAPATH
1471 */
1472class BluetoothAudioProviderHfpSoftwareEncodingAidl
1473 : public BluetoothAudioProviderFactoryAidl {
1474 public:
1475 virtual void SetUp() override {
1476 BluetoothAudioProviderFactoryAidl::SetUp();
1477 GetProviderCapabilitiesHelper(SessionType::HFP_SOFTWARE_ENCODING_DATAPATH);
1478 OpenProviderHelper(SessionType::HFP_SOFTWARE_ENCODING_DATAPATH);
1479 ASSERT_NE(audio_provider_, nullptr);
1480 }
1481
1482 virtual void TearDown() override {
1483 audio_port_ = nullptr;
1484 audio_provider_ = nullptr;
1485 BluetoothAudioProviderFactoryAidl::TearDown();
1486 }
1487
1488 bool OpenSession(int32_t sample_rate, int8_t bits_per_sample,
1489 ChannelMode channel_mode, int32_t data_interval_us) {
1490 PcmConfiguration pcm_config{
1491 .sampleRateHz = sample_rate,
1492 .channelMode = channel_mode,
1493 .bitsPerSample = bits_per_sample,
1494 .dataIntervalUs = data_interval_us,
1495 };
1496 // Checking against provider capability from getProviderCapabilities
1497 // For HFP software, it's
1498 // BluetoothAudioCodecs::GetSoftwarePcmCapabilities();
1499 DataMQDesc mq_desc;
1500 auto aidl_retval = audio_provider_->startSession(
1501 audio_port_, AudioConfiguration(pcm_config), latency_modes, &mq_desc);
1502 DataMQ data_mq(mq_desc);
1503
1504 if (!aidl_retval.isOk()) return false;
1505 if (!data_mq.isValid()) return false;
1506 return true;
1507 }
1508};
1509
1510/**
1511 * Test whether we can open a provider of type
1512 */
1513TEST_P(BluetoothAudioProviderHfpSoftwareEncodingAidl,
1514 OpenHfpSoftwareEncodingProvider) {}
1515
1516/**
1517 * Test whether each provider of type
1518 * SessionType::HFP_SOFTWARE_ENCODING_DATAPATH can be started and stopped with
1519 * different PCM config
1520 */
1521TEST_P(BluetoothAudioProviderHfpSoftwareEncodingAidl,
1522 StartAndEndHfpEncodingSoftwareSessionWithPossiblePcmConfig) {
1523 for (auto sample_rate : hfp_sample_rates_) {
1524 for (auto bits_per_sample : hfp_bits_per_samples_) {
1525 for (auto channel_mode : hfp_channel_modes_) {
1526 for (auto data_interval_us: hfp_data_interval_us_) {
1527 EXPECT_TRUE(OpenSession(sample_rate, bits_per_sample,
1528 channel_mode, data_interval_us));
1529 EXPECT_TRUE(audio_provider_->endSession().isOk());
1530 }
1531 }
1532 }
1533 }
1534}
1535
1536/**
1537 * openProvider HFP_SOFTWARE_DECODING_DATAPATH
1538 */
1539class BluetoothAudioProviderHfpSoftwareDecodingAidl
1540 : public BluetoothAudioProviderFactoryAidl {
1541 public:
1542 virtual void SetUp() override {
1543 BluetoothAudioProviderFactoryAidl::SetUp();
1544 GetProviderCapabilitiesHelper(SessionType::HFP_SOFTWARE_DECODING_DATAPATH);
1545 OpenProviderHelper(SessionType::HFP_SOFTWARE_DECODING_DATAPATH);
1546 ASSERT_NE(audio_provider_, nullptr);
1547 }
1548
1549 virtual void TearDown() override {
1550 audio_port_ = nullptr;
1551 audio_provider_ = nullptr;
1552 BluetoothAudioProviderFactoryAidl::TearDown();
1553 }
1554
1555 bool OpenSession(int32_t sample_rate, int8_t bits_per_sample,
1556 ChannelMode channel_mode, int32_t data_interval_us) {
1557 PcmConfiguration pcm_config{
1558 .sampleRateHz = sample_rate,
1559 .channelMode = channel_mode,
1560 .bitsPerSample = bits_per_sample,
1561 .dataIntervalUs = data_interval_us,
1562 };
1563 DataMQDesc mq_desc;
1564 auto aidl_retval = audio_provider_->startSession(
1565 audio_port_, AudioConfiguration(pcm_config), latency_modes, &mq_desc);
1566 DataMQ data_mq(mq_desc);
1567
1568 if (!aidl_retval.isOk()) return false;
1569 if (!data_mq.isValid()) return false;
1570 return true;
1571 }
1572};
1573
1574/**
1575 * Test whether we can open a provider of type
1576 */
1577TEST_P(BluetoothAudioProviderHfpSoftwareDecodingAidl,
1578 OpenHfpSoftwareDecodingProvider) {}
1579
1580/**
1581 * Test whether each provider of type
1582 * SessionType::HFP_SOFTWARE_DECODING_DATAPATH can be started and stopped with
1583 * different PCM config
1584 */
1585TEST_P(BluetoothAudioProviderHfpSoftwareDecodingAidl,
1586 StartAndEndHfpDecodingSoftwareSessionWithPossiblePcmConfig) {
1587 for (auto sample_rate : hfp_sample_rates_) {
1588 for (auto bits_per_sample : hfp_bits_per_samples_) {
1589 for (auto channel_mode : hfp_channel_modes_) {
1590 for (auto data_interval_us: hfp_data_interval_us_) {
1591 EXPECT_TRUE(OpenSession(sample_rate, bits_per_sample,
1592 channel_mode, data_interval_us));
1593 EXPECT_TRUE(audio_provider_->endSession().isOk());
1594 }
1595 }
1596 }
1597 }
1598}
1599
1600/**
Alice Kuoadcceec2022-03-28 13:28:43 +08001601 * openProvider A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH
1602 */
1603class BluetoothAudioProviderA2dpEncodingHardwareAidl
1604 : public BluetoothAudioProviderFactoryAidl {
1605 public:
1606 virtual void SetUp() override {
1607 BluetoothAudioProviderFactoryAidl::SetUp();
1608 GetProviderCapabilitiesHelper(
1609 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
1610 OpenProviderHelper(SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
1611 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
1612 audio_provider_ != nullptr);
1613 }
1614
1615 virtual void TearDown() override {
1616 audio_port_ = nullptr;
1617 audio_provider_ = nullptr;
1618 BluetoothAudioProviderFactoryAidl::TearDown();
1619 }
1620
1621 bool IsOffloadSupported() { return (temp_provider_capabilities_.size() > 0); }
1622};
1623
1624/**
1625 * Test whether we can open a provider of type
1626 */
1627TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1628 OpenA2dpEncodingHardwareProvider) {}
Josh Wu049e2cd2022-01-12 05:42:58 -08001629
1630/**
1631 * Test whether each provider of type
1632 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
1633 * SBC hardware encoding config
1634 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001635TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1636 StartAndEndA2dpSbcEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001637 if (!IsOffloadSupported()) {
1638 return;
1639 }
1640
1641 CodecConfiguration codec_config = {
1642 .codecType = CodecType::SBC,
1643 .encodedAudioBitrate = 328000,
1644 .peerMtu = 1005,
1645 .isScmstEnabled = false,
1646 };
1647 auto sbc_codec_specifics = GetSbcCodecSpecificSupportedList(true);
1648
1649 for (auto& codec_specific : sbc_codec_specifics) {
1650 copy_codec_specific(codec_config.config, codec_specific);
1651 DataMQDesc mq_desc;
1652 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001653 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001654
1655 ASSERT_TRUE(aidl_retval.isOk());
1656 EXPECT_TRUE(audio_provider_->endSession().isOk());
1657 }
1658}
1659
1660/**
1661 * Test whether each provider of type
1662 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
1663 * AAC hardware encoding config
1664 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001665TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1666 StartAndEndA2dpAacEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001667 if (!IsOffloadSupported()) {
1668 return;
1669 }
1670
1671 CodecConfiguration codec_config = {
1672 .codecType = CodecType::AAC,
1673 .encodedAudioBitrate = 320000,
1674 .peerMtu = 1005,
1675 .isScmstEnabled = false,
1676 };
1677 auto aac_codec_specifics = GetAacCodecSpecificSupportedList(true);
1678
1679 for (auto& codec_specific : aac_codec_specifics) {
1680 copy_codec_specific(codec_config.config, codec_specific);
1681 DataMQDesc mq_desc;
1682 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001683 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001684
1685 ASSERT_TRUE(aidl_retval.isOk());
1686 EXPECT_TRUE(audio_provider_->endSession().isOk());
1687 }
1688}
1689
1690/**
1691 * Test whether each provider of type
1692 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
1693 * LDAC hardware encoding config
1694 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001695TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1696 StartAndEndA2dpLdacEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001697 if (!IsOffloadSupported()) {
1698 return;
1699 }
1700
1701 CodecConfiguration codec_config = {
1702 .codecType = CodecType::LDAC,
1703 .encodedAudioBitrate = 990000,
1704 .peerMtu = 1005,
1705 .isScmstEnabled = false,
1706 };
1707 auto ldac_codec_specifics = GetLdacCodecSpecificSupportedList(true);
1708
1709 for (auto& codec_specific : ldac_codec_specifics) {
1710 copy_codec_specific(codec_config.config, codec_specific);
1711 DataMQDesc mq_desc;
1712 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001713 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001714
1715 ASSERT_TRUE(aidl_retval.isOk());
1716 EXPECT_TRUE(audio_provider_->endSession().isOk());
1717 }
1718}
1719
1720/**
1721 * Test whether each provider of type
1722 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
Omer Osmana2587da2022-05-01 03:54:11 +00001723 * Opus hardware encoding config
Josh Wu049e2cd2022-01-12 05:42:58 -08001724 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001725TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
Omer Osmana2587da2022-05-01 03:54:11 +00001726 StartAndEndA2dpOpusEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001727 if (!IsOffloadSupported()) {
1728 return;
1729 }
1730
1731 CodecConfiguration codec_config = {
Omer Osmana2587da2022-05-01 03:54:11 +00001732 .codecType = CodecType::OPUS,
Josh Wu049e2cd2022-01-12 05:42:58 -08001733 .encodedAudioBitrate = 990000,
1734 .peerMtu = 1005,
1735 .isScmstEnabled = false,
1736 };
Omer Osmana2587da2022-05-01 03:54:11 +00001737 auto opus_codec_specifics = GetOpusCodecSpecificSupportedList(true);
Josh Wu049e2cd2022-01-12 05:42:58 -08001738
Omer Osmana2587da2022-05-01 03:54:11 +00001739 for (auto& codec_specific : opus_codec_specifics) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001740 copy_codec_specific(codec_config.config, codec_specific);
1741 DataMQDesc mq_desc;
1742 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001743 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001744
1745 ASSERT_TRUE(aidl_retval.isOk());
1746 EXPECT_TRUE(audio_provider_->endSession().isOk());
1747 }
1748}
1749
1750/**
1751 * Test whether each provider of type
1752 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
1753 * AptX hardware encoding config
1754 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001755TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1756 StartAndEndA2dpAptxEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001757 if (!IsOffloadSupported()) {
1758 return;
1759 }
1760
1761 for (auto codec_type : {CodecType::APTX, CodecType::APTX_HD}) {
1762 CodecConfiguration codec_config = {
1763 .codecType = codec_type,
1764 .encodedAudioBitrate =
1765 (codec_type == CodecType::APTX ? 352000 : 576000),
1766 .peerMtu = 1005,
1767 .isScmstEnabled = false,
1768 };
1769
1770 auto aptx_codec_specifics = GetAptxCodecSpecificSupportedList(
1771 (codec_type == CodecType::APTX_HD ? true : false), true);
1772
1773 for (auto& codec_specific : aptx_codec_specifics) {
1774 copy_codec_specific(codec_config.config, codec_specific);
1775 DataMQDesc mq_desc;
1776 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001777 audio_port_, AudioConfiguration(codec_config), latency_modes,
1778 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001779
1780 ASSERT_TRUE(aidl_retval.isOk());
1781 EXPECT_TRUE(audio_provider_->endSession().isOk());
1782 }
1783 }
1784}
1785
1786/**
1787 * Test whether each provider of type
1788 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
1789 * an invalid codec config
1790 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001791TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1792 StartAndEndA2dpEncodingHardwareSessionInvalidCodecConfig) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001793 if (!IsOffloadSupported()) {
1794 return;
1795 }
1796 ASSERT_NE(audio_provider_, nullptr);
1797
1798 std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
Sagar Verma62df9102022-12-07 17:56:04 +05301799 for (auto codec_type : ndk::enum_range<CodecType>()) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001800 switch (codec_type) {
1801 case CodecType::SBC:
1802 codec_specifics = GetSbcCodecSpecificSupportedList(false);
1803 break;
1804 case CodecType::AAC:
1805 codec_specifics = GetAacCodecSpecificSupportedList(false);
1806 break;
1807 case CodecType::LDAC:
1808 codec_specifics = GetLdacCodecSpecificSupportedList(false);
1809 break;
1810 case CodecType::APTX:
1811 codec_specifics = GetAptxCodecSpecificSupportedList(false, false);
1812 break;
1813 case CodecType::APTX_HD:
1814 codec_specifics = GetAptxCodecSpecificSupportedList(true, false);
1815 break;
Omer Osmana2587da2022-05-01 03:54:11 +00001816 case CodecType::OPUS:
1817 codec_specifics = GetOpusCodecSpecificSupportedList(false);
Josh Wu049e2cd2022-01-12 05:42:58 -08001818 continue;
1819 case CodecType::APTX_ADAPTIVE:
Sagar Verma62df9102022-12-07 17:56:04 +05301820 case CodecType::APTX_ADAPTIVE_LE:
1821 case CodecType::APTX_ADAPTIVE_LEX:
Omer Osmana2587da2022-05-01 03:54:11 +00001822 case CodecType::LC3:
Josh Wu049e2cd2022-01-12 05:42:58 -08001823 case CodecType::VENDOR:
1824 case CodecType::UNKNOWN:
1825 codec_specifics.clear();
1826 break;
1827 }
1828 if (codec_specifics.empty()) {
1829 continue;
1830 }
1831
1832 CodecConfiguration codec_config = {
1833 .codecType = codec_type,
1834 .encodedAudioBitrate = 328000,
1835 .peerMtu = 1005,
1836 .isScmstEnabled = false,
1837 };
1838 for (auto codec_specific : codec_specifics) {
1839 copy_codec_specific(codec_config.config, codec_specific);
1840 DataMQDesc mq_desc;
1841 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001842 audio_port_, AudioConfiguration(codec_config), latency_modes,
1843 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001844
1845 // AIDL call should fail on invalid codec
1846 ASSERT_FALSE(aidl_retval.isOk());
1847 EXPECT_TRUE(audio_provider_->endSession().isOk());
1848 }
1849 }
1850}
1851
1852/**
Bao Do72399432023-11-09 08:13:05 +00001853 * openProvider HFP_HARDWARE_OFFLOAD_DATAPATH
1854 */
1855class BluetoothAudioProviderHfpHardwareAidl
1856 : public BluetoothAudioProviderFactoryAidl {
1857 public:
1858 virtual void SetUp() override {
1859 BluetoothAudioProviderFactoryAidl::SetUp();
1860 OpenProviderHelper(SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH);
1861 // Can open or empty capability
1862 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
1863 audio_provider_ != nullptr);
1864 }
1865
1866 virtual void TearDown() override {
1867 audio_port_ = nullptr;
1868 audio_provider_ = nullptr;
1869 BluetoothAudioProviderFactoryAidl::TearDown();
1870 }
1871
1872 bool OpenSession(CodecId codec_id, int connection_handle, bool nrec,
1873 bool controller_codec) {
1874 // Check if can open session with a Hfp configuration
1875 HfpConfiguration hfp_configuration{
1876 .codecId = codec_id,
1877 .connectionHandle = connection_handle,
1878 .nrec = nrec,
1879 .controllerCodec = controller_codec,
1880 };
1881 DataMQDesc mq_desc;
1882 auto aidl_retval = audio_provider_->startSession(
1883 audio_port_, AudioConfiguration(hfp_configuration), latency_modes,
1884 &mq_desc);
1885
1886 // Only check if aidl is ok to start session.
1887 return aidl_retval.isOk();
1888 }
1889};
1890
1891/**
1892 * Test whether we can open a provider of type
1893 */
1894TEST_P(BluetoothAudioProviderHfpHardwareAidl, OpenHfpHardwareProvider) {}
1895
1896/**
1897 * Test whether each provider of type
1898 * SessionType::HFP_SOFTWARE_DECODING_DATAPATH can be started and stopped with
1899 * different HFP config
1900 */
1901TEST_P(BluetoothAudioProviderHfpHardwareAidl,
1902 StartAndEndHfpHardwareSessionWithPossiblePcmConfig) {
1903 // Try to open with a sample configuration
1904 EXPECT_TRUE(OpenSession(CodecId::Core::CVSD, 6, false, true));
1905 EXPECT_TRUE(audio_provider_->endSession().isOk());
1906}
1907
1908/**
Josh Wu049e2cd2022-01-12 05:42:58 -08001909 * openProvider HEARING_AID_SOFTWARE_ENCODING_DATAPATH
1910 */
1911class BluetoothAudioProviderHearingAidSoftwareAidl
1912 : public BluetoothAudioProviderFactoryAidl {
1913 public:
1914 virtual void SetUp() override {
1915 BluetoothAudioProviderFactoryAidl::SetUp();
1916 GetProviderCapabilitiesHelper(
1917 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
1918 OpenProviderHelper(SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
1919 ASSERT_NE(audio_provider_, nullptr);
1920 }
1921
1922 virtual void TearDown() override {
1923 audio_port_ = nullptr;
1924 audio_provider_ = nullptr;
1925 BluetoothAudioProviderFactoryAidl::TearDown();
1926 }
1927
1928 static constexpr int32_t hearing_aid_sample_rates_[] = {0, 16000, 24000};
1929 static constexpr int8_t hearing_aid_bits_per_samples_[] = {0, 16, 24};
1930 static constexpr ChannelMode hearing_aid_channel_modes_[] = {
1931 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
1932};
1933
1934/**
1935 * Test whether we can open a provider of type
1936 */
1937TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl,
1938 OpenHearingAidSoftwareProvider) {}
1939
1940/**
1941 * Test whether each provider of type
1942 * SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH can be started and
1943 * stopped with different PCM config
1944 */
1945TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl,
1946 StartAndEndHearingAidSessionWithPossiblePcmConfig) {
1947 for (int32_t sample_rate : hearing_aid_sample_rates_) {
1948 for (int8_t bits_per_sample : hearing_aid_bits_per_samples_) {
1949 for (auto channel_mode : hearing_aid_channel_modes_) {
1950 PcmConfiguration pcm_config{
1951 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08001952 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00001953 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08001954 };
1955 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
1956 DataMQDesc mq_desc;
1957 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001958 audio_port_, AudioConfiguration(pcm_config), latency_modes,
1959 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001960 DataMQ data_mq(mq_desc);
1961
1962 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
1963 if (is_codec_config_valid) {
1964 EXPECT_TRUE(data_mq.isValid());
1965 }
1966 EXPECT_TRUE(audio_provider_->endSession().isOk());
1967 }
1968 }
1969 }
1970}
1971
1972/**
1973 * openProvider LE_AUDIO_SOFTWARE_ENCODING_DATAPATH
1974 */
1975class BluetoothAudioProviderLeAudioOutputSoftwareAidl
1976 : public BluetoothAudioProviderFactoryAidl {
1977 public:
1978 virtual void SetUp() override {
1979 BluetoothAudioProviderFactoryAidl::SetUp();
1980 GetProviderCapabilitiesHelper(
1981 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
1982 OpenProviderHelper(SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
1983 ASSERT_NE(audio_provider_, nullptr);
1984 }
1985
1986 virtual void TearDown() override {
1987 audio_port_ = nullptr;
1988 audio_provider_ = nullptr;
1989 BluetoothAudioProviderFactoryAidl::TearDown();
1990 }
1991
1992 static constexpr int32_t le_audio_output_sample_rates_[] = {
1993 0, 8000, 16000, 24000, 32000, 44100, 48000,
1994 };
1995 static constexpr int8_t le_audio_output_bits_per_samples_[] = {0, 16, 24};
1996 static constexpr ChannelMode le_audio_output_channel_modes_[] = {
1997 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
1998 static constexpr int32_t le_audio_output_data_interval_us_[] = {
1999 0 /* Invalid */, 10000 /* Valid 10ms */};
2000};
2001
2002/**
2003 * Test whether each provider of type
2004 * SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH can be started and
2005 * stopped
2006 */
2007TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl,
2008 OpenLeAudioOutputSoftwareProvider) {}
2009
2010/**
2011 * Test whether each provider of type
2012 * SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH can be started and
2013 * stopped with different PCM config
2014 */
2015TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl,
2016 StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
2017 for (auto sample_rate : le_audio_output_sample_rates_) {
2018 for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
2019 for (auto channel_mode : le_audio_output_channel_modes_) {
2020 for (auto data_interval_us : le_audio_output_data_interval_us_) {
2021 PcmConfiguration pcm_config{
2022 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08002023 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00002024 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08002025 .dataIntervalUs = data_interval_us,
2026 };
Josh Wu8a1be762022-02-15 09:37:29 -08002027 bool is_codec_config_valid =
2028 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
Josh Wu049e2cd2022-01-12 05:42:58 -08002029 DataMQDesc mq_desc;
2030 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002031 audio_port_, AudioConfiguration(pcm_config), latency_modes,
2032 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002033 DataMQ data_mq(mq_desc);
2034
2035 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
2036 if (is_codec_config_valid) {
2037 EXPECT_TRUE(data_mq.isValid());
2038 }
2039 EXPECT_TRUE(audio_provider_->endSession().isOk());
2040 }
2041 }
2042 }
2043 }
2044}
2045
2046/**
Alice Kuo04a399a2022-02-16 09:19:56 +08002047 * openProvider LE_AUDIO_SOFTWARE_DECODING_DATAPATH
Josh Wu049e2cd2022-01-12 05:42:58 -08002048 */
2049class BluetoothAudioProviderLeAudioInputSoftwareAidl
2050 : public BluetoothAudioProviderFactoryAidl {
2051 public:
2052 virtual void SetUp() override {
2053 BluetoothAudioProviderFactoryAidl::SetUp();
2054 GetProviderCapabilitiesHelper(
2055 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH);
2056 OpenProviderHelper(SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH);
2057 ASSERT_NE(audio_provider_, nullptr);
2058 }
2059
2060 virtual void TearDown() override {
2061 audio_port_ = nullptr;
2062 audio_provider_ = nullptr;
2063 BluetoothAudioProviderFactoryAidl::TearDown();
2064 }
2065
2066 static constexpr int32_t le_audio_input_sample_rates_[] = {
2067 0, 8000, 16000, 24000, 32000, 44100, 48000};
2068 static constexpr int8_t le_audio_input_bits_per_samples_[] = {0, 16, 24};
2069 static constexpr ChannelMode le_audio_input_channel_modes_[] = {
2070 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
2071 static constexpr int32_t le_audio_input_data_interval_us_[] = {
2072 0 /* Invalid */, 10000 /* Valid 10ms */};
2073};
2074
2075/**
2076 * Test whether each provider of type
Alice Kuo04a399a2022-02-16 09:19:56 +08002077 * SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002078 * stopped
2079 */
2080TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl,
2081 OpenLeAudioInputSoftwareProvider) {}
2082
2083/**
2084 * Test whether each provider of type
Alice Kuo04a399a2022-02-16 09:19:56 +08002085 * SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002086 * stopped with different PCM config
2087 */
2088TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl,
2089 StartAndEndLeAudioInputSessionWithPossiblePcmConfig) {
2090 for (auto sample_rate : le_audio_input_sample_rates_) {
2091 for (auto bits_per_sample : le_audio_input_bits_per_samples_) {
2092 for (auto channel_mode : le_audio_input_channel_modes_) {
2093 for (auto data_interval_us : le_audio_input_data_interval_us_) {
2094 PcmConfiguration pcm_config{
2095 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08002096 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00002097 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08002098 .dataIntervalUs = data_interval_us,
2099 };
Josh Wu8a1be762022-02-15 09:37:29 -08002100 bool is_codec_config_valid =
2101 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
Josh Wu049e2cd2022-01-12 05:42:58 -08002102 DataMQDesc mq_desc;
2103 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002104 audio_port_, AudioConfiguration(pcm_config), latency_modes,
2105 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002106 DataMQ data_mq(mq_desc);
2107
2108 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
2109 if (is_codec_config_valid) {
2110 EXPECT_TRUE(data_mq.isValid());
2111 }
2112 EXPECT_TRUE(audio_provider_->endSession().isOk());
2113 }
2114 }
2115 }
2116 }
2117}
2118
2119/**
Alice Kuo04a399a2022-02-16 09:19:56 +08002120 * openProvider LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH
Josh Wu049e2cd2022-01-12 05:42:58 -08002121 */
2122class BluetoothAudioProviderLeAudioOutputHardwareAidl
2123 : public BluetoothAudioProviderFactoryAidl {
2124 public:
2125 virtual void SetUp() override {
2126 BluetoothAudioProviderFactoryAidl::SetUp();
2127 GetProviderCapabilitiesHelper(
2128 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
2129 OpenProviderHelper(
2130 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
2131 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
2132 audio_provider_ != nullptr);
2133 }
2134
2135 virtual void TearDown() override {
2136 audio_port_ = nullptr;
2137 audio_provider_ = nullptr;
2138 BluetoothAudioProviderFactoryAidl::TearDown();
2139 }
2140
2141 bool IsOffloadOutputSupported() {
2142 for (auto& capability : temp_provider_capabilities_) {
2143 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2144 continue;
2145 }
2146 auto& le_audio_capability =
2147 capability.get<AudioCapabilities::leAudioCapabilities>();
2148 if (le_audio_capability.unicastEncodeCapability.codecType !=
2149 CodecType::UNKNOWN)
2150 return true;
2151 }
2152 return false;
2153 }
2154
2155 std::vector<Lc3Configuration> GetUnicastLc3SupportedList(bool decoding,
2156 bool supported) {
2157 std::vector<Lc3Configuration> le_audio_codec_configs;
2158 if (!supported) {
shihchienc3ab9f5e2022-09-23 08:18:05 +00002159 Lc3Configuration lc3_config{.pcmBitDepth = 0, .samplingFrequencyHz = 0};
Josh Wu049e2cd2022-01-12 05:42:58 -08002160 le_audio_codec_configs.push_back(lc3_config);
2161 return le_audio_codec_configs;
2162 }
2163
2164 // There might be more than one LeAudioCodecCapabilitiesSetting
2165 std::vector<Lc3Capabilities> lc3_capabilities;
2166 for (auto& capability : temp_provider_capabilities_) {
2167 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2168 continue;
2169 }
2170 auto& le_audio_capability =
2171 capability.get<AudioCapabilities::leAudioCapabilities>();
2172 auto& unicast_capability =
2173 decoding ? le_audio_capability.unicastDecodeCapability
2174 : le_audio_capability.unicastEncodeCapability;
2175 if (unicast_capability.codecType != CodecType::LC3) {
2176 continue;
2177 }
2178 auto& lc3_capability = unicast_capability.leAudioCodecCapabilities.get<
2179 UnicastCapability::LeAudioCodecCapabilities::lc3Capabilities>();
2180 lc3_capabilities.push_back(lc3_capability);
2181 }
2182
2183 // Combine those parameters into one list of LeAudioCodecConfiguration
2184 // This seems horrible, but usually each Lc3Capability only contains a
2185 // single Lc3Configuration, which means every array has a length of 1.
2186 for (auto& lc3_capability : lc3_capabilities) {
2187 for (int32_t samplingFrequencyHz : lc3_capability.samplingFrequencyHz) {
2188 for (int32_t frameDurationUs : lc3_capability.frameDurationUs) {
2189 for (int32_t octetsPerFrame : lc3_capability.octetsPerFrame) {
2190 Lc3Configuration lc3_config = {
2191 .samplingFrequencyHz = samplingFrequencyHz,
2192 .frameDurationUs = frameDurationUs,
2193 .octetsPerFrame = octetsPerFrame,
2194 };
2195 le_audio_codec_configs.push_back(lc3_config);
2196 }
2197 }
2198 }
2199 }
2200
2201 return le_audio_codec_configs;
2202 }
2203
Sagar Verma62df9102022-12-07 17:56:04 +05302204 static constexpr int32_t apx_adaptive_le_config_codec_modes[] = {0, 1, 2, 3};
2205
2206 std::vector<AptxAdaptiveLeConfiguration>
2207 GetUnicastAptxAdaptiveLeSupportedList(bool decoding, bool supported,
2208 bool is_le_extended) {
2209 std::vector<AptxAdaptiveLeConfiguration> le_audio_codec_configs;
2210 if (!supported) {
2211 AptxAdaptiveLeConfiguration aptx_adaptive_le_config{
2212 .pcmBitDepth = 0, .samplingFrequencyHz = 0};
2213 le_audio_codec_configs.push_back(aptx_adaptive_le_config);
2214 return le_audio_codec_configs;
2215 }
2216
2217 // There might be more than one LeAudioCodecCapabilitiesSetting
2218 std::vector<AptxAdaptiveLeCapabilities> aptx_adaptive_le_capabilities;
2219 for (auto& capability : temp_provider_capabilities_) {
2220 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2221 continue;
2222 }
2223 auto& le_audio_capability =
2224 capability.get<AudioCapabilities::leAudioCapabilities>();
2225 auto& unicast_capability =
2226 decoding ? le_audio_capability.unicastDecodeCapability
2227 : le_audio_capability.unicastEncodeCapability;
2228 if ((!is_le_extended &&
2229 unicast_capability.codecType != CodecType::APTX_ADAPTIVE_LE) ||
2230 (is_le_extended &&
2231 unicast_capability.codecType != CodecType::APTX_ADAPTIVE_LEX)) {
2232 continue;
2233 }
2234
2235 auto& aptx_adaptive_le_capability =
2236 unicast_capability.leAudioCodecCapabilities
2237 .get<UnicastCapability::LeAudioCodecCapabilities::
2238 aptxAdaptiveLeCapabilities>();
2239
2240 aptx_adaptive_le_capabilities.push_back(aptx_adaptive_le_capability);
2241 }
2242
2243 for (auto& aptx_adaptive_le_capability : aptx_adaptive_le_capabilities) {
2244 for (int32_t samplingFrequencyHz :
2245 aptx_adaptive_le_capability.samplingFrequencyHz) {
2246 for (int32_t frameDurationUs :
2247 aptx_adaptive_le_capability.frameDurationUs) {
2248 for (int32_t octetsPerFrame :
2249 aptx_adaptive_le_capability.octetsPerFrame) {
2250 for (int8_t blocksPerSdu :
2251 aptx_adaptive_le_capability.blocksPerSdu) {
2252 for (int32_t codecMode : apx_adaptive_le_config_codec_modes) {
2253 AptxAdaptiveLeConfiguration aptx_adaptive_le_config = {
2254 .samplingFrequencyHz = samplingFrequencyHz,
2255 .frameDurationUs = frameDurationUs,
2256 .octetsPerFrame = octetsPerFrame,
2257 .blocksPerSdu = blocksPerSdu,
2258 .codecMode = codecMode,
2259 };
2260 le_audio_codec_configs.push_back(aptx_adaptive_le_config);
2261 }
2262 }
2263 }
2264 }
2265 }
2266 }
2267
2268 return le_audio_codec_configs;
2269 }
2270
Josh Wu049e2cd2022-01-12 05:42:58 -08002271 LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
2272};
2273
2274/**
2275 * Test whether each provider of type
2276 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2277 * stopped
2278 */
2279TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2280 OpenLeAudioOutputHardwareProvider) {}
2281
2282/**
2283 * Test whether each provider of type
2284 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2285 * stopped with Unicast hardware encoding config
2286 */
2287TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2288 StartAndEndLeAudioOutputSessionWithPossibleUnicastConfig) {
2289 if (!IsOffloadOutputSupported()) {
2290 return;
2291 }
2292
2293 auto lc3_codec_configs =
2294 GetUnicastLc3SupportedList(false /* decoding */, true /* supported */);
2295 LeAudioConfiguration le_audio_config = {
2296 .codecType = CodecType::LC3,
2297 .peerDelayUs = 0,
2298 };
2299
2300 for (auto& lc3_config : lc3_codec_configs) {
2301 le_audio_config.leAudioCodecConfig
2302 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2303 DataMQDesc mq_desc;
2304 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002305 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2306 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002307
2308 ASSERT_TRUE(aidl_retval.isOk());
2309 EXPECT_TRUE(audio_provider_->endSession().isOk());
2310 }
2311}
2312
2313/**
2314 * Test whether each provider of type
2315 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2316 * stopped with Unicast hardware encoding config
2317 *
2318 * Disabled since offload codec checking is not ready
2319 */
2320TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2321 DISABLED_StartAndEndLeAudioOutputSessionWithInvalidAudioConfiguration) {
2322 if (!IsOffloadOutputSupported()) {
2323 return;
2324 }
2325
2326 auto lc3_codec_configs =
2327 GetUnicastLc3SupportedList(false /* decoding */, false /* supported */);
2328 LeAudioConfiguration le_audio_config = {
2329 .codecType = CodecType::LC3,
2330 .peerDelayUs = 0,
2331 };
2332
2333 for (auto& lc3_config : lc3_codec_configs) {
2334 le_audio_config.leAudioCodecConfig
2335 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2336 DataMQDesc mq_desc;
2337 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002338 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2339 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002340
2341 // AIDL call should fail on invalid codec
2342 ASSERT_FALSE(aidl_retval.isOk());
2343 EXPECT_TRUE(audio_provider_->endSession().isOk());
2344 }
2345}
2346
Sagar Verma62df9102022-12-07 17:56:04 +05302347static std::vector<uint8_t> vendorMetadata = {0x0B, // Length
2348 0xFF, // Type: Vendor-specific
2349 0x0A, 0x00, // Company_ID
2350 0x01, 0x02, 0x03, 0x04, // Data
2351 0x05, 0x06, 0x07, 0x08};
2352
2353/**
2354 * Test whether each provider of type
2355 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2356 * stopped with Unicast hardware encoding config
2357 */
2358TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2359 StartAndEndLeAudioOutputSessionWithAptxAdaptiveLeUnicastConfig) {
2360 if (!IsOffloadOutputSupported()) {
2361 return;
2362 }
2363 for (auto codec_type :
2364 {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
2365 bool is_le_extended = (codec_type == CodecType::APTX_ADAPTIVE_LEX);
2366 auto aptx_adaptive_le_codec_configs =
2367 GetUnicastAptxAdaptiveLeSupportedList(false, true, is_le_extended);
2368 LeAudioConfiguration le_audio_config = {
2369 .codecType = codec_type,
2370 .peerDelayUs = 0,
2371 .vendorSpecificMetadata = vendorMetadata,
2372 };
2373
2374 for (auto& aptx_adaptive_le_config : aptx_adaptive_le_codec_configs) {
2375 le_audio_config.leAudioCodecConfig
2376 .set<LeAudioCodecConfiguration::aptxAdaptiveLeConfig>(
2377 aptx_adaptive_le_config);
2378 DataMQDesc mq_desc;
2379 auto aidl_retval = audio_provider_->startSession(
2380 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2381 &mq_desc);
2382
2383 ASSERT_TRUE(aidl_retval.isOk());
2384 EXPECT_TRUE(audio_provider_->endSession().isOk());
2385 }
2386 }
2387}
2388
2389/**
2390 * Test whether each provider of type
2391 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2392 * stopped with Unicast hardware encoding config
2393 */
2394TEST_P(
2395 BluetoothAudioProviderLeAudioOutputHardwareAidl,
2396 BluetoothAudioProviderLeAudioOutputHardwareAidl_StartAndEndLeAudioOutputSessionWithInvalidAptxAdaptiveLeAudioConfiguration) {
2397 if (!IsOffloadOutputSupported()) {
2398 return;
2399 }
2400
2401 for (auto codec_type :
2402 {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
2403 bool is_le_extended = (codec_type == CodecType::APTX_ADAPTIVE_LEX);
2404 auto aptx_adaptive_le_codec_configs =
2405 GetUnicastAptxAdaptiveLeSupportedList(false, true, is_le_extended);
2406 LeAudioConfiguration le_audio_config = {
2407 .codecType = codec_type,
2408 .peerDelayUs = 0,
2409 .vendorSpecificMetadata = vendorMetadata,
2410 };
2411
2412 for (auto& aptx_adaptive_le_config : aptx_adaptive_le_codec_configs) {
2413 le_audio_config.leAudioCodecConfig
2414 .set<LeAudioCodecConfiguration::aptxAdaptiveLeConfig>(
2415 aptx_adaptive_le_config);
2416 DataMQDesc mq_desc;
2417 auto aidl_retval = audio_provider_->startSession(
2418 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2419 &mq_desc);
2420
2421 // AIDL call should fail on invalid codec
2422 ASSERT_FALSE(aidl_retval.isOk());
2423 EXPECT_TRUE(audio_provider_->endSession().isOk());
2424 }
2425 }
2426}
2427
Josh Wu049e2cd2022-01-12 05:42:58 -08002428/**
2429 * openProvider LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH
2430 */
2431class BluetoothAudioProviderLeAudioInputHardwareAidl
2432 : public BluetoothAudioProviderLeAudioOutputHardwareAidl {
2433 public:
2434 virtual void SetUp() override {
2435 BluetoothAudioProviderFactoryAidl::SetUp();
2436 GetProviderCapabilitiesHelper(
2437 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
2438 OpenProviderHelper(
2439 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
2440 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
2441 audio_provider_ != nullptr);
2442 }
2443
2444 bool IsOffloadInputSupported() {
2445 for (auto& capability : temp_provider_capabilities_) {
2446 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2447 continue;
2448 }
2449 auto& le_audio_capability =
2450 capability.get<AudioCapabilities::leAudioCapabilities>();
2451 if (le_audio_capability.unicastDecodeCapability.codecType !=
2452 CodecType::UNKNOWN)
2453 return true;
2454 }
2455 return false;
2456 }
2457
2458 virtual void TearDown() override {
2459 audio_port_ = nullptr;
2460 audio_provider_ = nullptr;
2461 BluetoothAudioProviderFactoryAidl::TearDown();
2462 }
2463};
2464
2465/**
2466 * Test whether each provider of type
2467 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2468 * stopped
2469 */
2470TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
2471 OpenLeAudioInputHardwareProvider) {}
2472
2473/**
2474 * Test whether each provider of type
2475 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2476 * stopped with Unicast hardware encoding config
2477 */
2478TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
2479 StartAndEndLeAudioInputSessionWithPossibleUnicastConfig) {
2480 if (!IsOffloadInputSupported()) {
2481 return;
2482 }
2483
2484 auto lc3_codec_configs =
2485 GetUnicastLc3SupportedList(true /* decoding */, true /* supported */);
2486 LeAudioConfiguration le_audio_config = {
2487 .codecType = CodecType::LC3,
2488 .peerDelayUs = 0,
2489 };
2490
2491 for (auto& lc3_config : lc3_codec_configs) {
2492 le_audio_config.leAudioCodecConfig
2493 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2494 DataMQDesc mq_desc;
2495 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002496 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2497 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002498
2499 ASSERT_TRUE(aidl_retval.isOk());
2500 EXPECT_TRUE(audio_provider_->endSession().isOk());
2501 }
2502}
2503
2504/**
2505 * Test whether each provider of type
2506 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2507 * stopped with Unicast hardware encoding config
2508 *
2509 * Disabled since offload codec checking is not ready
2510 */
2511TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
2512 DISABLED_StartAndEndLeAudioInputSessionWithInvalidAudioConfiguration) {
2513 if (!IsOffloadInputSupported()) {
2514 return;
2515 }
2516
2517 auto lc3_codec_configs =
2518 GetUnicastLc3SupportedList(true /* decoding */, false /* supported */);
2519 LeAudioConfiguration le_audio_config = {
2520 .codecType = CodecType::LC3,
2521 .peerDelayUs = 0,
2522 };
2523
2524 for (auto& lc3_config : lc3_codec_configs) {
2525 le_audio_config.leAudioCodecConfig
2526 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2527
2528 DataMQDesc mq_desc;
2529 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002530 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2531 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002532
2533 // AIDL call should fail on invalid codec
2534 ASSERT_FALSE(aidl_retval.isOk());
2535 EXPECT_TRUE(audio_provider_->endSession().isOk());
2536 }
2537}
2538
2539/**
2540 * openProvider LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH
2541 */
2542class BluetoothAudioProviderLeAudioBroadcastSoftwareAidl
2543 : public BluetoothAudioProviderFactoryAidl {
2544 public:
2545 virtual void SetUp() override {
2546 BluetoothAudioProviderFactoryAidl::SetUp();
2547 GetProviderCapabilitiesHelper(
2548 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
2549 OpenProviderHelper(
2550 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
2551 ASSERT_NE(audio_provider_, nullptr);
2552 }
2553
2554 virtual void TearDown() override {
2555 audio_port_ = nullptr;
2556 audio_provider_ = nullptr;
2557 BluetoothAudioProviderFactoryAidl::TearDown();
2558 }
2559
2560 static constexpr int32_t le_audio_output_sample_rates_[] = {
2561 0, 8000, 16000, 24000, 32000, 44100, 48000,
2562 };
2563 static constexpr int8_t le_audio_output_bits_per_samples_[] = {0, 16, 24};
2564 static constexpr ChannelMode le_audio_output_channel_modes_[] = {
2565 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
2566 static constexpr int32_t le_audio_output_data_interval_us_[] = {
2567 0 /* Invalid */, 10000 /* Valid 10ms */};
2568};
2569
2570/**
2571 * Test whether each provider of type
2572 * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started and
2573 * stopped
2574 */
2575TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
Josh Wu3202eab2022-02-17 18:09:05 -08002576 OpenLeAudioOutputSoftwareProvider) {}
Josh Wu049e2cd2022-01-12 05:42:58 -08002577
2578/**
2579 * Test whether each provider of type
2580 * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started and
2581 * stopped with different PCM config
2582 */
2583TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
Josh Wu3202eab2022-02-17 18:09:05 -08002584 StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
Josh Wu049e2cd2022-01-12 05:42:58 -08002585 for (auto sample_rate : le_audio_output_sample_rates_) {
2586 for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
2587 for (auto channel_mode : le_audio_output_channel_modes_) {
2588 for (auto data_interval_us : le_audio_output_data_interval_us_) {
2589 PcmConfiguration pcm_config{
2590 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08002591 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00002592 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08002593 .dataIntervalUs = data_interval_us,
2594 };
Josh Wu8a1be762022-02-15 09:37:29 -08002595 bool is_codec_config_valid =
2596 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
Josh Wu049e2cd2022-01-12 05:42:58 -08002597 DataMQDesc mq_desc;
2598 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002599 audio_port_, AudioConfiguration(pcm_config), latency_modes,
2600 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002601 DataMQ data_mq(mq_desc);
2602
2603 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
2604 if (is_codec_config_valid) {
2605 EXPECT_TRUE(data_mq.isValid());
2606 }
2607 EXPECT_TRUE(audio_provider_->endSession().isOk());
2608 }
2609 }
2610 }
2611 }
2612}
2613
Alice Kuo336d90c2022-02-16 09:09:59 +08002614/**
2615 * openProvider LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH
2616 */
2617class BluetoothAudioProviderLeAudioBroadcastHardwareAidl
2618 : public BluetoothAudioProviderFactoryAidl {
2619 public:
2620 virtual void SetUp() override {
2621 BluetoothAudioProviderFactoryAidl::SetUp();
2622 GetProviderCapabilitiesHelper(
2623 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
2624 OpenProviderHelper(
2625 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
2626 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
2627 audio_provider_ != nullptr);
2628 }
2629
2630 virtual void TearDown() override {
2631 audio_port_ = nullptr;
2632 audio_provider_ = nullptr;
2633 BluetoothAudioProviderFactoryAidl::TearDown();
2634 }
2635
2636 bool IsBroadcastOffloadSupported() {
2637 for (auto& capability : temp_provider_capabilities_) {
2638 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2639 continue;
2640 }
2641 auto& le_audio_capability =
2642 capability.get<AudioCapabilities::leAudioCapabilities>();
2643 if (le_audio_capability.broadcastCapability.codecType !=
2644 CodecType::UNKNOWN)
2645 return true;
2646 }
2647 return false;
2648 }
2649
2650 std::vector<Lc3Configuration> GetBroadcastLc3SupportedList(bool supported) {
2651 std::vector<Lc3Configuration> le_audio_codec_configs;
2652 if (!supported) {
shihchienc3ab9f5e2022-09-23 08:18:05 +00002653 Lc3Configuration lc3_config{.pcmBitDepth = 0, .samplingFrequencyHz = 0};
Alice Kuo336d90c2022-02-16 09:09:59 +08002654 le_audio_codec_configs.push_back(lc3_config);
2655 return le_audio_codec_configs;
2656 }
2657
2658 // There might be more than one LeAudioCodecCapabilitiesSetting
2659 std::vector<Lc3Capabilities> lc3_capabilities;
2660 for (auto& capability : temp_provider_capabilities_) {
2661 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2662 continue;
2663 }
2664 auto& le_audio_capability =
2665 capability.get<AudioCapabilities::leAudioCapabilities>();
2666 auto& broadcast_capability = le_audio_capability.broadcastCapability;
2667 if (broadcast_capability.codecType != CodecType::LC3) {
2668 continue;
2669 }
2670 auto& lc3_capability = broadcast_capability.leAudioCodecCapabilities.get<
2671 BroadcastCapability::LeAudioCodecCapabilities::lc3Capabilities>();
2672 for (int idx = 0; idx < lc3_capability->size(); idx++)
2673 lc3_capabilities.push_back(*lc3_capability->at(idx));
2674 }
2675
2676 // Combine those parameters into one list of LeAudioCodecConfiguration
2677 // This seems horrible, but usually each Lc3Capability only contains a
2678 // single Lc3Configuration, which means every array has a length of 1.
2679 for (auto& lc3_capability : lc3_capabilities) {
2680 for (int32_t samplingFrequencyHz : lc3_capability.samplingFrequencyHz) {
2681 for (int32_t frameDurationUs : lc3_capability.frameDurationUs) {
2682 for (int32_t octetsPerFrame : lc3_capability.octetsPerFrame) {
2683 Lc3Configuration lc3_config = {
2684 .samplingFrequencyHz = samplingFrequencyHz,
2685 .frameDurationUs = frameDurationUs,
2686 .octetsPerFrame = octetsPerFrame,
2687 };
2688 le_audio_codec_configs.push_back(lc3_config);
2689 }
2690 }
2691 }
2692 }
2693
2694 return le_audio_codec_configs;
2695 }
2696
2697 LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
2698};
2699
2700/**
2701 * Test whether each provider of type
2702 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
2703 * started and stopped
2704 */
2705TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
2706 OpenLeAudioOutputHardwareProvider) {}
2707
2708/**
2709 * Test whether each provider of type
2710 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
2711 * started and stopped with broadcast hardware encoding config
2712 */
2713TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
2714 StartAndEndLeAudioBroadcastSessionWithPossibleBroadcastConfig) {
2715 if (!IsBroadcastOffloadSupported()) {
2716 return;
2717 }
2718
2719 auto lc3_codec_configs = GetBroadcastLc3SupportedList(true /* supported */);
2720 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
2721 .codecType = CodecType::LC3,
2722 .streamMap = {},
2723 };
2724
2725 for (auto& lc3_config : lc3_codec_configs) {
Patty Huangac077ef2022-11-23 14:45:15 +08002726 le_audio_broadcast_config.streamMap.resize(1);
Alice Kuo336d90c2022-02-16 09:09:59 +08002727 le_audio_broadcast_config.streamMap[0]
2728 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
2729 lc3_config);
Rongxuan Liuc1aea322023-01-26 17:14:54 +00002730 le_audio_broadcast_config.streamMap[0].streamHandle = 0x0;
2731 le_audio_broadcast_config.streamMap[0].pcmStreamId = 0x0;
2732 le_audio_broadcast_config.streamMap[0].audioChannelAllocation = 0x1 << 0;
2733
Alice Kuo336d90c2022-02-16 09:09:59 +08002734 DataMQDesc mq_desc;
2735 auto aidl_retval = audio_provider_->startSession(
Chen Chen60d52e42022-02-16 12:19:12 -08002736 audio_port_, AudioConfiguration(le_audio_broadcast_config),
2737 latency_modes, &mq_desc);
Alice Kuo336d90c2022-02-16 09:09:59 +08002738
2739 ASSERT_TRUE(aidl_retval.isOk());
2740 EXPECT_TRUE(audio_provider_->endSession().isOk());
2741 }
2742}
2743
2744/**
2745 * Test whether each provider of type
2746 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
2747 * started and stopped with Broadcast hardware encoding config
2748 *
2749 * Disabled since offload codec checking is not ready
2750 */
2751TEST_P(
2752 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
2753 DISABLED_StartAndEndLeAudioBroadcastSessionWithInvalidAudioConfiguration) {
2754 if (!IsBroadcastOffloadSupported()) {
2755 return;
2756 }
2757
2758 auto lc3_codec_configs = GetBroadcastLc3SupportedList(false /* supported */);
2759 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
2760 .codecType = CodecType::LC3,
2761 .streamMap = {},
2762 };
2763
2764 for (auto& lc3_config : lc3_codec_configs) {
2765 le_audio_broadcast_config.streamMap[0]
2766 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
2767 lc3_config);
2768 DataMQDesc mq_desc;
2769 auto aidl_retval = audio_provider_->startSession(
Chen Chen60d52e42022-02-16 12:19:12 -08002770 audio_port_, AudioConfiguration(le_audio_broadcast_config),
2771 latency_modes, &mq_desc);
Alice Kuo336d90c2022-02-16 09:09:59 +08002772
2773 // AIDL call should fail on invalid codec
2774 ASSERT_FALSE(aidl_retval.isOk());
2775 EXPECT_TRUE(audio_provider_->endSession().isOk());
2776 }
2777}
2778
Alice Kuoadcceec2022-03-28 13:28:43 +08002779/**
2780 * openProvider A2DP_SOFTWARE_DECODING_DATAPATH
2781 */
2782class BluetoothAudioProviderA2dpDecodingSoftwareAidl
2783 : public BluetoothAudioProviderFactoryAidl {
2784 public:
2785 virtual void SetUp() override {
2786 BluetoothAudioProviderFactoryAidl::SetUp();
2787 GetProviderCapabilitiesHelper(SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
2788 OpenProviderHelper(SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
2789 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
2790 audio_provider_ != nullptr);
2791 }
2792
2793 virtual void TearDown() override {
2794 audio_port_ = nullptr;
2795 audio_provider_ = nullptr;
2796 BluetoothAudioProviderFactoryAidl::TearDown();
2797 }
2798};
2799
2800/**
2801 * Test whether we can open a provider of type
2802 */
2803TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,
2804 OpenA2dpDecodingSoftwareProvider) {}
2805
2806/**
2807 * Test whether each provider of type
2808 * SessionType::A2DP_SOFTWARE_DECODING_DATAPATH can be started and stopped with
2809 * different PCM config
2810 */
2811TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,
2812 StartAndEndA2dpDecodingSoftwareSessionWithPossiblePcmConfig) {
2813 for (auto sample_rate : a2dp_sample_rates) {
2814 for (auto bits_per_sample : a2dp_bits_per_samples) {
2815 for (auto channel_mode : a2dp_channel_modes) {
2816 PcmConfiguration pcm_config{
2817 .sampleRateHz = sample_rate,
Alice Kuoadcceec2022-03-28 13:28:43 +08002818 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00002819 .bitsPerSample = bits_per_sample,
Alice Kuoadcceec2022-03-28 13:28:43 +08002820 };
2821 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
2822 DataMQDesc mq_desc;
2823 auto aidl_retval = audio_provider_->startSession(
2824 audio_port_, AudioConfiguration(pcm_config), latency_modes,
2825 &mq_desc);
2826 DataMQ data_mq(mq_desc);
2827
2828 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
2829 if (is_codec_config_valid) {
2830 EXPECT_TRUE(data_mq.isValid());
2831 }
2832 EXPECT_TRUE(audio_provider_->endSession().isOk());
2833 }
2834 }
2835 }
2836}
2837
2838/**
2839 * openProvider A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH
2840 */
2841class BluetoothAudioProviderA2dpDecodingHardwareAidl
2842 : public BluetoothAudioProviderFactoryAidl {
2843 public:
2844 virtual void SetUp() override {
2845 BluetoothAudioProviderFactoryAidl::SetUp();
2846 GetProviderCapabilitiesHelper(
2847 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
2848 OpenProviderHelper(SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
2849 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
2850 audio_provider_ != nullptr);
2851 }
2852
2853 virtual void TearDown() override {
2854 audio_port_ = nullptr;
2855 audio_provider_ = nullptr;
2856 BluetoothAudioProviderFactoryAidl::TearDown();
2857 }
2858
2859 bool IsOffloadSupported() { return (temp_provider_capabilities_.size() > 0); }
2860};
2861
2862/**
2863 * Test whether we can open a provider of type
2864 */
2865TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
2866 OpenA2dpDecodingHardwareProvider) {}
2867
2868/**
2869 * Test whether each provider of type
2870 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
2871 * SBC hardware encoding config
2872 */
2873TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
2874 StartAndEndA2dpSbcDecodingHardwareSession) {
2875 if (!IsOffloadSupported()) {
2876 return;
2877 }
2878
2879 CodecConfiguration codec_config = {
2880 .codecType = CodecType::SBC,
2881 .encodedAudioBitrate = 328000,
2882 .peerMtu = 1005,
2883 .isScmstEnabled = false,
2884 };
2885 auto sbc_codec_specifics = GetSbcCodecSpecificSupportedList(true);
2886
2887 for (auto& codec_specific : sbc_codec_specifics) {
2888 copy_codec_specific(codec_config.config, codec_specific);
2889 DataMQDesc mq_desc;
2890 auto aidl_retval = audio_provider_->startSession(
2891 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
2892
2893 ASSERT_TRUE(aidl_retval.isOk());
2894 EXPECT_TRUE(audio_provider_->endSession().isOk());
2895 }
2896}
2897
2898/**
2899 * Test whether each provider of type
2900 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
2901 * AAC hardware encoding config
2902 */
2903TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
2904 StartAndEndA2dpAacDecodingHardwareSession) {
2905 if (!IsOffloadSupported()) {
2906 return;
2907 }
2908
2909 CodecConfiguration codec_config = {
2910 .codecType = CodecType::AAC,
2911 .encodedAudioBitrate = 320000,
2912 .peerMtu = 1005,
2913 .isScmstEnabled = false,
2914 };
2915 auto aac_codec_specifics = GetAacCodecSpecificSupportedList(true);
2916
2917 for (auto& codec_specific : aac_codec_specifics) {
2918 copy_codec_specific(codec_config.config, codec_specific);
2919 DataMQDesc mq_desc;
2920 auto aidl_retval = audio_provider_->startSession(
2921 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
2922
2923 ASSERT_TRUE(aidl_retval.isOk());
2924 EXPECT_TRUE(audio_provider_->endSession().isOk());
2925 }
2926}
2927
2928/**
2929 * Test whether each provider of type
2930 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
2931 * LDAC hardware encoding config
2932 */
2933TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
2934 StartAndEndA2dpLdacDecodingHardwareSession) {
2935 if (!IsOffloadSupported()) {
2936 return;
2937 }
2938
2939 CodecConfiguration codec_config = {
2940 .codecType = CodecType::LDAC,
2941 .encodedAudioBitrate = 990000,
2942 .peerMtu = 1005,
2943 .isScmstEnabled = false,
2944 };
2945 auto ldac_codec_specifics = GetLdacCodecSpecificSupportedList(true);
2946
2947 for (auto& codec_specific : ldac_codec_specifics) {
2948 copy_codec_specific(codec_config.config, codec_specific);
2949 DataMQDesc mq_desc;
2950 auto aidl_retval = audio_provider_->startSession(
2951 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
2952
2953 ASSERT_TRUE(aidl_retval.isOk());
2954 EXPECT_TRUE(audio_provider_->endSession().isOk());
2955 }
2956}
2957
2958/**
2959 * Test whether each provider of type
2960 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
Omer Osmana2587da2022-05-01 03:54:11 +00002961 * Opus hardware encoding config
Alice Kuoadcceec2022-03-28 13:28:43 +08002962 */
2963TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
Omer Osmana2587da2022-05-01 03:54:11 +00002964 StartAndEndA2dpOpusDecodingHardwareSession) {
Alice Kuoadcceec2022-03-28 13:28:43 +08002965 if (!IsOffloadSupported()) {
2966 return;
2967 }
2968
2969 CodecConfiguration codec_config = {
Omer Osmana2587da2022-05-01 03:54:11 +00002970 .codecType = CodecType::OPUS,
Alice Kuoadcceec2022-03-28 13:28:43 +08002971 .encodedAudioBitrate = 990000,
2972 .peerMtu = 1005,
2973 .isScmstEnabled = false,
2974 };
Omer Osmana2587da2022-05-01 03:54:11 +00002975 auto opus_codec_specifics = GetOpusCodecSpecificSupportedList(true);
Alice Kuoadcceec2022-03-28 13:28:43 +08002976
Omer Osmana2587da2022-05-01 03:54:11 +00002977 for (auto& codec_specific : opus_codec_specifics) {
Alice Kuoadcceec2022-03-28 13:28:43 +08002978 copy_codec_specific(codec_config.config, codec_specific);
2979 DataMQDesc mq_desc;
2980 auto aidl_retval = audio_provider_->startSession(
2981 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
2982
2983 ASSERT_TRUE(aidl_retval.isOk());
2984 EXPECT_TRUE(audio_provider_->endSession().isOk());
2985 }
2986}
2987
2988/**
2989 * Test whether each provider of type
2990 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
2991 * AptX hardware encoding config
2992 */
2993TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
2994 StartAndEndA2dpAptxDecodingHardwareSession) {
2995 if (!IsOffloadSupported()) {
2996 return;
2997 }
2998
2999 for (auto codec_type : {CodecType::APTX, CodecType::APTX_HD}) {
3000 CodecConfiguration codec_config = {
3001 .codecType = codec_type,
3002 .encodedAudioBitrate =
3003 (codec_type == CodecType::APTX ? 352000 : 576000),
3004 .peerMtu = 1005,
3005 .isScmstEnabled = false,
3006 };
3007
3008 auto aptx_codec_specifics = GetAptxCodecSpecificSupportedList(
3009 (codec_type == CodecType::APTX_HD ? true : false), true);
3010
3011 for (auto& codec_specific : aptx_codec_specifics) {
3012 copy_codec_specific(codec_config.config, codec_specific);
3013 DataMQDesc mq_desc;
3014 auto aidl_retval = audio_provider_->startSession(
3015 audio_port_, AudioConfiguration(codec_config), latency_modes,
3016 &mq_desc);
3017
3018 ASSERT_TRUE(aidl_retval.isOk());
3019 EXPECT_TRUE(audio_provider_->endSession().isOk());
3020 }
3021 }
3022}
3023
3024/**
3025 * Test whether each provider of type
3026 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
3027 * an invalid codec config
3028 */
3029TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3030 StartAndEndA2dpDecodingHardwareSessionInvalidCodecConfig) {
3031 if (!IsOffloadSupported()) {
3032 return;
3033 }
3034 ASSERT_NE(audio_provider_, nullptr);
3035
3036 std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
Sagar Verma62df9102022-12-07 17:56:04 +05303037 for (auto codec_type : ndk::enum_range<CodecType>()) {
Alice Kuoadcceec2022-03-28 13:28:43 +08003038 switch (codec_type) {
3039 case CodecType::SBC:
3040 codec_specifics = GetSbcCodecSpecificSupportedList(false);
3041 break;
3042 case CodecType::AAC:
3043 codec_specifics = GetAacCodecSpecificSupportedList(false);
3044 break;
3045 case CodecType::LDAC:
3046 codec_specifics = GetLdacCodecSpecificSupportedList(false);
3047 break;
3048 case CodecType::APTX:
3049 codec_specifics = GetAptxCodecSpecificSupportedList(false, false);
3050 break;
3051 case CodecType::APTX_HD:
3052 codec_specifics = GetAptxCodecSpecificSupportedList(true, false);
3053 break;
Omer Osmana2587da2022-05-01 03:54:11 +00003054 case CodecType::OPUS:
3055 codec_specifics = GetOpusCodecSpecificSupportedList(false);
Alice Kuoadcceec2022-03-28 13:28:43 +08003056 continue;
3057 case CodecType::APTX_ADAPTIVE:
Sagar Verma62df9102022-12-07 17:56:04 +05303058 case CodecType::APTX_ADAPTIVE_LE:
3059 case CodecType::APTX_ADAPTIVE_LEX:
Omer Osmana2587da2022-05-01 03:54:11 +00003060 case CodecType::LC3:
Alice Kuoadcceec2022-03-28 13:28:43 +08003061 case CodecType::VENDOR:
3062 case CodecType::UNKNOWN:
3063 codec_specifics.clear();
3064 break;
3065 }
3066 if (codec_specifics.empty()) {
3067 continue;
3068 }
3069
3070 CodecConfiguration codec_config = {
3071 .codecType = codec_type,
3072 .encodedAudioBitrate = 328000,
3073 .peerMtu = 1005,
3074 .isScmstEnabled = false,
3075 };
3076 for (auto codec_specific : codec_specifics) {
3077 copy_codec_specific(codec_config.config, codec_specific);
3078 DataMQDesc mq_desc;
3079 auto aidl_retval = audio_provider_->startSession(
3080 audio_port_, AudioConfiguration(codec_config), latency_modes,
3081 &mq_desc);
3082
3083 // AIDL call should fail on invalid codec
3084 ASSERT_FALSE(aidl_retval.isOk());
3085 EXPECT_TRUE(audio_provider_->endSession().isOk());
3086 }
3087 }
3088}
3089
Josh Wu049e2cd2022-01-12 05:42:58 -08003090GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3091 BluetoothAudioProviderFactoryAidl);
3092INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderFactoryAidl,
3093 testing::ValuesIn(android::getAidlHalInstanceNames(
3094 IBluetoothAudioProviderFactory::descriptor)),
3095 android::PrintInstanceNameToString);
3096
Antoine SOULIER33c4e5a2023-09-28 21:59:19 +00003097GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothAudioProviderAidl);
3098INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderAidl,
3099 testing::ValuesIn(android::getAidlHalInstanceNames(
3100 IBluetoothAudioProviderFactory::descriptor)),
3101 android::PrintInstanceNameToString);
3102
Josh Wu049e2cd2022-01-12 05:42:58 -08003103GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
Alice Kuoadcceec2022-03-28 13:28:43 +08003104 BluetoothAudioProviderA2dpEncodingSoftwareAidl);
3105INSTANTIATE_TEST_SUITE_P(PerInstance,
3106 BluetoothAudioProviderA2dpEncodingSoftwareAidl,
Josh Wu049e2cd2022-01-12 05:42:58 -08003107 testing::ValuesIn(android::getAidlHalInstanceNames(
3108 IBluetoothAudioProviderFactory::descriptor)),
3109 android::PrintInstanceNameToString);
3110
3111GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
Alice Kuoadcceec2022-03-28 13:28:43 +08003112 BluetoothAudioProviderA2dpEncodingHardwareAidl);
3113INSTANTIATE_TEST_SUITE_P(PerInstance,
3114 BluetoothAudioProviderA2dpEncodingHardwareAidl,
Josh Wu049e2cd2022-01-12 05:42:58 -08003115 testing::ValuesIn(android::getAidlHalInstanceNames(
3116 IBluetoothAudioProviderFactory::descriptor)),
3117 android::PrintInstanceNameToString);
3118
3119GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3120 BluetoothAudioProviderHearingAidSoftwareAidl);
3121INSTANTIATE_TEST_SUITE_P(PerInstance,
3122 BluetoothAudioProviderHearingAidSoftwareAidl,
3123 testing::ValuesIn(android::getAidlHalInstanceNames(
3124 IBluetoothAudioProviderFactory::descriptor)),
3125 android::PrintInstanceNameToString);
3126
3127GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3128 BluetoothAudioProviderLeAudioOutputSoftwareAidl);
3129INSTANTIATE_TEST_SUITE_P(PerInstance,
3130 BluetoothAudioProviderLeAudioOutputSoftwareAidl,
3131 testing::ValuesIn(android::getAidlHalInstanceNames(
3132 IBluetoothAudioProviderFactory::descriptor)),
3133 android::PrintInstanceNameToString);
3134
3135GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3136 BluetoothAudioProviderLeAudioInputSoftwareAidl);
3137INSTANTIATE_TEST_SUITE_P(PerInstance,
3138 BluetoothAudioProviderLeAudioInputSoftwareAidl,
3139 testing::ValuesIn(android::getAidlHalInstanceNames(
3140 IBluetoothAudioProviderFactory::descriptor)),
3141 android::PrintInstanceNameToString);
3142
3143GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3144 BluetoothAudioProviderLeAudioOutputHardwareAidl);
3145INSTANTIATE_TEST_SUITE_P(PerInstance,
3146 BluetoothAudioProviderLeAudioOutputHardwareAidl,
3147 testing::ValuesIn(android::getAidlHalInstanceNames(
3148 IBluetoothAudioProviderFactory::descriptor)),
3149 android::PrintInstanceNameToString);
3150
3151GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3152 BluetoothAudioProviderLeAudioInputHardwareAidl);
3153INSTANTIATE_TEST_SUITE_P(PerInstance,
3154 BluetoothAudioProviderLeAudioInputHardwareAidl,
3155 testing::ValuesIn(android::getAidlHalInstanceNames(
3156 IBluetoothAudioProviderFactory::descriptor)),
3157 android::PrintInstanceNameToString);
3158
3159GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3160 BluetoothAudioProviderLeAudioBroadcastSoftwareAidl);
3161INSTANTIATE_TEST_SUITE_P(PerInstance,
3162 BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
3163 testing::ValuesIn(android::getAidlHalInstanceNames(
3164 IBluetoothAudioProviderFactory::descriptor)),
3165 android::PrintInstanceNameToString);
3166
Alice Kuo336d90c2022-02-16 09:09:59 +08003167GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3168 BluetoothAudioProviderLeAudioBroadcastHardwareAidl);
3169INSTANTIATE_TEST_SUITE_P(PerInstance,
3170 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3171 testing::ValuesIn(android::getAidlHalInstanceNames(
3172 IBluetoothAudioProviderFactory::descriptor)),
3173 android::PrintInstanceNameToString);
Josh Wu049e2cd2022-01-12 05:42:58 -08003174
Alice Kuoadcceec2022-03-28 13:28:43 +08003175GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3176 BluetoothAudioProviderA2dpDecodingSoftwareAidl);
3177INSTANTIATE_TEST_SUITE_P(PerInstance,
3178 BluetoothAudioProviderA2dpDecodingSoftwareAidl,
3179 testing::ValuesIn(android::getAidlHalInstanceNames(
3180 IBluetoothAudioProviderFactory::descriptor)),
3181 android::PrintInstanceNameToString);
3182
3183GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3184 BluetoothAudioProviderA2dpDecodingHardwareAidl);
3185INSTANTIATE_TEST_SUITE_P(PerInstance,
3186 BluetoothAudioProviderA2dpDecodingHardwareAidl,
3187 testing::ValuesIn(android::getAidlHalInstanceNames(
3188 IBluetoothAudioProviderFactory::descriptor)),
3189 android::PrintInstanceNameToString);
3190
Bao Do72399432023-11-09 08:13:05 +00003191GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3192 BluetoothAudioProviderHfpHardwareAidl);
3193INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderHfpHardwareAidl,
3194 testing::ValuesIn(android::getAidlHalInstanceNames(
3195 IBluetoothAudioProviderFactory::descriptor)),
3196 android::PrintInstanceNameToString);
3197
3198GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3199 BluetoothAudioProviderHfpSoftwareDecodingAidl);
3200INSTANTIATE_TEST_SUITE_P(PerInstance,
3201 BluetoothAudioProviderHfpSoftwareDecodingAidl,
3202 testing::ValuesIn(android::getAidlHalInstanceNames(
3203 IBluetoothAudioProviderFactory::descriptor)),
3204 android::PrintInstanceNameToString);
3205
3206GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3207 BluetoothAudioProviderHfpSoftwareEncodingAidl);
3208INSTANTIATE_TEST_SUITE_P(PerInstance,
3209 BluetoothAudioProviderHfpSoftwareEncodingAidl,
3210 testing::ValuesIn(android::getAidlHalInstanceNames(
3211 IBluetoothAudioProviderFactory::descriptor)),
3212 android::PrintInstanceNameToString);
3213
Josh Wu049e2cd2022-01-12 05:42:58 -08003214int main(int argc, char** argv) {
3215 ::testing::InitGoogleTest(&argc, argv);
3216 ABinderProcess_setThreadPoolMaxThreadCount(1);
3217 ABinderProcess_startThreadPool();
3218 return RUN_ALL_TESTS();
3219}