blob: be49a74b8a398f2c692f642db2273e465b95102c [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;
Bao Doc36897d2023-12-06 01:27:54 +000049using aidl::android::hardware::bluetooth::audio::AudioContext;
Josh Wu049e2cd2022-01-12 05:42:58 -080050using aidl::android::hardware::bluetooth::audio::BnBluetoothAudioPort;
Alice Kuo336d90c2022-02-16 09:09:59 +080051using aidl::android::hardware::bluetooth::audio::BroadcastCapability;
Josh Wu049e2cd2022-01-12 05:42:58 -080052using aidl::android::hardware::bluetooth::audio::ChannelMode;
53using aidl::android::hardware::bluetooth::audio::CodecCapabilities;
54using aidl::android::hardware::bluetooth::audio::CodecConfiguration;
Antoine SOULIER8c90f1f2023-09-26 18:55:17 +000055using aidl::android::hardware::bluetooth::audio::CodecId;
56using aidl::android::hardware::bluetooth::audio::CodecInfo;
Antoine SOULIER33c4e5a2023-09-28 21:59:19 +000057using aidl::android::hardware::bluetooth::audio::CodecParameters;
Bao Doc36897d2023-12-06 01:27:54 +000058using aidl::android::hardware::bluetooth::audio::CodecSpecificCapabilitiesLtv;
59using aidl::android::hardware::bluetooth::audio::CodecSpecificConfigurationLtv;
Josh Wu049e2cd2022-01-12 05:42:58 -080060using aidl::android::hardware::bluetooth::audio::CodecType;
Bao Do72399432023-11-09 08:13:05 +000061using aidl::android::hardware::bluetooth::audio::HfpConfiguration;
Josh Wu049e2cd2022-01-12 05:42:58 -080062using aidl::android::hardware::bluetooth::audio::IBluetoothAudioPort;
63using aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider;
64using aidl::android::hardware::bluetooth::audio::IBluetoothAudioProviderFactory;
65using aidl::android::hardware::bluetooth::audio::LatencyMode;
66using aidl::android::hardware::bluetooth::audio::Lc3Capabilities;
67using aidl::android::hardware::bluetooth::audio::Lc3Configuration;
68using aidl::android::hardware::bluetooth::audio::LdacCapabilities;
69using aidl::android::hardware::bluetooth::audio::LdacConfiguration;
Bao Doc36897d2023-12-06 01:27:54 +000070using aidl::android::hardware::bluetooth::audio::LeAudioAseConfiguration;
Alice Kuo336d90c2022-02-16 09:09:59 +080071using aidl::android::hardware::bluetooth::audio::LeAudioBroadcastConfiguration;
Josh Wu049e2cd2022-01-12 05:42:58 -080072using aidl::android::hardware::bluetooth::audio::
73 LeAudioCodecCapabilitiesSetting;
74using aidl::android::hardware::bluetooth::audio::LeAudioCodecConfiguration;
75using aidl::android::hardware::bluetooth::audio::LeAudioConfiguration;
Bao Doc36897d2023-12-06 01:27:54 +000076using aidl::android::hardware::bluetooth::audio::MetadataLtv;
Omer Osmana2587da2022-05-01 03:54:11 +000077using aidl::android::hardware::bluetooth::audio::OpusCapabilities;
78using aidl::android::hardware::bluetooth::audio::OpusConfiguration;
Josh Wu049e2cd2022-01-12 05:42:58 -080079using aidl::android::hardware::bluetooth::audio::PcmConfiguration;
80using aidl::android::hardware::bluetooth::audio::PresentationPosition;
81using aidl::android::hardware::bluetooth::audio::SbcAllocMethod;
82using aidl::android::hardware::bluetooth::audio::SbcCapabilities;
83using aidl::android::hardware::bluetooth::audio::SbcChannelMode;
84using aidl::android::hardware::bluetooth::audio::SbcConfiguration;
85using aidl::android::hardware::bluetooth::audio::SessionType;
86using aidl::android::hardware::bluetooth::audio::UnicastCapability;
87using aidl::android::hardware::common::fmq::MQDescriptor;
88using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
89using android::AidlMessageQueue;
90using android::ProcessState;
91using android::String16;
92using ndk::ScopedAStatus;
93using ndk::SpAIBinder;
94
95using MqDataType = int8_t;
96using MqDataMode = SynchronizedReadWrite;
97using DataMQ = AidlMessageQueue<MqDataType, MqDataMode>;
98using DataMQDesc = MQDescriptor<MqDataType, MqDataMode>;
99
Bao Doc36897d2023-12-06 01:27:54 +0000100using LeAudioAseConfigurationSetting =
101 IBluetoothAudioProvider::LeAudioAseConfigurationSetting;
102using AseDirectionRequirement = IBluetoothAudioProvider::
103 LeAudioConfigurationRequirement::AseDirectionRequirement;
104using AseDirectionConfiguration = IBluetoothAudioProvider::
105 LeAudioAseConfigurationSetting::AseDirectionConfiguration;
106using AseQosDirectionRequirement = IBluetoothAudioProvider::
107 LeAudioAseQosConfigurationRequirement::AseQosDirectionRequirement;
108using LeAudioAseQosConfiguration =
109 IBluetoothAudioProvider::LeAudioAseQosConfiguration;
110using LeAudioDeviceCapabilities =
111 IBluetoothAudioProvider::LeAudioDeviceCapabilities;
112using LeAudioConfigurationRequirement =
113 IBluetoothAudioProvider::LeAudioConfigurationRequirement;
114
Josh Wu049e2cd2022-01-12 05:42:58 -0800115// Constants
116
117static constexpr int32_t a2dp_sample_rates[] = {0, 44100, 48000, 88200, 96000};
118static constexpr int8_t a2dp_bits_per_samples[] = {0, 16, 24, 32};
119static constexpr ChannelMode a2dp_channel_modes[] = {
120 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
Chen Chenc92270e2022-02-14 18:29:52 -0800121static std::vector<LatencyMode> latency_modes = {LatencyMode::FREE};
Bao Do72399432023-11-09 08:13:05 +0000122
123// Some valid configs for HFP PCM configuration (software sessions)
124static constexpr int32_t hfp_sample_rates_[] = {8000, 16000, 32000};
125static constexpr int8_t hfp_bits_per_samples_[] = {16};
126static constexpr ChannelMode hfp_channel_modes_[] = {ChannelMode::MONO};
127static constexpr int32_t hfp_data_interval_us_[] = {7500};
128
Josh Wu049e2cd2022-01-12 05:42:58 -0800129// Helpers
130
131template <typename T>
132struct identity {
133 typedef T type;
134};
135
136template <class T>
137bool contained_in_vector(const std::vector<T>& vector,
138 const typename identity<T>::type& target) {
139 return std::find(vector.begin(), vector.end(), target) != vector.end();
140}
141
142void copy_codec_specific(CodecConfiguration::CodecSpecific& dst,
143 const CodecConfiguration::CodecSpecific& src) {
144 switch (src.getTag()) {
145 case CodecConfiguration::CodecSpecific::sbcConfig:
146 dst.set<CodecConfiguration::CodecSpecific::sbcConfig>(
147 src.get<CodecConfiguration::CodecSpecific::sbcConfig>());
148 break;
149 case CodecConfiguration::CodecSpecific::aacConfig:
150 dst.set<CodecConfiguration::CodecSpecific::aacConfig>(
151 src.get<CodecConfiguration::CodecSpecific::aacConfig>());
152 break;
153 case CodecConfiguration::CodecSpecific::ldacConfig:
154 dst.set<CodecConfiguration::CodecSpecific::ldacConfig>(
155 src.get<CodecConfiguration::CodecSpecific::ldacConfig>());
156 break;
157 case CodecConfiguration::CodecSpecific::aptxConfig:
158 dst.set<CodecConfiguration::CodecSpecific::aptxConfig>(
159 src.get<CodecConfiguration::CodecSpecific::aptxConfig>());
160 break;
Omer Osmana2587da2022-05-01 03:54:11 +0000161 case CodecConfiguration::CodecSpecific::opusConfig:
162 dst.set<CodecConfiguration::CodecSpecific::opusConfig>(
163 src.get<CodecConfiguration::CodecSpecific::opusConfig>());
Josh Wu049e2cd2022-01-12 05:42:58 -0800164 break;
165 case CodecConfiguration::CodecSpecific::aptxAdaptiveConfig:
166 dst.set<CodecConfiguration::CodecSpecific::aptxAdaptiveConfig>(
167 src.get<CodecConfiguration::CodecSpecific::aptxAdaptiveConfig>());
168 break;
169 default:
170 break;
171 }
172}
173
174class BluetoothAudioPort : public BnBluetoothAudioPort {
175 public:
176 BluetoothAudioPort() {}
177
Chen Chen0a68a922022-02-15 18:43:26 -0800178 ndk::ScopedAStatus startStream(bool) { return ScopedAStatus::ok(); }
Josh Wu049e2cd2022-01-12 05:42:58 -0800179
180 ndk::ScopedAStatus suspendStream() { return ScopedAStatus::ok(); }
181
182 ndk::ScopedAStatus stopStream() { return ScopedAStatus::ok(); }
183
184 ndk::ScopedAStatus getPresentationPosition(PresentationPosition*) {
185 return ScopedAStatus::ok();
186 }
187
188 ndk::ScopedAStatus updateSourceMetadata(const SourceMetadata&) {
189 return ScopedAStatus::ok();
190 }
191
192 ndk::ScopedAStatus updateSinkMetadata(const SinkMetadata&) {
193 return ScopedAStatus::ok();
194 }
195
196 ndk::ScopedAStatus setLatencyMode(const LatencyMode) {
197 return ScopedAStatus::ok();
198 }
199
200 ndk::ScopedAStatus setCodecType(const CodecType) {
201 return ScopedAStatus::ok();
202 }
203
204 protected:
205 virtual ~BluetoothAudioPort() = default;
206};
207
208class BluetoothAudioProviderFactoryAidl
209 : public testing::TestWithParam<std::string> {
210 public:
211 virtual void SetUp() override {
212 provider_factory_ = IBluetoothAudioProviderFactory::fromBinder(
213 SpAIBinder(AServiceManager_getService(GetParam().c_str())));
214 audio_provider_ = nullptr;
215 ASSERT_NE(provider_factory_, nullptr);
216 }
217
218 virtual void TearDown() override { provider_factory_ = nullptr; }
219
Bao Doc36897d2023-12-06 01:27:54 +0000220 void GetProviderInfoHelper(const SessionType& session_type) {
221 temp_provider_info_ = std::nullopt;
222 auto aidl_reval =
223 provider_factory_->getProviderInfo(session_type, &temp_provider_info_);
224 ASSERT_TRUE(aidl_reval.isOk());
225 }
226
Josh Wu049e2cd2022-01-12 05:42:58 -0800227 void GetProviderCapabilitiesHelper(const SessionType& session_type) {
228 temp_provider_capabilities_.clear();
229 auto aidl_retval = provider_factory_->getProviderCapabilities(
230 session_type, &temp_provider_capabilities_);
231 // AIDL calls should not be failed and callback has to be executed
232 ASSERT_TRUE(aidl_retval.isOk());
233 switch (session_type) {
234 case SessionType::UNKNOWN: {
235 ASSERT_TRUE(temp_provider_capabilities_.empty());
236 } break;
237 case SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH:
238 case SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH:
239 case SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH:
240 case SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH:
Bao Do72399432023-11-09 08:13:05 +0000241 case SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH:
242 case SessionType::HFP_SOFTWARE_ENCODING_DATAPATH: {
Josh Wu049e2cd2022-01-12 05:42:58 -0800243 // All software paths are mandatory and must have exact 1
244 // "PcmParameters"
245 ASSERT_EQ(temp_provider_capabilities_.size(), 1);
246 ASSERT_EQ(temp_provider_capabilities_[0].getTag(),
247 AudioCapabilities::pcmCapabilities);
248 } break;
Alice Kuoadcceec2022-03-28 13:28:43 +0800249 case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
250 case SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH: {
Josh Wu049e2cd2022-01-12 05:42:58 -0800251 std::unordered_set<CodecType> codec_types;
252 // empty capability means offload is unsupported
253 for (auto& audio_capability : temp_provider_capabilities_) {
254 ASSERT_EQ(audio_capability.getTag(),
255 AudioCapabilities::a2dpCapabilities);
256 const auto& codec_capabilities =
257 audio_capability.get<AudioCapabilities::a2dpCapabilities>();
258 // Every codec can present once at most
259 ASSERT_EQ(codec_types.count(codec_capabilities.codecType), 0);
260 switch (codec_capabilities.codecType) {
261 case CodecType::SBC:
262 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
263 CodecCapabilities::Capabilities::sbcCapabilities);
264 break;
265 case CodecType::AAC:
266 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
267 CodecCapabilities::Capabilities::aacCapabilities);
268 break;
269 case CodecType::APTX:
270 case CodecType::APTX_HD:
271 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
272 CodecCapabilities::Capabilities::aptxCapabilities);
273 break;
274 case CodecType::LDAC:
275 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
276 CodecCapabilities::Capabilities::ldacCapabilities);
277 break;
Omer Osmana2587da2022-05-01 03:54:11 +0000278 case CodecType::OPUS:
Josh Wu049e2cd2022-01-12 05:42:58 -0800279 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
Omer Osmana2587da2022-05-01 03:54:11 +0000280 CodecCapabilities::Capabilities::opusCapabilities);
Josh Wu049e2cd2022-01-12 05:42:58 -0800281 break;
282 case CodecType::APTX_ADAPTIVE:
Sagar Verma62df9102022-12-07 17:56:04 +0530283 case CodecType::APTX_ADAPTIVE_LE:
284 case CodecType::APTX_ADAPTIVE_LEX:
Omer Osmana2587da2022-05-01 03:54:11 +0000285 case CodecType::LC3:
Josh Wu049e2cd2022-01-12 05:42:58 -0800286 case CodecType::VENDOR:
287 case CodecType::UNKNOWN:
288 break;
289 }
290 codec_types.insert(codec_capabilities.codecType);
291 }
292 } break;
293 case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
294 case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
295 case SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH: {
shihchienc3ab9f5e2022-09-23 08:18:05 +0000296 // empty capability means offload is unsupported since capabilities are
297 // not hardcoded
Josh Wu049e2cd2022-01-12 05:42:58 -0800298 for (auto audio_capability : temp_provider_capabilities_) {
299 ASSERT_EQ(audio_capability.getTag(),
300 AudioCapabilities::leAudioCapabilities);
301 }
302 } break;
Bao Do72399432023-11-09 08:13:05 +0000303 case SessionType::A2DP_SOFTWARE_DECODING_DATAPATH:
304 case SessionType::HFP_SOFTWARE_DECODING_DATAPATH: {
Alice Kuoadcceec2022-03-28 13:28:43 +0800305 if (!temp_provider_capabilities_.empty()) {
306 ASSERT_EQ(temp_provider_capabilities_.size(), 1);
307 ASSERT_EQ(temp_provider_capabilities_[0].getTag(),
308 AudioCapabilities::pcmCapabilities);
309 }
310 } break;
311 default: {
312 ASSERT_TRUE(temp_provider_capabilities_.empty());
313 }
Josh Wu049e2cd2022-01-12 05:42:58 -0800314 }
315 }
316
317 /***
318 * This helps to open the specified provider and check the openProvider()
319 * has corruct return values. BUT, to keep it simple, it does not consider
320 * the capability, and please do so at the SetUp of each session's test.
321 ***/
322 void OpenProviderHelper(const SessionType& session_type) {
323 auto aidl_retval =
324 provider_factory_->openProvider(session_type, &audio_provider_);
325 if (aidl_retval.isOk()) {
326 ASSERT_NE(session_type, SessionType::UNKNOWN);
327 ASSERT_NE(audio_provider_, nullptr);
328 audio_port_ = ndk::SharedRefBase::make<BluetoothAudioPort>();
329 } else {
Alice Kuoadcceec2022-03-28 13:28:43 +0800330 // optional session type
Josh Wu049e2cd2022-01-12 05:42:58 -0800331 ASSERT_TRUE(
332 session_type == SessionType::UNKNOWN ||
333 session_type ==
334 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
335 session_type ==
336 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
337 session_type ==
338 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
339 session_type ==
340 SessionType::
Alice Kuoadcceec2022-03-28 13:28:43 +0800341 LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
342 session_type ==
343 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
Bao Do72399432023-11-09 08:13:05 +0000344 session_type == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH ||
345 session_type == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH ||
346 session_type == SessionType::HFP_SOFTWARE_DECODING_DATAPATH ||
347 session_type == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH);
Josh Wu049e2cd2022-01-12 05:42:58 -0800348 ASSERT_EQ(audio_provider_, nullptr);
349 }
350 }
351
Josh Wu049e2cd2022-01-12 05:42:58 -0800352 void GetA2dpOffloadCapabilityHelper(const CodecType& codec_type) {
353 temp_codec_capabilities_ = nullptr;
Josh Wu4d2938f2022-02-15 09:21:10 -0800354 for (auto& codec_capability : temp_provider_capabilities_) {
Josh Wu049e2cd2022-01-12 05:42:58 -0800355 auto& a2dp_capabilities =
356 codec_capability.get<AudioCapabilities::a2dpCapabilities>();
357 if (a2dp_capabilities.codecType != codec_type) {
358 continue;
359 }
360 temp_codec_capabilities_ = &a2dp_capabilities;
361 }
362 }
363
364 std::vector<CodecConfiguration::CodecSpecific>
365 GetSbcCodecSpecificSupportedList(bool supported) {
366 std::vector<CodecConfiguration::CodecSpecific> sbc_codec_specifics;
367 if (!supported) {
368 SbcConfiguration sbc_config{.sampleRateHz = 0, .bitsPerSample = 0};
369 sbc_codec_specifics.push_back(
370 CodecConfiguration::CodecSpecific(sbc_config));
371 return sbc_codec_specifics;
372 }
373 GetA2dpOffloadCapabilityHelper(CodecType::SBC);
374 if (temp_codec_capabilities_ == nullptr ||
375 temp_codec_capabilities_->codecType != CodecType::SBC) {
376 return sbc_codec_specifics;
377 }
378 // parse the capability
379 auto& sbc_capability =
380 temp_codec_capabilities_->capabilities
381 .get<CodecCapabilities::Capabilities::sbcCapabilities>();
382 if (sbc_capability.minBitpool > sbc_capability.maxBitpool) {
383 return sbc_codec_specifics;
384 }
385
386 // combine those parameters into one list of
387 // CodecConfiguration::CodecSpecific
388 for (int32_t sample_rate : sbc_capability.sampleRateHz) {
389 for (int8_t block_length : sbc_capability.blockLength) {
390 for (int8_t num_subbands : sbc_capability.numSubbands) {
391 for (int8_t bits_per_sample : sbc_capability.bitsPerSample) {
392 for (auto channel_mode : sbc_capability.channelMode) {
393 for (auto alloc_method : sbc_capability.allocMethod) {
394 SbcConfiguration sbc_data = {
395 .sampleRateHz = sample_rate,
396 .channelMode = channel_mode,
397 .blockLength = block_length,
398 .numSubbands = num_subbands,
399 .allocMethod = alloc_method,
400 .bitsPerSample = bits_per_sample,
401 .minBitpool = sbc_capability.minBitpool,
402 .maxBitpool = sbc_capability.maxBitpool};
403 sbc_codec_specifics.push_back(
404 CodecConfiguration::CodecSpecific(sbc_data));
405 }
406 }
407 }
408 }
409 }
410 }
411 return sbc_codec_specifics;
412 }
413
414 std::vector<CodecConfiguration::CodecSpecific>
415 GetAacCodecSpecificSupportedList(bool supported) {
416 std::vector<CodecConfiguration::CodecSpecific> aac_codec_specifics;
417 if (!supported) {
418 AacConfiguration aac_config{.sampleRateHz = 0, .bitsPerSample = 0};
419 aac_codec_specifics.push_back(
420 CodecConfiguration::CodecSpecific(aac_config));
421 return aac_codec_specifics;
422 }
423 GetA2dpOffloadCapabilityHelper(CodecType::AAC);
424 if (temp_codec_capabilities_ == nullptr ||
425 temp_codec_capabilities_->codecType != CodecType::AAC) {
426 return aac_codec_specifics;
427 }
428 // parse the capability
429 auto& aac_capability =
430 temp_codec_capabilities_->capabilities
431 .get<CodecCapabilities::Capabilities::aacCapabilities>();
432
433 std::vector<bool> variable_bit_rate_enableds = {false};
434 if (aac_capability.variableBitRateSupported) {
435 variable_bit_rate_enableds.push_back(true);
436 }
437
Sagar Verma62df9102022-12-07 17:56:04 +0530438 std::vector<bool> adaptive_bit_rate_supporteds = {false};
439 if (aac_capability.adaptiveBitRateSupported) {
440 adaptive_bit_rate_supporteds.push_back(true);
441 }
442
Josh Wu049e2cd2022-01-12 05:42:58 -0800443 // combine those parameters into one list of
444 // CodecConfiguration::CodecSpecific
445 for (auto object_type : aac_capability.objectType) {
446 for (int32_t sample_rate : aac_capability.sampleRateHz) {
447 for (auto channel_mode : aac_capability.channelMode) {
448 for (int8_t bits_per_sample : aac_capability.bitsPerSample) {
449 for (auto variable_bit_rate_enabled : variable_bit_rate_enableds) {
Sagar Verma62df9102022-12-07 17:56:04 +0530450 for (auto adaptive_bit_rate_supported :
451 adaptive_bit_rate_supporteds) {
452 AacConfiguration aac_data{
453 .objectType = object_type,
454 .sampleRateHz = sample_rate,
455 .channelMode = channel_mode,
456 .variableBitRateEnabled = variable_bit_rate_enabled,
457 .bitsPerSample = bits_per_sample,
458 .adaptiveBitRateSupported = adaptive_bit_rate_supported};
459 aac_codec_specifics.push_back(
460 CodecConfiguration::CodecSpecific(aac_data));
461 }
Josh Wu049e2cd2022-01-12 05:42:58 -0800462 }
463 }
464 }
465 }
466 }
467 return aac_codec_specifics;
468 }
469
470 std::vector<CodecConfiguration::CodecSpecific>
471 GetLdacCodecSpecificSupportedList(bool supported) {
472 std::vector<CodecConfiguration::CodecSpecific> ldac_codec_specifics;
473 if (!supported) {
474 LdacConfiguration ldac_config{.sampleRateHz = 0, .bitsPerSample = 0};
475 ldac_codec_specifics.push_back(
476 CodecConfiguration::CodecSpecific(ldac_config));
477 return ldac_codec_specifics;
478 }
479 GetA2dpOffloadCapabilityHelper(CodecType::LDAC);
480 if (temp_codec_capabilities_ == nullptr ||
481 temp_codec_capabilities_->codecType != CodecType::LDAC) {
482 return ldac_codec_specifics;
483 }
484 // parse the capability
485 auto& ldac_capability =
486 temp_codec_capabilities_->capabilities
487 .get<CodecCapabilities::Capabilities::ldacCapabilities>();
488
489 // combine those parameters into one list of
490 // CodecConfiguration::CodecSpecific
491 for (int32_t sample_rate : ldac_capability.sampleRateHz) {
492 for (int8_t bits_per_sample : ldac_capability.bitsPerSample) {
493 for (auto channel_mode : ldac_capability.channelMode) {
494 for (auto quality_index : ldac_capability.qualityIndex) {
495 LdacConfiguration ldac_data{.sampleRateHz = sample_rate,
496 .channelMode = channel_mode,
497 .qualityIndex = quality_index,
498 .bitsPerSample = bits_per_sample};
499 ldac_codec_specifics.push_back(
500 CodecConfiguration::CodecSpecific(ldac_data));
501 }
502 }
503 }
504 }
505 return ldac_codec_specifics;
506 }
507
508 std::vector<CodecConfiguration::CodecSpecific>
509 GetAptxCodecSpecificSupportedList(bool is_hd, bool supported) {
510 std::vector<CodecConfiguration::CodecSpecific> aptx_codec_specifics;
511 if (!supported) {
512 AptxConfiguration aptx_config{.sampleRateHz = 0, .bitsPerSample = 0};
513 aptx_codec_specifics.push_back(
514 CodecConfiguration::CodecSpecific(aptx_config));
515 return aptx_codec_specifics;
516 }
517 GetA2dpOffloadCapabilityHelper(
518 (is_hd ? CodecType::APTX_HD : CodecType::APTX));
519 if (temp_codec_capabilities_ == nullptr) {
520 return aptx_codec_specifics;
521 }
522 if ((is_hd && temp_codec_capabilities_->codecType != CodecType::APTX_HD) ||
523 (!is_hd && temp_codec_capabilities_->codecType != CodecType::APTX)) {
524 return aptx_codec_specifics;
525 }
526
527 // parse the capability
528 auto& aptx_capability =
529 temp_codec_capabilities_->capabilities
530 .get<CodecCapabilities::Capabilities::aptxCapabilities>();
531
532 // combine those parameters into one list of
533 // CodecConfiguration::CodecSpecific
534 for (int8_t bits_per_sample : aptx_capability.bitsPerSample) {
535 for (int32_t sample_rate : aptx_capability.sampleRateHz) {
536 for (auto channel_mode : aptx_capability.channelMode) {
537 AptxConfiguration aptx_data{.sampleRateHz = sample_rate,
538 .channelMode = channel_mode,
539 .bitsPerSample = bits_per_sample};
540 aptx_codec_specifics.push_back(
541 CodecConfiguration::CodecSpecific(aptx_data));
542 }
543 }
544 }
545 return aptx_codec_specifics;
546 }
547
548 std::vector<CodecConfiguration::CodecSpecific>
Omer Osmana2587da2022-05-01 03:54:11 +0000549 GetOpusCodecSpecificSupportedList(bool supported) {
550 std::vector<CodecConfiguration::CodecSpecific> opus_codec_specifics;
Josh Wu049e2cd2022-01-12 05:42:58 -0800551 if (!supported) {
Omer Osmana2587da2022-05-01 03:54:11 +0000552 OpusConfiguration opus_config{.samplingFrequencyHz = 0,
553 .frameDurationUs = 0};
554 opus_codec_specifics.push_back(
555 CodecConfiguration::CodecSpecific(opus_config));
556 return opus_codec_specifics;
Josh Wu049e2cd2022-01-12 05:42:58 -0800557 }
Omer Osmana2587da2022-05-01 03:54:11 +0000558 GetA2dpOffloadCapabilityHelper(CodecType::OPUS);
Josh Wu049e2cd2022-01-12 05:42:58 -0800559 if (temp_codec_capabilities_ == nullptr ||
Omer Osmana2587da2022-05-01 03:54:11 +0000560 temp_codec_capabilities_->codecType != CodecType::OPUS) {
561 return opus_codec_specifics;
Josh Wu049e2cd2022-01-12 05:42:58 -0800562 }
563 // parse the capability
Omer Osmana2587da2022-05-01 03:54:11 +0000564 auto& opus_capability =
Josh Wu049e2cd2022-01-12 05:42:58 -0800565 temp_codec_capabilities_->capabilities
Omer Osmana2587da2022-05-01 03:54:11 +0000566 .get<CodecCapabilities::Capabilities::opusCapabilities>();
Josh Wu049e2cd2022-01-12 05:42:58 -0800567
568 // combine those parameters into one list of
569 // CodecConfiguration::CodecSpecific
Omer Osmana2587da2022-05-01 03:54:11 +0000570 for (int32_t samplingFrequencyHz : opus_capability->samplingFrequencyHz) {
571 for (int32_t frameDurationUs : opus_capability->frameDurationUs) {
572 for (auto channel_mode : opus_capability->channelMode) {
573 OpusConfiguration opus_data{
574 .samplingFrequencyHz = samplingFrequencyHz,
shihchienc3ab9f5e2022-09-23 08:18:05 +0000575 .frameDurationUs = frameDurationUs,
Omer Osmana2587da2022-05-01 03:54:11 +0000576 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +0000577 };
Omer Osmana2587da2022-05-01 03:54:11 +0000578 opus_codec_specifics.push_back(
579 CodecConfiguration::CodecSpecific(opus_data));
Josh Wu049e2cd2022-01-12 05:42:58 -0800580 }
581 }
582 }
Omer Osmana2587da2022-05-01 03:54:11 +0000583 return opus_codec_specifics;
Josh Wu049e2cd2022-01-12 05:42:58 -0800584 }
585
Alice Kuoadcceec2022-03-28 13:28:43 +0800586 bool IsPcmConfigSupported(const PcmConfiguration& pcm_config) {
587 if (temp_provider_capabilities_.size() != 1 ||
588 temp_provider_capabilities_[0].getTag() !=
589 AudioCapabilities::pcmCapabilities) {
590 return false;
591 }
592 auto pcm_capability = temp_provider_capabilities_[0]
593 .get<AudioCapabilities::pcmCapabilities>();
594 return (contained_in_vector(pcm_capability.channelMode,
595 pcm_config.channelMode) &&
596 contained_in_vector(pcm_capability.sampleRateHz,
597 pcm_config.sampleRateHz) &&
598 contained_in_vector(pcm_capability.bitsPerSample,
599 pcm_config.bitsPerSample));
600 }
601
602 std::shared_ptr<IBluetoothAudioProviderFactory> provider_factory_;
603 std::shared_ptr<IBluetoothAudioProvider> audio_provider_;
604 std::shared_ptr<IBluetoothAudioPort> audio_port_;
605 std::vector<AudioCapabilities> temp_provider_capabilities_;
Bao Doc36897d2023-12-06 01:27:54 +0000606 std::optional<IBluetoothAudioProviderFactory::ProviderInfo>
607 temp_provider_info_;
Alice Kuoadcceec2022-03-28 13:28:43 +0800608
Josh Wu049e2cd2022-01-12 05:42:58 -0800609 // temp storage saves the specified codec capability by
610 // GetOffloadCodecCapabilityHelper()
611 CodecCapabilities* temp_codec_capabilities_;
Alice Kuoadcceec2022-03-28 13:28:43 +0800612
613 static constexpr SessionType kSessionTypes[] = {
614 SessionType::UNKNOWN,
615 SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
616 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
617 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
618 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
619 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
620 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
621 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
622 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
623 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
624 SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
625 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
Bao Do72399432023-11-09 08:13:05 +0000626 SessionType::HFP_SOFTWARE_ENCODING_DATAPATH,
627 SessionType::HFP_SOFTWARE_DECODING_DATAPATH,
Alice Kuoadcceec2022-03-28 13:28:43 +0800628 };
629};
630
631/**
632 * Test whether we can get the FactoryService from HIDL
633 */
634TEST_P(BluetoothAudioProviderFactoryAidl, GetProviderFactoryService) {}
635
636/**
637 * Test whether we can open a provider for each provider returned by
638 * getProviderCapabilities() with non-empty capabalities
639 */
640TEST_P(BluetoothAudioProviderFactoryAidl,
641 OpenProviderAndCheckCapabilitiesBySession) {
642 for (auto session_type : kSessionTypes) {
643 GetProviderCapabilitiesHelper(session_type);
644 OpenProviderHelper(session_type);
645 // We must be able to open a provider if its getProviderCapabilities()
646 // returns non-empty list.
647 EXPECT_TRUE(temp_provider_capabilities_.empty() ||
648 audio_provider_ != nullptr);
649 }
650}
651
652/**
Antoine SOULIER8c90f1f2023-09-26 18:55:17 +0000653 * Test that getProviderInfo, when implemented,
654 * returns empty information for session types for
655 * software data paths.
656 */
657TEST_P(BluetoothAudioProviderFactoryAidl, getProviderInfo_invalidSessionTypes) {
658 static constexpr SessionType kInvalidSessionTypes[]{
659 SessionType::UNKNOWN,
660 SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
661 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
662 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
663 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
664 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
665 SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
666 };
667
668 for (auto session_type : kInvalidSessionTypes) {
669 std::optional<IBluetoothAudioProviderFactory::ProviderInfo> provider_info =
670 std::nullopt;
671 auto aidl_retval =
672 provider_factory_->getProviderInfo(session_type, &provider_info);
673 if (!aidl_retval.isOk()) {
674 continue;
675 }
676
677 // If getProviderInfo is supported, the provider info
678 // must be empty for software session types.
679 ASSERT_FALSE(provider_info.has_value());
680 }
681}
682
683/**
684 * Test that getProviderInfo, when implemented,
685 * returns valid information for session types for
686 * a2dp hardware data paths.
687 */
688TEST_P(BluetoothAudioProviderFactoryAidl, getProviderInfo_a2dpSessionTypes) {
689 static constexpr SessionType kA2dpSessionTypes[]{
690 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
691 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
692 };
693
694 for (auto session_type : kA2dpSessionTypes) {
695 std::optional<IBluetoothAudioProviderFactory::ProviderInfo> provider_info =
696 std::nullopt;
697 auto aidl_retval =
698 provider_factory_->getProviderInfo(session_type, &provider_info);
699 if (!aidl_retval.isOk() || !provider_info.has_value()) {
700 continue;
701 }
702
703 for (auto const& codec_info : provider_info->codecInfos) {
704 // The codec id must not be core.
705 ASSERT_NE(codec_info.id.getTag(), CodecId::core);
706 // The codec info must contain the information
707 // for a2dp transport.
708 ASSERT_EQ(codec_info.transport.getTag(), CodecInfo::Transport::a2dp);
709 }
710 }
711}
712
713/**
714 * Test that getProviderInfo, when implemented,
715 * returns valid information for session types for
716 * le audio hardware data paths.
717 */
718TEST_P(BluetoothAudioProviderFactoryAidl, getProviderInfo_leAudioSessionTypes) {
719 static constexpr SessionType kLeAudioSessionTypes[]{
720 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
721 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
722 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
723 };
724
725 for (auto session_type : kLeAudioSessionTypes) {
726 std::optional<IBluetoothAudioProviderFactory::ProviderInfo> provider_info =
727 std::nullopt;
728 auto aidl_retval =
729 provider_factory_->getProviderInfo(session_type, &provider_info);
730 if (!aidl_retval.isOk() || !provider_info.has_value()) {
731 continue;
732 }
733
734 for (auto const& codec_info : provider_info->codecInfos) {
735 // The codec id must not be a2dp.
736 ASSERT_NE(codec_info.id.getTag(), CodecId::a2dp);
737 // The codec info must contain the information
738 // for le audio transport.
739 // ASSERT_EQ(codec_info.transport.getTag(),
740 // CodecInfo::Transport::le_audio);
741 }
742 }
743}
744
Antoine SOULIER33c4e5a2023-09-28 21:59:19 +0000745class BluetoothAudioProviderAidl : public BluetoothAudioProviderFactoryAidl {
746 protected:
747 std::optional<IBluetoothAudioProviderFactory::ProviderInfo>
748 a2dp_encoding_provider_info_{};
749 std::optional<IBluetoothAudioProviderFactory::ProviderInfo>
750 a2dp_decoding_provider_info_{};
751 std::shared_ptr<IBluetoothAudioProvider> a2dp_encoding_provider_{nullptr};
752 std::shared_ptr<IBluetoothAudioProvider> a2dp_decoding_provider_{nullptr};
753
754 public:
755 void SetUp() override {
756 BluetoothAudioProviderFactoryAidl::SetUp();
757 audio_port_ = ndk::SharedRefBase::make<BluetoothAudioPort>();
758
759 (void)provider_factory_->getProviderInfo(
760 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
761 &a2dp_encoding_provider_info_);
762
763 (void)provider_factory_->getProviderInfo(
764 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
765 &a2dp_decoding_provider_info_);
766
767 (void)provider_factory_->openProvider(
768 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
769 &a2dp_encoding_provider_);
770
771 (void)provider_factory_->openProvider(
772 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
773 &a2dp_decoding_provider_);
774 }
775};
776
777/**
778 * Calling parseA2dpConfiguration on a session of a different type than
779 * A2DP_HARDWARE_OFFLOAD_(ENCODING|DECODING)_DATAPATH must fail.
780 */
781TEST_P(BluetoothAudioProviderAidl, parseA2dpConfiguration_invalidSessionType) {
782 static constexpr SessionType kInvalidSessionTypes[] = {
783 SessionType::UNKNOWN,
784 SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
785 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
786 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
787 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
788 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
789 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
790 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
791 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
792 SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
793 };
794
795 for (auto session_type : kInvalidSessionTypes) {
796 // Open a BluetoothAudioProvider instance of the selected session type.
797 // Skip validation if the provider cannot be opened.
798 std::shared_ptr<IBluetoothAudioProvider> provider{nullptr};
799 (void)provider_factory_->openProvider(session_type, &provider);
800 if (provider == nullptr) {
801 continue;
802 }
803
804 // parseA2dpConfiguration must fail without returning an A2dpStatus.
805 CodecId codec_id(CodecId::A2dp::SBC);
806 CodecParameters codec_parameters;
807 A2dpStatus a2dp_status = A2dpStatus::OK;
808 auto aidl_retval = provider->parseA2dpConfiguration(
809 codec_id, std::vector<uint8_t>{}, &codec_parameters, &a2dp_status);
810 EXPECT_FALSE(aidl_retval.isOk());
811 }
812}
813
814/**
815 * Calling parseA2dpConfiguration with an unknown codec must fail
816 * with the A2dpStatus code INVALID_CODEC_TYPE or NOT_SUPPORTED_CODEC_TYPE.
817 */
818TEST_P(BluetoothAudioProviderAidl,
819 parseA2dpConfiguration_unsupportedCodecType) {
820 CodecId unsupported_core_id(CodecId::Core::CVSD);
821 CodecId unsupported_vendor_id(
822 CodecId::Vendor(0xFCB1, 0x42)); // Google Codec #42
823
824 for (auto& provider : {a2dp_encoding_provider_, a2dp_decoding_provider_}) {
825 if (provider == nullptr) {
826 continue;
827 }
828
829 CodecParameters codec_parameters;
830 A2dpStatus a2dp_status = A2dpStatus::OK;
831 ::ndk::ScopedAStatus aidl_retval;
832
833 // Test with two invalid codec identifiers: vendor or core.
834 aidl_retval = provider->parseA2dpConfiguration(
835 unsupported_core_id, std::vector<uint8_t>{}, &codec_parameters,
836 &a2dp_status);
837 EXPECT_TRUE(!aidl_retval.isOk() ||
838 a2dp_status == A2dpStatus::NOT_SUPPORTED_CODEC_TYPE);
839
840 aidl_retval = provider->parseA2dpConfiguration(
841 unsupported_vendor_id, std::vector<uint8_t>{}, &codec_parameters,
842 &a2dp_status);
843 EXPECT_TRUE(!aidl_retval.isOk() ||
844 a2dp_status == A2dpStatus::NOT_SUPPORTED_CODEC_TYPE);
845 }
846}
847
848/**
849 * Calling parseA2dpConfiguration with a known codec and invalid configuration
850 * must fail with an A2dpStatus code different from INVALID_CODEC_TYPE or
851 * NOT_SUPPORTED_CODEC_TYPE.
852 */
853TEST_P(BluetoothAudioProviderAidl,
854 parseA2dpConfiguration_invalidConfiguration) {
855 for (auto& [provider, provider_info] :
856 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
857 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
858 if (provider == nullptr || !provider_info.has_value() ||
859 provider_info->codecInfos.empty()) {
860 continue;
861 }
862
863 CodecParameters codec_parameters;
864 A2dpStatus a2dp_status = A2dpStatus::OK;
865 ::ndk::ScopedAStatus aidl_retval;
866
867 // Test with the first available codec in the provider info for testing.
868 // The test runs with an empty parameters array, anything more specific
869 // would need understanding the codec.
870 aidl_retval = provider->parseA2dpConfiguration(
871 provider_info->codecInfos[0].id, std::vector<uint8_t>{},
872 &codec_parameters, &a2dp_status);
873 ASSERT_TRUE(aidl_retval.isOk());
874 EXPECT_TRUE(a2dp_status != A2dpStatus::OK &&
875 a2dp_status != A2dpStatus::NOT_SUPPORTED_CODEC_TYPE &&
876 a2dp_status != A2dpStatus::INVALID_CODEC_TYPE);
877 }
878}
879
880/**
881 * Calling parseA2dpConfiguration with a known codec and valid parameters
882 * must return with A2dpStatus OK.
883 */
884TEST_P(BluetoothAudioProviderAidl, parseA2dpConfiguration_valid) {
885 for (auto& [provider, provider_info] :
886 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
887 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
888 if (provider == nullptr || !provider_info.has_value() ||
889 provider_info->codecInfos.empty()) {
890 continue;
891 }
892
893 CodecParameters codec_parameters;
894 A2dpStatus a2dp_status = A2dpStatus::OK;
895 ::ndk::ScopedAStatus aidl_retval;
896
897 // Test with the first available codec in the provider info for testing.
898 // To get a valid configuration (the capabilities array in the provider
899 // info is not a selection), getA2dpConfiguration is used with the
900 // selected codec parameters as input.
901 auto const& codec_info = provider_info->codecInfos[0];
902 auto transport = codec_info.transport.get<CodecInfo::Transport::a2dp>();
903 A2dpRemoteCapabilities remote_capabilities(/*seid*/ 0, codec_info.id,
904 transport.capabilities);
905 std::optional<A2dpConfiguration> configuration;
906 aidl_retval = provider->getA2dpConfiguration(
907 std::vector<A2dpRemoteCapabilities>{remote_capabilities},
908 A2dpConfigurationHint(), &configuration);
909 ASSERT_TRUE(aidl_retval.isOk());
910 ASSERT_TRUE(configuration.has_value());
911
912 aidl_retval = provider->parseA2dpConfiguration(
913 configuration->id, configuration->configuration, &codec_parameters,
914 &a2dp_status);
915 ASSERT_TRUE(aidl_retval.isOk());
916 EXPECT_TRUE(a2dp_status == A2dpStatus::OK);
917 EXPECT_EQ(codec_parameters, configuration->parameters);
918 }
919}
920
921/**
922 * Calling getA2dpConfiguration on a session of a different type than
923 * A2DP_HARDWARE_OFFLOAD_(ENCODING|DECODING)_DATAPATH must fail.
924 */
925TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_invalidSessionType) {
926 static constexpr SessionType kInvalidSessionTypes[] = {
927 SessionType::UNKNOWN,
928 SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
929 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
930 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
931 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
932 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
933 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
934 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
935 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
936 SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
937 };
938
939 for (auto session_type : kInvalidSessionTypes) {
940 // Open a BluetoothAudioProvider instance of the selected session type.
941 // Skip validation if the provider cannot be opened.
942 std::shared_ptr<IBluetoothAudioProvider> provider{nullptr};
943 auto aidl_retval = provider_factory_->openProvider(session_type, &provider);
944 if (provider == nullptr) {
945 continue;
946 }
947
948 // getA2dpConfiguration must fail without returning a configuration.
949 std::optional<A2dpConfiguration> configuration;
950 aidl_retval =
951 provider->getA2dpConfiguration(std::vector<A2dpRemoteCapabilities>{},
952 A2dpConfigurationHint(), &configuration);
953 EXPECT_FALSE(aidl_retval.isOk());
954 }
955}
956
957/**
958 * Calling getA2dpConfiguration with empty or unknown remote capabilities
959 * must return an empty configuration.
960 */
961TEST_P(BluetoothAudioProviderAidl,
962 getA2dpConfiguration_unknownRemoteCapabilities) {
963 for (auto& [provider, provider_info] :
964 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
965 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
966 if (provider == nullptr || !provider_info.has_value() ||
967 provider_info->codecInfos.empty()) {
968 continue;
969 }
970
971 std::optional<A2dpConfiguration> configuration;
972 ::ndk::ScopedAStatus aidl_retval;
973
974 // Test with empty remote capabilities.
975 aidl_retval =
976 provider->getA2dpConfiguration(std::vector<A2dpRemoteCapabilities>{},
977 A2dpConfigurationHint(), &configuration);
978 ASSERT_TRUE(aidl_retval.isOk());
979 EXPECT_FALSE(configuration.has_value());
980
981 // Test with unknown remote capabilities.
982 A2dpRemoteCapabilities unknown_core_remote_capabilities(
983 /*seid*/ 0, CodecId::Core::CVSD, std::vector<uint8_t>{1, 2, 3});
984 A2dpRemoteCapabilities unknown_vendor_remote_capabilities(
985 /*seid*/ 1,
986 /* Google Codec #42 */ CodecId::Vendor(0xFCB1, 0x42),
987 std::vector<uint8_t>{1, 2, 3});
988 aidl_retval = provider->getA2dpConfiguration(
989 std::vector<A2dpRemoteCapabilities>{
990 unknown_core_remote_capabilities,
991 unknown_vendor_remote_capabilities,
992 },
993 A2dpConfigurationHint(), &configuration);
994 ASSERT_TRUE(aidl_retval.isOk());
995 EXPECT_FALSE(configuration.has_value());
996 }
997}
998
999/**
1000 * Calling getA2dpConfiguration with invalid remote capabilities
1001 * must return an empty configuration.
1002 */
1003TEST_P(BluetoothAudioProviderAidl,
1004 getA2dpConfiguration_invalidRemoteCapabilities) {
1005 for (auto& [provider, provider_info] :
1006 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1007 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1008 if (provider == nullptr || !provider_info.has_value() ||
1009 provider_info->codecInfos.empty()) {
1010 continue;
1011 }
1012
1013 std::optional<A2dpConfiguration> configuration;
1014 ::ndk::ScopedAStatus aidl_retval;
1015
1016 // Use the first available codec in the provider info for testing.
1017 // The capabilities are modified to make them invalid.
1018 auto const& codec_info = provider_info->codecInfos[0];
1019 auto transport = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1020 std::vector<uint8_t> invalid_capabilities = transport.capabilities;
1021 invalid_capabilities.push_back(0x42); // adding bytes should be invalid.
1022 aidl_retval = provider->getA2dpConfiguration(
1023 std::vector<A2dpRemoteCapabilities>{
1024 A2dpRemoteCapabilities(/*seid*/ 0, codec_info.id,
1025 std::vector<uint8_t>()),
1026 A2dpRemoteCapabilities(/*seid*/ 1, codec_info.id,
1027 invalid_capabilities),
1028 },
1029 A2dpConfigurationHint(), &configuration);
1030 ASSERT_TRUE(aidl_retval.isOk());
1031 EXPECT_FALSE(configuration.has_value());
1032 }
1033}
1034
1035/**
1036 * Calling getA2dpConfiguration with valid remote capabilities
1037 * must return a valid configuration. The selected parameters must
1038 * be contained in the original capabilities. The returned configuration
1039 * must match the returned parameters. The returned SEID must match the
1040 * input SEID.
1041 */
1042TEST_P(BluetoothAudioProviderAidl,
1043 getA2dpConfiguration_validRemoteCapabilities) {
1044 for (auto& [provider, provider_info] :
1045 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1046 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1047 if (provider == nullptr || !provider_info.has_value() ||
1048 provider_info->codecInfos.empty()) {
1049 continue;
1050 }
1051
1052 // Test with all available codecs in the provider info.
1053 for (auto const& codec_info : provider_info->codecInfos) {
1054 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1055 std::optional<A2dpConfiguration> configuration{};
1056 ::ndk::ScopedAStatus aidl_retval;
1057
1058 aidl_retval = provider->getA2dpConfiguration(
1059 std::vector<A2dpRemoteCapabilities>{
1060 A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
1061 a2dp_info.capabilities),
1062 },
1063 A2dpConfigurationHint(), &configuration);
1064
1065 ASSERT_TRUE(aidl_retval.isOk());
1066 ASSERT_TRUE(configuration.has_value());
1067
1068 // Returned configuration must have the same codec id
1069 // as the remote capability.
1070 EXPECT_EQ(configuration->id, codec_info.id);
1071
1072 // Returned configuration must have the same SEID
1073 // as the remote capability.
1074 EXPECT_EQ(configuration->remoteSeid, 42);
1075
1076 // Returned codec parameters must be in the range of input
1077 // parameters.
1078 EXPECT_NE(
1079 std::find(a2dp_info.channelMode.begin(), a2dp_info.channelMode.end(),
1080 configuration->parameters.channelMode),
1081 a2dp_info.channelMode.end());
1082 EXPECT_NE(std::find(a2dp_info.samplingFrequencyHz.begin(),
1083 a2dp_info.samplingFrequencyHz.end(),
1084 configuration->parameters.samplingFrequencyHz),
1085 a2dp_info.samplingFrequencyHz.end());
1086 EXPECT_NE(std::find(a2dp_info.bitdepth.begin(), a2dp_info.bitdepth.end(),
1087 configuration->parameters.bitdepth),
1088 a2dp_info.bitdepth.end());
1089 EXPECT_EQ(a2dp_info.lossless, configuration->parameters.lossless);
1090 EXPECT_TRUE(configuration->parameters.minBitrate <=
1091 configuration->parameters.maxBitrate);
1092
1093 // Returned configuration must be parsable by parseA2dpParameters
1094 // and match the codec parameters.
1095 CodecParameters codec_parameters;
1096 A2dpStatus a2dp_status = A2dpStatus::OK;
1097 aidl_retval = provider->parseA2dpConfiguration(
1098 configuration->id, configuration->configuration, &codec_parameters,
1099 &a2dp_status);
1100 ASSERT_TRUE(aidl_retval.isOk());
1101 EXPECT_TRUE(a2dp_status == A2dpStatus::OK);
1102 EXPECT_EQ(codec_parameters, configuration->parameters);
1103 }
1104 }
1105}
1106
1107/**
1108 * Calling getA2dpConfiguration with valid remote capabilities
1109 * with various hinted codec ids.
1110 */
1111TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_hintCodecId) {
1112 for (auto& [provider, provider_info] :
1113 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1114 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1115 if (provider == nullptr || !provider_info.has_value() ||
1116 provider_info->codecInfos.empty()) {
1117 continue;
1118 }
1119
1120 // Build the remote capabilities with all supported codecs.
1121 std::vector<A2dpRemoteCapabilities> remote_capabilities;
1122 for (size_t n = 0; n < provider_info->codecInfos.size(); n++) {
1123 auto const& codec_info = provider_info->codecInfos[n];
1124 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1125 remote_capabilities.push_back(A2dpRemoteCapabilities(
1126 /*seid*/ n, codec_info.id, a2dp_info.capabilities));
1127 }
1128
1129 // Test with all supported codec identifiers,
1130 for (auto const& codec_info : provider_info->codecInfos) {
1131 std::optional<A2dpConfiguration> configuration{};
1132 ::ndk::ScopedAStatus aidl_retval;
1133
1134 A2dpConfigurationHint hint;
1135 hint.codecId = codec_info.id;
1136
1137 aidl_retval = provider->getA2dpConfiguration(remote_capabilities, hint,
1138 &configuration);
1139
1140 ASSERT_TRUE(aidl_retval.isOk());
1141 ASSERT_TRUE(configuration.has_value());
1142 EXPECT_EQ(configuration->id, codec_info.id);
1143 }
1144
1145 // Test with unknown codec identifiers: either core or vendor.
1146 for (auto& codec_id :
1147 {CodecId(CodecId::Core::CVSD),
1148 CodecId(CodecId::Vendor(0xFCB1, 0x42)) /*Google Codec #42*/}) {
1149 std::optional<A2dpConfiguration> configuration{};
1150 ::ndk::ScopedAStatus aidl_retval;
1151
1152 A2dpConfigurationHint hint;
1153 hint.codecId = codec_id;
1154
1155 aidl_retval = provider->getA2dpConfiguration(remote_capabilities, hint,
1156 &configuration);
1157
1158 ASSERT_TRUE(aidl_retval.isOk());
1159 ASSERT_TRUE(configuration.has_value());
1160 EXPECT_NE(configuration->id, codec_id);
1161 }
1162 }
1163}
1164
1165/**
1166 * Calling getA2dpConfiguration with valid remote capabilities
1167 * with various hinted channel modes.
1168 */
1169TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_hintChannelMode) {
1170 for (auto& [provider, provider_info] :
1171 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1172 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1173 if (provider == nullptr || !provider_info.has_value() ||
1174 provider_info->codecInfos.empty()) {
1175 continue;
1176 }
1177
1178 // Test with all available codecs in the provider info.
1179 for (auto const& codec_info : provider_info->codecInfos) {
1180 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1181 std::optional<A2dpConfiguration> configuration{};
1182 ::ndk::ScopedAStatus aidl_retval;
1183
1184 for (auto& channel_mode :
1185 {ChannelMode::STEREO, ChannelMode::MONO, ChannelMode::DUALMONO}) {
1186 // Add the hint for the channel mode.
1187 A2dpConfigurationHint hint;
1188 auto& codec_parameters = hint.codecParameters.emplace();
1189 codec_parameters.channelMode = channel_mode;
1190
1191 aidl_retval = provider->getA2dpConfiguration(
1192 std::vector<A2dpRemoteCapabilities>{
1193 A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
1194 a2dp_info.capabilities),
1195 },
1196 hint, &configuration);
1197
1198 ASSERT_TRUE(aidl_retval.isOk());
1199 ASSERT_TRUE(configuration.has_value());
1200
1201 // The hint must be ignored if the channel mode is not supported
1202 // by the codec, and applied otherwise.
1203 ASSERT_EQ(configuration->parameters.channelMode == channel_mode,
1204 std::find(a2dp_info.channelMode.begin(),
1205 a2dp_info.channelMode.end(),
1206 channel_mode) != a2dp_info.channelMode.end());
1207 }
1208 }
1209 }
1210}
1211
1212/**
1213 * Calling getA2dpConfiguration with valid remote capabilities
1214 * with various hinted sampling frequencies.
1215 */
1216TEST_P(BluetoothAudioProviderAidl,
1217 getA2dpConfiguration_hintSamplingFrequencyHz) {
1218 for (auto& [provider, provider_info] :
1219 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1220 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1221 if (provider == nullptr || !provider_info.has_value() ||
1222 provider_info->codecInfos.empty()) {
1223 continue;
1224 }
1225
1226 // Test with all available codecs in the provider info.
1227 for (auto const& codec_info : provider_info->codecInfos) {
1228 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1229 std::optional<A2dpConfiguration> configuration{};
1230 ::ndk::ScopedAStatus aidl_retval;
1231
1232 for (auto& sampling_frequency_hz : {
1233 0,
1234 1,
1235 8000,
1236 16000,
1237 24000,
1238 32000,
1239 44100,
1240 48000,
1241 88200,
1242 96000,
1243 176400,
1244 192000,
1245 }) {
1246 // Add the hint for the sampling frequency.
1247 A2dpConfigurationHint hint;
1248 auto& codec_parameters = hint.codecParameters.emplace();
1249 codec_parameters.samplingFrequencyHz = sampling_frequency_hz;
1250
1251 aidl_retval = provider->getA2dpConfiguration(
1252 std::vector<A2dpRemoteCapabilities>{
1253 A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
1254 a2dp_info.capabilities),
1255 },
1256 hint, &configuration);
1257
1258 ASSERT_TRUE(aidl_retval.isOk());
1259 ASSERT_TRUE(configuration.has_value());
1260
1261 // The hint must be ignored if the sampling frequency is not supported
1262 // by the codec, and applied otherwise.
1263 ASSERT_EQ(configuration->parameters.samplingFrequencyHz ==
1264 sampling_frequency_hz,
1265 std::find(a2dp_info.samplingFrequencyHz.begin(),
1266 a2dp_info.samplingFrequencyHz.end(),
1267 sampling_frequency_hz) !=
1268 a2dp_info.samplingFrequencyHz.end());
1269 }
1270 }
1271 }
1272}
1273
1274/**
1275 * Calling getA2dpConfiguration with valid remote capabilities
1276 * with various hinted sampling bit-depths.
1277 */
1278TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_hintBitdepth) {
1279 for (auto& [provider, provider_info] :
1280 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1281 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1282 if (provider == nullptr || !provider_info.has_value() ||
1283 provider_info->codecInfos.empty()) {
1284 continue;
1285 }
1286
1287 // Test with all available codecs in the provider info.
1288 for (auto const& codec_info : provider_info->codecInfos) {
1289 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1290 std::optional<A2dpConfiguration> configuration{};
1291 ::ndk::ScopedAStatus aidl_retval;
1292
1293 for (auto& bitdepth : {0, 1, 16, 24, 32}) {
1294 // Add the hint for the bit depth.
1295 A2dpConfigurationHint hint;
1296 auto& codec_parameters = hint.codecParameters.emplace();
1297 codec_parameters.bitdepth = bitdepth;
1298
1299 aidl_retval = provider->getA2dpConfiguration(
1300 std::vector<A2dpRemoteCapabilities>{
1301 A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
1302 a2dp_info.capabilities),
1303 },
1304 hint, &configuration);
1305
1306 ASSERT_TRUE(aidl_retval.isOk());
1307 ASSERT_TRUE(configuration.has_value());
1308
1309 // The hint must be ignored if the bitdepth is not supported
1310 // by the codec, and applied otherwise.
1311 ASSERT_EQ(
1312 configuration->parameters.bitdepth == bitdepth,
1313 std::find(a2dp_info.bitdepth.begin(), a2dp_info.bitdepth.end(),
1314 bitdepth) != a2dp_info.bitdepth.end());
1315 }
1316 }
1317 }
1318}
1319
1320/**
1321 * Calling startSession with an unknown codec id must fail.
1322 */
1323TEST_P(BluetoothAudioProviderAidl, startSession_unknownCodecId) {
1324 for (auto& [provider, provider_info] :
1325 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1326 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1327 if (provider == nullptr || !provider_info.has_value() ||
1328 provider_info->codecInfos.empty()) {
1329 continue;
1330 }
1331
1332 for (auto& codec_id :
1333 {CodecId(CodecId::Core::CVSD),
1334 CodecId(CodecId::Vendor(0xFCB1, 0x42) /*Google Codec #42*/)}) {
1335 A2dpStreamConfiguration a2dp_config;
1336 DataMQDesc data_mq_desc;
1337
1338 a2dp_config.codecId = codec_id;
1339 a2dp_config.configuration = std::vector<uint8_t>{1, 2, 3};
1340
1341 auto aidl_retval =
1342 provider->startSession(audio_port_, AudioConfiguration(a2dp_config),
1343 std::vector<LatencyMode>{}, &data_mq_desc);
1344
1345 EXPECT_FALSE(aidl_retval.isOk());
1346 }
1347 }
1348}
1349
1350/**
1351 * Calling startSession with a known codec and a valid configuration
1352 * must succeed.
1353 */
1354TEST_P(BluetoothAudioProviderAidl, startSession_valid) {
1355 for (auto& [provider, provider_info] :
1356 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1357 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1358 if (provider == nullptr || !provider_info.has_value() ||
1359 provider_info->codecInfos.empty()) {
1360 continue;
1361 }
1362
1363 // Use the first available codec in the provider info for testing.
1364 // To get a valid configuration (the capabilities array in the provider
1365 // info is not a selection), getA2dpConfiguration is used with the
1366 // selected codec parameters as input.
1367 auto const& codec_info = provider_info->codecInfos[0];
1368 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1369 ::ndk::ScopedAStatus aidl_retval;
1370 A2dpRemoteCapabilities remote_capabilities(/*seid*/ 0, codec_info.id,
1371 a2dp_info.capabilities);
1372 std::optional<A2dpConfiguration> configuration;
1373 aidl_retval = provider->getA2dpConfiguration(
1374 std::vector<A2dpRemoteCapabilities>{remote_capabilities},
1375 A2dpConfigurationHint(), &configuration);
1376 ASSERT_TRUE(aidl_retval.isOk());
1377 ASSERT_TRUE(configuration.has_value());
1378
1379 // Build the stream configuration.
1380 A2dpStreamConfiguration a2dp_config;
1381 DataMQDesc data_mq_desc;
1382
1383 a2dp_config.codecId = codec_info.id;
1384 a2dp_config.configuration = configuration->configuration;
1385
1386 aidl_retval =
1387 provider->startSession(audio_port_, AudioConfiguration(a2dp_config),
1388 std::vector<LatencyMode>{}, &data_mq_desc);
1389
1390 EXPECT_TRUE(aidl_retval.isOk());
1391 }
1392}
1393
1394/**
1395 * Calling startSession with a known codec but an invalid configuration
1396 * must fail.
1397 */
1398TEST_P(BluetoothAudioProviderAidl, startSession_invalidConfiguration) {
1399 for (auto& [provider, provider_info] :
1400 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1401 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1402 if (provider == nullptr || !provider_info.has_value() ||
1403 provider_info->codecInfos.empty()) {
1404 continue;
1405 }
1406
1407 // Use the first available codec in the provider info for testing.
1408 // To get a valid configuration (the capabilities array in the provider
1409 // info is not a selection), getA2dpConfiguration is used with the
1410 // selected codec parameters as input.
1411 ::ndk::ScopedAStatus aidl_retval;
1412 auto const& codec_info = provider_info->codecInfos[0];
1413 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1414 A2dpRemoteCapabilities remote_capabilities(/*seid*/ 0, codec_info.id,
1415 a2dp_info.capabilities);
1416 std::optional<A2dpConfiguration> configuration;
1417 aidl_retval = provider->getA2dpConfiguration(
1418 std::vector<A2dpRemoteCapabilities>{remote_capabilities},
1419 A2dpConfigurationHint(), &configuration);
1420 ASSERT_TRUE(aidl_retval.isOk());
1421 ASSERT_TRUE(configuration.has_value());
1422
1423 // Build the stream configuration but edit the configuration bytes
1424 // to make it invalid.
1425 A2dpStreamConfiguration a2dp_config;
1426 DataMQDesc data_mq_desc;
1427
1428 a2dp_config.codecId = codec_info.id;
1429 a2dp_config.configuration = configuration->configuration;
1430 a2dp_config.configuration.push_back(42);
1431
1432 aidl_retval =
1433 provider->startSession(audio_port_, AudioConfiguration(a2dp_config),
1434 std::vector<LatencyMode>{}, &data_mq_desc);
1435
1436 EXPECT_FALSE(aidl_retval.isOk());
1437 }
1438}
1439
Antoine SOULIER8c90f1f2023-09-26 18:55:17 +00001440/**
Alice Kuoadcceec2022-03-28 13:28:43 +08001441 * openProvider A2DP_SOFTWARE_ENCODING_DATAPATH
1442 */
1443class BluetoothAudioProviderA2dpEncodingSoftwareAidl
1444 : public BluetoothAudioProviderFactoryAidl {
1445 public:
1446 virtual void SetUp() override {
1447 BluetoothAudioProviderFactoryAidl::SetUp();
1448 GetProviderCapabilitiesHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
1449 OpenProviderHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
1450 ASSERT_NE(audio_provider_, nullptr);
1451 }
1452
1453 virtual void TearDown() override {
1454 audio_port_ = nullptr;
1455 audio_provider_ = nullptr;
1456 BluetoothAudioProviderFactoryAidl::TearDown();
1457 }
Josh Wu049e2cd2022-01-12 05:42:58 -08001458};
1459
1460/**
1461 * Test whether we can open a provider of type
1462 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001463TEST_P(BluetoothAudioProviderA2dpEncodingSoftwareAidl,
1464 OpenA2dpEncodingSoftwareProvider) {}
1465
1466/**
1467 * Test whether each provider of type
1468 * SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH can be started and stopped with
1469 * different PCM config
1470 */
1471TEST_P(BluetoothAudioProviderA2dpEncodingSoftwareAidl,
1472 StartAndEndA2dpEncodingSoftwareSessionWithPossiblePcmConfig) {
1473 for (auto sample_rate : a2dp_sample_rates) {
1474 for (auto bits_per_sample : a2dp_bits_per_samples) {
1475 for (auto channel_mode : a2dp_channel_modes) {
1476 PcmConfiguration pcm_config{
1477 .sampleRateHz = sample_rate,
Alice Kuoadcceec2022-03-28 13:28:43 +08001478 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00001479 .bitsPerSample = bits_per_sample,
Alice Kuoadcceec2022-03-28 13:28:43 +08001480 };
1481 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
1482 DataMQDesc mq_desc;
1483 auto aidl_retval = audio_provider_->startSession(
1484 audio_port_, AudioConfiguration(pcm_config), latency_modes,
1485 &mq_desc);
1486 DataMQ data_mq(mq_desc);
1487
1488 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
1489 if (is_codec_config_valid) {
1490 EXPECT_TRUE(data_mq.isValid());
1491 }
1492 EXPECT_TRUE(audio_provider_->endSession().isOk());
1493 }
1494 }
1495 }
1496}
1497
1498/**
Bao Do72399432023-11-09 08:13:05 +00001499 * openProvider HFP_SOFTWARE_ENCODING_DATAPATH
1500 */
1501class BluetoothAudioProviderHfpSoftwareEncodingAidl
1502 : public BluetoothAudioProviderFactoryAidl {
1503 public:
1504 virtual void SetUp() override {
1505 BluetoothAudioProviderFactoryAidl::SetUp();
1506 GetProviderCapabilitiesHelper(SessionType::HFP_SOFTWARE_ENCODING_DATAPATH);
1507 OpenProviderHelper(SessionType::HFP_SOFTWARE_ENCODING_DATAPATH);
1508 ASSERT_NE(audio_provider_, nullptr);
1509 }
1510
1511 virtual void TearDown() override {
1512 audio_port_ = nullptr;
1513 audio_provider_ = nullptr;
1514 BluetoothAudioProviderFactoryAidl::TearDown();
1515 }
1516
1517 bool OpenSession(int32_t sample_rate, int8_t bits_per_sample,
Bao Do5b2fdab2023-11-20 08:02:55 +00001518 ChannelMode channel_mode, int32_t data_interval_us) {
Bao Do72399432023-11-09 08:13:05 +00001519 PcmConfiguration pcm_config{
1520 .sampleRateHz = sample_rate,
1521 .channelMode = channel_mode,
1522 .bitsPerSample = bits_per_sample,
1523 .dataIntervalUs = data_interval_us,
1524 };
1525 // Checking against provider capability from getProviderCapabilities
1526 // For HFP software, it's
1527 // BluetoothAudioCodecs::GetSoftwarePcmCapabilities();
1528 DataMQDesc mq_desc;
1529 auto aidl_retval = audio_provider_->startSession(
1530 audio_port_, AudioConfiguration(pcm_config), latency_modes, &mq_desc);
1531 DataMQ data_mq(mq_desc);
1532
1533 if (!aidl_retval.isOk()) return false;
1534 if (!data_mq.isValid()) return false;
1535 return true;
1536 }
1537};
1538
1539/**
1540 * Test whether we can open a provider of type
1541 */
1542TEST_P(BluetoothAudioProviderHfpSoftwareEncodingAidl,
1543 OpenHfpSoftwareEncodingProvider) {}
1544
1545/**
1546 * Test whether each provider of type
1547 * SessionType::HFP_SOFTWARE_ENCODING_DATAPATH can be started and stopped with
1548 * different PCM config
1549 */
1550TEST_P(BluetoothAudioProviderHfpSoftwareEncodingAidl,
1551 StartAndEndHfpEncodingSoftwareSessionWithPossiblePcmConfig) {
1552 for (auto sample_rate : hfp_sample_rates_) {
1553 for (auto bits_per_sample : hfp_bits_per_samples_) {
1554 for (auto channel_mode : hfp_channel_modes_) {
Bao Do5b2fdab2023-11-20 08:02:55 +00001555 for (auto data_interval_us : hfp_data_interval_us_) {
1556 EXPECT_TRUE(OpenSession(sample_rate, bits_per_sample, channel_mode,
1557 data_interval_us));
Bao Do72399432023-11-09 08:13:05 +00001558 EXPECT_TRUE(audio_provider_->endSession().isOk());
1559 }
1560 }
1561 }
1562 }
1563}
1564
1565/**
1566 * openProvider HFP_SOFTWARE_DECODING_DATAPATH
1567 */
1568class BluetoothAudioProviderHfpSoftwareDecodingAidl
1569 : public BluetoothAudioProviderFactoryAidl {
1570 public:
1571 virtual void SetUp() override {
1572 BluetoothAudioProviderFactoryAidl::SetUp();
1573 GetProviderCapabilitiesHelper(SessionType::HFP_SOFTWARE_DECODING_DATAPATH);
1574 OpenProviderHelper(SessionType::HFP_SOFTWARE_DECODING_DATAPATH);
1575 ASSERT_NE(audio_provider_, nullptr);
1576 }
1577
1578 virtual void TearDown() override {
1579 audio_port_ = nullptr;
1580 audio_provider_ = nullptr;
1581 BluetoothAudioProviderFactoryAidl::TearDown();
1582 }
1583
1584 bool OpenSession(int32_t sample_rate, int8_t bits_per_sample,
Bao Do5b2fdab2023-11-20 08:02:55 +00001585 ChannelMode channel_mode, int32_t data_interval_us) {
Bao Do72399432023-11-09 08:13:05 +00001586 PcmConfiguration pcm_config{
1587 .sampleRateHz = sample_rate,
1588 .channelMode = channel_mode,
1589 .bitsPerSample = bits_per_sample,
1590 .dataIntervalUs = data_interval_us,
1591 };
1592 DataMQDesc mq_desc;
1593 auto aidl_retval = audio_provider_->startSession(
1594 audio_port_, AudioConfiguration(pcm_config), latency_modes, &mq_desc);
1595 DataMQ data_mq(mq_desc);
1596
1597 if (!aidl_retval.isOk()) return false;
1598 if (!data_mq.isValid()) return false;
1599 return true;
1600 }
1601};
1602
1603/**
1604 * Test whether we can open a provider of type
1605 */
1606TEST_P(BluetoothAudioProviderHfpSoftwareDecodingAidl,
1607 OpenHfpSoftwareDecodingProvider) {}
1608
1609/**
1610 * Test whether each provider of type
1611 * SessionType::HFP_SOFTWARE_DECODING_DATAPATH can be started and stopped with
1612 * different PCM config
1613 */
1614TEST_P(BluetoothAudioProviderHfpSoftwareDecodingAidl,
1615 StartAndEndHfpDecodingSoftwareSessionWithPossiblePcmConfig) {
1616 for (auto sample_rate : hfp_sample_rates_) {
1617 for (auto bits_per_sample : hfp_bits_per_samples_) {
1618 for (auto channel_mode : hfp_channel_modes_) {
Bao Do5b2fdab2023-11-20 08:02:55 +00001619 for (auto data_interval_us : hfp_data_interval_us_) {
1620 EXPECT_TRUE(OpenSession(sample_rate, bits_per_sample, channel_mode,
1621 data_interval_us));
1622 EXPECT_TRUE(audio_provider_->endSession().isOk());
Bao Do72399432023-11-09 08:13:05 +00001623 }
1624 }
1625 }
1626 }
1627}
1628
1629/**
Alice Kuoadcceec2022-03-28 13:28:43 +08001630 * openProvider A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH
1631 */
1632class BluetoothAudioProviderA2dpEncodingHardwareAidl
1633 : public BluetoothAudioProviderFactoryAidl {
1634 public:
1635 virtual void SetUp() override {
1636 BluetoothAudioProviderFactoryAidl::SetUp();
1637 GetProviderCapabilitiesHelper(
1638 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
1639 OpenProviderHelper(SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
1640 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
1641 audio_provider_ != nullptr);
1642 }
1643
1644 virtual void TearDown() override {
1645 audio_port_ = nullptr;
1646 audio_provider_ = nullptr;
1647 BluetoothAudioProviderFactoryAidl::TearDown();
1648 }
1649
1650 bool IsOffloadSupported() { return (temp_provider_capabilities_.size() > 0); }
1651};
1652
1653/**
1654 * Test whether we can open a provider of type
1655 */
1656TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1657 OpenA2dpEncodingHardwareProvider) {}
Josh Wu049e2cd2022-01-12 05:42:58 -08001658
1659/**
1660 * Test whether each provider of type
1661 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
1662 * SBC hardware encoding config
1663 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001664TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1665 StartAndEndA2dpSbcEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001666 if (!IsOffloadSupported()) {
1667 return;
1668 }
1669
1670 CodecConfiguration codec_config = {
1671 .codecType = CodecType::SBC,
1672 .encodedAudioBitrate = 328000,
1673 .peerMtu = 1005,
1674 .isScmstEnabled = false,
1675 };
1676 auto sbc_codec_specifics = GetSbcCodecSpecificSupportedList(true);
1677
1678 for (auto& codec_specific : sbc_codec_specifics) {
1679 copy_codec_specific(codec_config.config, codec_specific);
1680 DataMQDesc mq_desc;
1681 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001682 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001683
1684 ASSERT_TRUE(aidl_retval.isOk());
1685 EXPECT_TRUE(audio_provider_->endSession().isOk());
1686 }
1687}
1688
1689/**
1690 * Test whether each provider of type
1691 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
1692 * AAC hardware encoding config
1693 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001694TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1695 StartAndEndA2dpAacEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001696 if (!IsOffloadSupported()) {
1697 return;
1698 }
1699
1700 CodecConfiguration codec_config = {
1701 .codecType = CodecType::AAC,
1702 .encodedAudioBitrate = 320000,
1703 .peerMtu = 1005,
1704 .isScmstEnabled = false,
1705 };
1706 auto aac_codec_specifics = GetAacCodecSpecificSupportedList(true);
1707
1708 for (auto& codec_specific : aac_codec_specifics) {
1709 copy_codec_specific(codec_config.config, codec_specific);
1710 DataMQDesc mq_desc;
1711 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001712 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001713
1714 ASSERT_TRUE(aidl_retval.isOk());
1715 EXPECT_TRUE(audio_provider_->endSession().isOk());
1716 }
1717}
1718
1719/**
1720 * Test whether each provider of type
1721 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
1722 * LDAC hardware encoding config
1723 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001724TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1725 StartAndEndA2dpLdacEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001726 if (!IsOffloadSupported()) {
1727 return;
1728 }
1729
1730 CodecConfiguration codec_config = {
1731 .codecType = CodecType::LDAC,
1732 .encodedAudioBitrate = 990000,
1733 .peerMtu = 1005,
1734 .isScmstEnabled = false,
1735 };
1736 auto ldac_codec_specifics = GetLdacCodecSpecificSupportedList(true);
1737
1738 for (auto& codec_specific : ldac_codec_specifics) {
1739 copy_codec_specific(codec_config.config, codec_specific);
1740 DataMQDesc mq_desc;
1741 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001742 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001743
1744 ASSERT_TRUE(aidl_retval.isOk());
1745 EXPECT_TRUE(audio_provider_->endSession().isOk());
1746 }
1747}
1748
1749/**
1750 * Test whether each provider of type
1751 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
Omer Osmana2587da2022-05-01 03:54:11 +00001752 * Opus hardware encoding config
Josh Wu049e2cd2022-01-12 05:42:58 -08001753 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001754TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
Omer Osmana2587da2022-05-01 03:54:11 +00001755 StartAndEndA2dpOpusEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001756 if (!IsOffloadSupported()) {
1757 return;
1758 }
1759
1760 CodecConfiguration codec_config = {
Omer Osmana2587da2022-05-01 03:54:11 +00001761 .codecType = CodecType::OPUS,
Josh Wu049e2cd2022-01-12 05:42:58 -08001762 .encodedAudioBitrate = 990000,
1763 .peerMtu = 1005,
1764 .isScmstEnabled = false,
1765 };
Omer Osmana2587da2022-05-01 03:54:11 +00001766 auto opus_codec_specifics = GetOpusCodecSpecificSupportedList(true);
Josh Wu049e2cd2022-01-12 05:42:58 -08001767
Omer Osmana2587da2022-05-01 03:54:11 +00001768 for (auto& codec_specific : opus_codec_specifics) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001769 copy_codec_specific(codec_config.config, codec_specific);
1770 DataMQDesc mq_desc;
1771 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001772 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001773
1774 ASSERT_TRUE(aidl_retval.isOk());
1775 EXPECT_TRUE(audio_provider_->endSession().isOk());
1776 }
1777}
1778
1779/**
1780 * Test whether each provider of type
1781 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
1782 * AptX hardware encoding config
1783 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001784TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1785 StartAndEndA2dpAptxEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001786 if (!IsOffloadSupported()) {
1787 return;
1788 }
1789
1790 for (auto codec_type : {CodecType::APTX, CodecType::APTX_HD}) {
1791 CodecConfiguration codec_config = {
1792 .codecType = codec_type,
1793 .encodedAudioBitrate =
1794 (codec_type == CodecType::APTX ? 352000 : 576000),
1795 .peerMtu = 1005,
1796 .isScmstEnabled = false,
1797 };
1798
1799 auto aptx_codec_specifics = GetAptxCodecSpecificSupportedList(
1800 (codec_type == CodecType::APTX_HD ? true : false), true);
1801
1802 for (auto& codec_specific : aptx_codec_specifics) {
1803 copy_codec_specific(codec_config.config, codec_specific);
1804 DataMQDesc mq_desc;
1805 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001806 audio_port_, AudioConfiguration(codec_config), latency_modes,
1807 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001808
1809 ASSERT_TRUE(aidl_retval.isOk());
1810 EXPECT_TRUE(audio_provider_->endSession().isOk());
1811 }
1812 }
1813}
1814
1815/**
1816 * Test whether each provider of type
1817 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
1818 * an invalid codec config
1819 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001820TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1821 StartAndEndA2dpEncodingHardwareSessionInvalidCodecConfig) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001822 if (!IsOffloadSupported()) {
1823 return;
1824 }
1825 ASSERT_NE(audio_provider_, nullptr);
1826
1827 std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
Sagar Verma62df9102022-12-07 17:56:04 +05301828 for (auto codec_type : ndk::enum_range<CodecType>()) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001829 switch (codec_type) {
1830 case CodecType::SBC:
1831 codec_specifics = GetSbcCodecSpecificSupportedList(false);
1832 break;
1833 case CodecType::AAC:
1834 codec_specifics = GetAacCodecSpecificSupportedList(false);
1835 break;
1836 case CodecType::LDAC:
1837 codec_specifics = GetLdacCodecSpecificSupportedList(false);
1838 break;
1839 case CodecType::APTX:
1840 codec_specifics = GetAptxCodecSpecificSupportedList(false, false);
1841 break;
1842 case CodecType::APTX_HD:
1843 codec_specifics = GetAptxCodecSpecificSupportedList(true, false);
1844 break;
Omer Osmana2587da2022-05-01 03:54:11 +00001845 case CodecType::OPUS:
1846 codec_specifics = GetOpusCodecSpecificSupportedList(false);
Josh Wu049e2cd2022-01-12 05:42:58 -08001847 continue;
1848 case CodecType::APTX_ADAPTIVE:
Sagar Verma62df9102022-12-07 17:56:04 +05301849 case CodecType::APTX_ADAPTIVE_LE:
1850 case CodecType::APTX_ADAPTIVE_LEX:
Omer Osmana2587da2022-05-01 03:54:11 +00001851 case CodecType::LC3:
Josh Wu049e2cd2022-01-12 05:42:58 -08001852 case CodecType::VENDOR:
1853 case CodecType::UNKNOWN:
1854 codec_specifics.clear();
1855 break;
1856 }
1857 if (codec_specifics.empty()) {
1858 continue;
1859 }
1860
1861 CodecConfiguration codec_config = {
1862 .codecType = codec_type,
1863 .encodedAudioBitrate = 328000,
1864 .peerMtu = 1005,
1865 .isScmstEnabled = false,
1866 };
1867 for (auto codec_specific : codec_specifics) {
1868 copy_codec_specific(codec_config.config, codec_specific);
1869 DataMQDesc mq_desc;
1870 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001871 audio_port_, AudioConfiguration(codec_config), latency_modes,
1872 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001873
1874 // AIDL call should fail on invalid codec
1875 ASSERT_FALSE(aidl_retval.isOk());
1876 EXPECT_TRUE(audio_provider_->endSession().isOk());
1877 }
1878 }
1879}
1880
1881/**
Bao Do72399432023-11-09 08:13:05 +00001882 * openProvider HFP_HARDWARE_OFFLOAD_DATAPATH
1883 */
1884class BluetoothAudioProviderHfpHardwareAidl
1885 : public BluetoothAudioProviderFactoryAidl {
1886 public:
1887 virtual void SetUp() override {
1888 BluetoothAudioProviderFactoryAidl::SetUp();
1889 OpenProviderHelper(SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH);
1890 // Can open or empty capability
1891 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
1892 audio_provider_ != nullptr);
1893 }
1894
1895 virtual void TearDown() override {
1896 audio_port_ = nullptr;
1897 audio_provider_ = nullptr;
1898 BluetoothAudioProviderFactoryAidl::TearDown();
1899 }
1900
1901 bool OpenSession(CodecId codec_id, int connection_handle, bool nrec,
Bao Do5b2fdab2023-11-20 08:02:55 +00001902 bool controller_codec) {
Bao Do72399432023-11-09 08:13:05 +00001903 // Check if can open session with a Hfp configuration
1904 HfpConfiguration hfp_configuration{
1905 .codecId = codec_id,
1906 .connectionHandle = connection_handle,
1907 .nrec = nrec,
1908 .controllerCodec = controller_codec,
1909 };
1910 DataMQDesc mq_desc;
1911 auto aidl_retval = audio_provider_->startSession(
1912 audio_port_, AudioConfiguration(hfp_configuration), latency_modes,
1913 &mq_desc);
1914
1915 // Only check if aidl is ok to start session.
1916 return aidl_retval.isOk();
1917 }
1918};
1919
1920/**
1921 * Test whether we can open a provider of type
1922 */
1923TEST_P(BluetoothAudioProviderHfpHardwareAidl, OpenHfpHardwareProvider) {}
1924
1925/**
1926 * Test whether each provider of type
1927 * SessionType::HFP_SOFTWARE_DECODING_DATAPATH can be started and stopped with
1928 * different HFP config
1929 */
1930TEST_P(BluetoothAudioProviderHfpHardwareAidl,
1931 StartAndEndHfpHardwareSessionWithPossiblePcmConfig) {
1932 // Try to open with a sample configuration
1933 EXPECT_TRUE(OpenSession(CodecId::Core::CVSD, 6, false, true));
1934 EXPECT_TRUE(audio_provider_->endSession().isOk());
1935}
1936
1937/**
Josh Wu049e2cd2022-01-12 05:42:58 -08001938 * openProvider HEARING_AID_SOFTWARE_ENCODING_DATAPATH
1939 */
1940class BluetoothAudioProviderHearingAidSoftwareAidl
1941 : public BluetoothAudioProviderFactoryAidl {
1942 public:
1943 virtual void SetUp() override {
1944 BluetoothAudioProviderFactoryAidl::SetUp();
1945 GetProviderCapabilitiesHelper(
1946 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
1947 OpenProviderHelper(SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
1948 ASSERT_NE(audio_provider_, nullptr);
1949 }
1950
1951 virtual void TearDown() override {
1952 audio_port_ = nullptr;
1953 audio_provider_ = nullptr;
1954 BluetoothAudioProviderFactoryAidl::TearDown();
1955 }
1956
1957 static constexpr int32_t hearing_aid_sample_rates_[] = {0, 16000, 24000};
1958 static constexpr int8_t hearing_aid_bits_per_samples_[] = {0, 16, 24};
1959 static constexpr ChannelMode hearing_aid_channel_modes_[] = {
1960 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
1961};
1962
1963/**
1964 * Test whether we can open a provider of type
1965 */
1966TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl,
1967 OpenHearingAidSoftwareProvider) {}
1968
1969/**
1970 * Test whether each provider of type
1971 * SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH can be started and
1972 * stopped with different PCM config
1973 */
1974TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl,
1975 StartAndEndHearingAidSessionWithPossiblePcmConfig) {
1976 for (int32_t sample_rate : hearing_aid_sample_rates_) {
1977 for (int8_t bits_per_sample : hearing_aid_bits_per_samples_) {
1978 for (auto channel_mode : hearing_aid_channel_modes_) {
1979 PcmConfiguration pcm_config{
1980 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08001981 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00001982 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08001983 };
1984 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
1985 DataMQDesc mq_desc;
1986 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001987 audio_port_, AudioConfiguration(pcm_config), latency_modes,
1988 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001989 DataMQ data_mq(mq_desc);
1990
1991 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
1992 if (is_codec_config_valid) {
1993 EXPECT_TRUE(data_mq.isValid());
1994 }
1995 EXPECT_TRUE(audio_provider_->endSession().isOk());
1996 }
1997 }
1998 }
1999}
2000
2001/**
2002 * openProvider LE_AUDIO_SOFTWARE_ENCODING_DATAPATH
2003 */
2004class BluetoothAudioProviderLeAudioOutputSoftwareAidl
2005 : public BluetoothAudioProviderFactoryAidl {
2006 public:
2007 virtual void SetUp() override {
2008 BluetoothAudioProviderFactoryAidl::SetUp();
2009 GetProviderCapabilitiesHelper(
2010 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
2011 OpenProviderHelper(SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
2012 ASSERT_NE(audio_provider_, nullptr);
2013 }
2014
2015 virtual void TearDown() override {
2016 audio_port_ = nullptr;
2017 audio_provider_ = nullptr;
2018 BluetoothAudioProviderFactoryAidl::TearDown();
2019 }
2020
2021 static constexpr int32_t le_audio_output_sample_rates_[] = {
2022 0, 8000, 16000, 24000, 32000, 44100, 48000,
2023 };
2024 static constexpr int8_t le_audio_output_bits_per_samples_[] = {0, 16, 24};
2025 static constexpr ChannelMode le_audio_output_channel_modes_[] = {
2026 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
2027 static constexpr int32_t le_audio_output_data_interval_us_[] = {
2028 0 /* Invalid */, 10000 /* Valid 10ms */};
2029};
2030
2031/**
2032 * Test whether each provider of type
2033 * SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH can be started and
2034 * stopped
2035 */
2036TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl,
2037 OpenLeAudioOutputSoftwareProvider) {}
2038
2039/**
2040 * Test whether each provider of type
2041 * SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH can be started and
2042 * stopped with different PCM config
2043 */
2044TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl,
2045 StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
2046 for (auto sample_rate : le_audio_output_sample_rates_) {
2047 for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
2048 for (auto channel_mode : le_audio_output_channel_modes_) {
2049 for (auto data_interval_us : le_audio_output_data_interval_us_) {
2050 PcmConfiguration pcm_config{
2051 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08002052 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00002053 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08002054 .dataIntervalUs = data_interval_us,
2055 };
Josh Wu8a1be762022-02-15 09:37:29 -08002056 bool is_codec_config_valid =
2057 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
Josh Wu049e2cd2022-01-12 05:42:58 -08002058 DataMQDesc mq_desc;
2059 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002060 audio_port_, AudioConfiguration(pcm_config), latency_modes,
2061 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002062 DataMQ data_mq(mq_desc);
2063
2064 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
2065 if (is_codec_config_valid) {
2066 EXPECT_TRUE(data_mq.isValid());
2067 }
2068 EXPECT_TRUE(audio_provider_->endSession().isOk());
2069 }
2070 }
2071 }
2072 }
2073}
2074
2075/**
Alice Kuo04a399a2022-02-16 09:19:56 +08002076 * openProvider LE_AUDIO_SOFTWARE_DECODING_DATAPATH
Josh Wu049e2cd2022-01-12 05:42:58 -08002077 */
2078class BluetoothAudioProviderLeAudioInputSoftwareAidl
2079 : public BluetoothAudioProviderFactoryAidl {
2080 public:
2081 virtual void SetUp() override {
2082 BluetoothAudioProviderFactoryAidl::SetUp();
2083 GetProviderCapabilitiesHelper(
2084 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH);
2085 OpenProviderHelper(SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH);
2086 ASSERT_NE(audio_provider_, nullptr);
2087 }
2088
2089 virtual void TearDown() override {
2090 audio_port_ = nullptr;
2091 audio_provider_ = nullptr;
2092 BluetoothAudioProviderFactoryAidl::TearDown();
2093 }
2094
2095 static constexpr int32_t le_audio_input_sample_rates_[] = {
2096 0, 8000, 16000, 24000, 32000, 44100, 48000};
2097 static constexpr int8_t le_audio_input_bits_per_samples_[] = {0, 16, 24};
2098 static constexpr ChannelMode le_audio_input_channel_modes_[] = {
2099 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
2100 static constexpr int32_t le_audio_input_data_interval_us_[] = {
2101 0 /* Invalid */, 10000 /* Valid 10ms */};
2102};
2103
2104/**
2105 * Test whether each provider of type
Alice Kuo04a399a2022-02-16 09:19:56 +08002106 * SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002107 * stopped
2108 */
2109TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl,
2110 OpenLeAudioInputSoftwareProvider) {}
2111
2112/**
2113 * Test whether each provider of type
Alice Kuo04a399a2022-02-16 09:19:56 +08002114 * SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002115 * stopped with different PCM config
2116 */
2117TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl,
2118 StartAndEndLeAudioInputSessionWithPossiblePcmConfig) {
2119 for (auto sample_rate : le_audio_input_sample_rates_) {
2120 for (auto bits_per_sample : le_audio_input_bits_per_samples_) {
2121 for (auto channel_mode : le_audio_input_channel_modes_) {
2122 for (auto data_interval_us : le_audio_input_data_interval_us_) {
2123 PcmConfiguration pcm_config{
2124 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08002125 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00002126 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08002127 .dataIntervalUs = data_interval_us,
2128 };
Josh Wu8a1be762022-02-15 09:37:29 -08002129 bool is_codec_config_valid =
2130 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
Josh Wu049e2cd2022-01-12 05:42:58 -08002131 DataMQDesc mq_desc;
2132 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002133 audio_port_, AudioConfiguration(pcm_config), latency_modes,
2134 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002135 DataMQ data_mq(mq_desc);
2136
2137 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
2138 if (is_codec_config_valid) {
2139 EXPECT_TRUE(data_mq.isValid());
2140 }
2141 EXPECT_TRUE(audio_provider_->endSession().isOk());
2142 }
2143 }
2144 }
2145 }
2146}
2147
2148/**
Alice Kuo04a399a2022-02-16 09:19:56 +08002149 * openProvider LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH
Josh Wu049e2cd2022-01-12 05:42:58 -08002150 */
2151class BluetoothAudioProviderLeAudioOutputHardwareAidl
2152 : public BluetoothAudioProviderFactoryAidl {
2153 public:
2154 virtual void SetUp() override {
2155 BluetoothAudioProviderFactoryAidl::SetUp();
2156 GetProviderCapabilitiesHelper(
2157 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
Bao Doc36897d2023-12-06 01:27:54 +00002158 GetProviderInfoHelper(
2159 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
Josh Wu049e2cd2022-01-12 05:42:58 -08002160 OpenProviderHelper(
2161 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
2162 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
2163 audio_provider_ != nullptr);
2164 }
2165
2166 virtual void TearDown() override {
2167 audio_port_ = nullptr;
2168 audio_provider_ = nullptr;
2169 BluetoothAudioProviderFactoryAidl::TearDown();
2170 }
2171
2172 bool IsOffloadOutputSupported() {
2173 for (auto& capability : temp_provider_capabilities_) {
2174 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2175 continue;
2176 }
2177 auto& le_audio_capability =
2178 capability.get<AudioCapabilities::leAudioCapabilities>();
2179 if (le_audio_capability.unicastEncodeCapability.codecType !=
2180 CodecType::UNKNOWN)
2181 return true;
2182 }
2183 return false;
2184 }
2185
Bao Doc36897d2023-12-06 01:27:54 +00002186 bool IsOffloadOutputProviderInfoSupported() {
2187 if (!temp_provider_info_.has_value()) return false;
2188 if (temp_provider_info_.value().codecInfos.empty()) return false;
2189 // Check if all codec info is of LeAudio type
2190 for (auto& codec_info : temp_provider_info_.value().codecInfos) {
2191 if (codec_info.transport.getTag() != CodecInfo::Transport::leAudio)
2192 return false;
2193 }
2194 return true;
2195 }
2196
2197 std::vector<Lc3Configuration> GetUnicastLc3SupportedListFromProviderInfo() {
2198 std::vector<Lc3Configuration> le_audio_codec_configs;
2199 for (auto& codec_info : temp_provider_info_.value().codecInfos) {
2200 // Only gets LC3 codec information
2201 if (codec_info.id != CodecId::Core::LC3) continue;
2202 // Combine those parameters into one list of Lc3Configuration
2203 auto& transport =
2204 codec_info.transport.get<CodecInfo::Transport::Tag::leAudio>();
2205 for (int32_t samplingFrequencyHz : transport.samplingFrequencyHz) {
2206 for (int32_t frameDurationUs : transport.frameDurationUs) {
2207 for (int32_t octetsPerFrame : transport.bitdepth) {
2208 Lc3Configuration lc3_config = {
2209 .samplingFrequencyHz = samplingFrequencyHz,
2210 .frameDurationUs = frameDurationUs,
2211 .octetsPerFrame = octetsPerFrame,
2212 };
2213 le_audio_codec_configs.push_back(lc3_config);
2214 }
2215 }
2216 }
2217 }
2218
2219 return le_audio_codec_configs;
2220 }
2221
2222 AudioContext GetAudioContext(int32_t bitmask) {
2223 AudioContext media_audio_context;
2224 media_audio_context.bitmask = bitmask;
2225 return media_audio_context;
2226 }
2227
2228 LeAudioDeviceCapabilities GetDefaultRemoteCapability() {
2229 // Create a capability
2230 LeAudioDeviceCapabilities capability;
2231
2232 capability.codecId = CodecId::Core::LC3;
2233
2234 auto pref_context_metadata = MetadataLtv::PreferredAudioContexts();
2235 pref_context_metadata.values = GetAudioContext(AudioContext::MEDIA);
2236 capability.metadata = {pref_context_metadata};
2237
2238 auto sampling_rate =
2239 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies();
2240 sampling_rate.bitmask =
2241 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ8000;
2242 auto frame_duration =
2243 CodecSpecificCapabilitiesLtv::SupportedFrameDurations();
2244 frame_duration.bitmask =
2245 CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US7500;
2246 auto octets = CodecSpecificCapabilitiesLtv::SupportedOctetsPerCodecFrame();
2247 octets.minimum = 0;
2248 octets.maximum = 60;
2249 auto frames = CodecSpecificCapabilitiesLtv::SupportedMaxCodecFramesPerSDU();
2250 frames.value = 2;
2251 capability.codecSpecificCapabilities = {sampling_rate, frame_duration,
2252 octets, frames};
2253 return capability;
2254 }
2255
2256 LeAudioConfigurationRequirement GetDefaultRequirement(
2257 bool is_source_requriement) {
2258 // Create a requirements
2259 LeAudioConfigurationRequirement requirement;
2260 requirement.audioContext = GetAudioContext(AudioContext::MEDIA);
2261
2262 auto direction_ase_requriement = AseDirectionRequirement();
2263 direction_ase_requriement.aseConfiguration.codecId = CodecId::Core::LC3;
2264 direction_ase_requriement.aseConfiguration.targetLatency =
2265 LeAudioAseConfiguration::TargetLatency::BALANCED_LATENCY_RELIABILITY;
2266
2267 // Mismatch sampling frequency
2268 direction_ase_requriement.aseConfiguration.codecConfiguration = {
2269 CodecSpecificConfigurationLtv::SamplingFrequency::HZ11025,
2270 CodecSpecificConfigurationLtv::FrameDuration::US7500,
2271 };
2272 if (is_source_requriement)
2273 requirement.sourceAseRequirement = {direction_ase_requriement};
2274 else
2275 requirement.sinkAseRequirement = {direction_ase_requriement};
2276 return requirement;
2277 }
2278
Josh Wu049e2cd2022-01-12 05:42:58 -08002279 std::vector<Lc3Configuration> GetUnicastLc3SupportedList(bool decoding,
2280 bool supported) {
2281 std::vector<Lc3Configuration> le_audio_codec_configs;
2282 if (!supported) {
shihchienc3ab9f5e2022-09-23 08:18:05 +00002283 Lc3Configuration lc3_config{.pcmBitDepth = 0, .samplingFrequencyHz = 0};
Josh Wu049e2cd2022-01-12 05:42:58 -08002284 le_audio_codec_configs.push_back(lc3_config);
2285 return le_audio_codec_configs;
2286 }
2287
2288 // There might be more than one LeAudioCodecCapabilitiesSetting
2289 std::vector<Lc3Capabilities> lc3_capabilities;
2290 for (auto& capability : temp_provider_capabilities_) {
2291 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2292 continue;
2293 }
2294 auto& le_audio_capability =
2295 capability.get<AudioCapabilities::leAudioCapabilities>();
2296 auto& unicast_capability =
2297 decoding ? le_audio_capability.unicastDecodeCapability
2298 : le_audio_capability.unicastEncodeCapability;
2299 if (unicast_capability.codecType != CodecType::LC3) {
2300 continue;
2301 }
2302 auto& lc3_capability = unicast_capability.leAudioCodecCapabilities.get<
2303 UnicastCapability::LeAudioCodecCapabilities::lc3Capabilities>();
2304 lc3_capabilities.push_back(lc3_capability);
2305 }
2306
2307 // Combine those parameters into one list of LeAudioCodecConfiguration
2308 // This seems horrible, but usually each Lc3Capability only contains a
2309 // single Lc3Configuration, which means every array has a length of 1.
2310 for (auto& lc3_capability : lc3_capabilities) {
2311 for (int32_t samplingFrequencyHz : lc3_capability.samplingFrequencyHz) {
2312 for (int32_t frameDurationUs : lc3_capability.frameDurationUs) {
2313 for (int32_t octetsPerFrame : lc3_capability.octetsPerFrame) {
2314 Lc3Configuration lc3_config = {
2315 .samplingFrequencyHz = samplingFrequencyHz,
2316 .frameDurationUs = frameDurationUs,
2317 .octetsPerFrame = octetsPerFrame,
2318 };
2319 le_audio_codec_configs.push_back(lc3_config);
2320 }
2321 }
2322 }
2323 }
2324
2325 return le_audio_codec_configs;
2326 }
2327
Sagar Verma62df9102022-12-07 17:56:04 +05302328 static constexpr int32_t apx_adaptive_le_config_codec_modes[] = {0, 1, 2, 3};
2329
2330 std::vector<AptxAdaptiveLeConfiguration>
2331 GetUnicastAptxAdaptiveLeSupportedList(bool decoding, bool supported,
2332 bool is_le_extended) {
2333 std::vector<AptxAdaptiveLeConfiguration> le_audio_codec_configs;
2334 if (!supported) {
2335 AptxAdaptiveLeConfiguration aptx_adaptive_le_config{
2336 .pcmBitDepth = 0, .samplingFrequencyHz = 0};
2337 le_audio_codec_configs.push_back(aptx_adaptive_le_config);
2338 return le_audio_codec_configs;
2339 }
2340
2341 // There might be more than one LeAudioCodecCapabilitiesSetting
2342 std::vector<AptxAdaptiveLeCapabilities> aptx_adaptive_le_capabilities;
2343 for (auto& capability : temp_provider_capabilities_) {
2344 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2345 continue;
2346 }
2347 auto& le_audio_capability =
2348 capability.get<AudioCapabilities::leAudioCapabilities>();
2349 auto& unicast_capability =
2350 decoding ? le_audio_capability.unicastDecodeCapability
2351 : le_audio_capability.unicastEncodeCapability;
2352 if ((!is_le_extended &&
2353 unicast_capability.codecType != CodecType::APTX_ADAPTIVE_LE) ||
2354 (is_le_extended &&
2355 unicast_capability.codecType != CodecType::APTX_ADAPTIVE_LEX)) {
2356 continue;
2357 }
2358
2359 auto& aptx_adaptive_le_capability =
2360 unicast_capability.leAudioCodecCapabilities
2361 .get<UnicastCapability::LeAudioCodecCapabilities::
2362 aptxAdaptiveLeCapabilities>();
2363
2364 aptx_adaptive_le_capabilities.push_back(aptx_adaptive_le_capability);
2365 }
2366
2367 for (auto& aptx_adaptive_le_capability : aptx_adaptive_le_capabilities) {
2368 for (int32_t samplingFrequencyHz :
2369 aptx_adaptive_le_capability.samplingFrequencyHz) {
2370 for (int32_t frameDurationUs :
2371 aptx_adaptive_le_capability.frameDurationUs) {
2372 for (int32_t octetsPerFrame :
2373 aptx_adaptive_le_capability.octetsPerFrame) {
2374 for (int8_t blocksPerSdu :
2375 aptx_adaptive_le_capability.blocksPerSdu) {
2376 for (int32_t codecMode : apx_adaptive_le_config_codec_modes) {
2377 AptxAdaptiveLeConfiguration aptx_adaptive_le_config = {
2378 .samplingFrequencyHz = samplingFrequencyHz,
2379 .frameDurationUs = frameDurationUs,
2380 .octetsPerFrame = octetsPerFrame,
2381 .blocksPerSdu = blocksPerSdu,
2382 .codecMode = codecMode,
2383 };
2384 le_audio_codec_configs.push_back(aptx_adaptive_le_config);
2385 }
2386 }
2387 }
2388 }
2389 }
2390 }
2391
2392 return le_audio_codec_configs;
2393 }
2394
Josh Wu049e2cd2022-01-12 05:42:58 -08002395 LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
Bao Doc36897d2023-12-06 01:27:54 +00002396 std::vector<int32_t> all_context_bitmasks = {
2397 AudioContext::UNSPECIFIED, AudioContext::CONVERSATIONAL,
2398 AudioContext::MEDIA, AudioContext::GAME,
2399 AudioContext::INSTRUCTIONAL, AudioContext::VOICE_ASSISTANTS,
2400 AudioContext::LIVE_AUDIO, AudioContext::SOUND_EFFECTS,
2401 AudioContext::NOTIFICATIONS, AudioContext::RINGTONE_ALERTS,
2402 AudioContext::ALERTS, AudioContext::EMERGENCY_ALARM,
2403 };
Josh Wu049e2cd2022-01-12 05:42:58 -08002404};
2405
2406/**
2407 * Test whether each provider of type
2408 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2409 * stopped
2410 */
2411TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2412 OpenLeAudioOutputHardwareProvider) {}
2413
2414/**
2415 * Test whether each provider of type
2416 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
Bao Doc36897d2023-12-06 01:27:54 +00002417 * stopped with Unicast hardware encoding config taken from provider info
2418 */
2419TEST_P(
2420 BluetoothAudioProviderLeAudioOutputHardwareAidl,
2421 StartAndEndLeAudioOutputSessionWithPossibleUnicastConfigFromProviderInfo) {
2422 if (!IsOffloadOutputProviderInfoSupported()) {
2423 return;
2424 }
2425
2426 auto lc3_codec_configs = GetUnicastLc3SupportedListFromProviderInfo();
2427 LeAudioConfiguration le_audio_config = {
2428 .codecType = CodecType::LC3,
2429 .peerDelayUs = 0,
2430 };
2431
2432 for (auto& lc3_config : lc3_codec_configs) {
2433 le_audio_config.leAudioCodecConfig
2434 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2435 DataMQDesc mq_desc;
2436 auto aidl_retval = audio_provider_->startSession(
2437 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2438 &mq_desc);
2439
2440 ASSERT_TRUE(aidl_retval.isOk());
2441 EXPECT_TRUE(audio_provider_->endSession().isOk());
2442 }
2443}
2444
2445TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2446 GetEmptyAseConfigurationEmptyCapability) {
2447 std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
2448 std::vector<LeAudioConfigurationRequirement> empty_requirement;
2449 std::vector<LeAudioAseConfigurationSetting> configurations;
2450
2451 // Check empty capability for source direction
2452 auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
2453 std::nullopt, empty_capability, empty_requirement, &configurations);
2454
2455 ASSERT_TRUE(aidl_retval.isOk());
2456 ASSERT_TRUE(configurations.empty());
2457
2458 // Check empty capability for sink direction
2459 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
2460 empty_capability, std::nullopt, empty_requirement, &configurations);
2461
2462 ASSERT_TRUE(aidl_retval.isOk());
2463 ASSERT_TRUE(configurations.empty());
2464}
2465
2466TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2467 GetEmptyAseConfigurationMismatchedRequirement) {
2468 std::vector<std::optional<LeAudioDeviceCapabilities>> capabilities = {
2469 GetDefaultRemoteCapability()};
2470
2471 // Check empty capability for source direction
2472 std::vector<LeAudioAseConfigurationSetting> configurations;
2473 std::vector<LeAudioConfigurationRequirement> source_requirements = {
2474 GetDefaultRequirement(true)};
2475 auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
2476 std::nullopt, capabilities, source_requirements, &configurations);
2477
2478 ASSERT_TRUE(aidl_retval.isOk());
2479 ASSERT_TRUE(configurations.empty());
2480
2481 // Check empty capability for sink direction
2482 std::vector<LeAudioConfigurationRequirement> sink_requirements = {
2483 GetDefaultRequirement(false)};
2484 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
2485 capabilities, std::nullopt, source_requirements, &configurations);
2486
2487 ASSERT_TRUE(aidl_retval.isOk());
2488 ASSERT_TRUE(configurations.empty());
2489}
2490
2491TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl, GetQoSConfiguration) {
2492 IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement requirement;
2493 std::vector<IBluetoothAudioProvider::LeAudioAseQosConfiguration>
2494 QoSConfigurations;
2495 for (auto bitmask : all_context_bitmasks) {
2496 requirement.contextType = GetAudioContext(bitmask);
2497 IBluetoothAudioProvider::LeAudioAseQosConfigurationPair result;
2498 auto aidl_retval =
2499 audio_provider_->getLeAudioAseQosConfiguration(requirement, &result);
2500 ASSERT_TRUE(aidl_retval.isOk());
2501 if (result.sinkQosConfiguration.has_value())
2502 QoSConfigurations.push_back(result.sinkQosConfiguration.value());
2503 if (result.sourceQosConfiguration.has_value())
2504 QoSConfigurations.push_back(result.sourceQosConfiguration.value());
2505 }
2506 // QoS Configurations should not be empty, as we searched for all contexts
2507 ASSERT_FALSE(QoSConfigurations.empty());
2508}
Jakub Tyszkowskic8a62242024-01-05 15:25:49 +00002509
2510TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2511 GetDataPathConfiguration) {
2512 IBluetoothAudioProvider::StreamConfig sink_requirement;
2513 IBluetoothAudioProvider::StreamConfig source_requirement;
2514 std::vector<IBluetoothAudioProvider::LeAudioDataPathConfiguration>
2515 DataPathConfigurations;
2516 bool is_supported = false;
2517
2518 for (auto bitmask : all_context_bitmasks) {
2519 sink_requirement.context = GetAudioContext(bitmask);
2520 source_requirement.context = GetAudioContext(bitmask);
2521 IBluetoothAudioProvider::LeAudioDataPathConfigurationPair result;
2522 auto aidl_retval = audio_provider_->getLeAudioAseDatapathConfiguration(
2523 sink_requirement, source_requirement, &result);
2524 if (!aidl_retval.isOk()) {
2525 // If not OK, then it could be not supported, as it is an optional feature
2526 ASSERT_EQ(aidl_retval.getExceptionCode(), EX_UNSUPPORTED_OPERATION);
2527 } else {
2528 is_supported = true;
2529 if (result.inputConfig.has_value())
2530 DataPathConfigurations.push_back(result.inputConfig.value());
2531 if (result.inputConfig.has_value())
2532 DataPathConfigurations.push_back(result.inputConfig.value());
2533 }
2534 }
2535
2536 if (is_supported) {
2537 // Datapath Configurations should not be empty, as we searched for all
2538 // contexts
2539 ASSERT_FALSE(DataPathConfigurations.empty());
2540 }
2541}
2542
Bao Doc36897d2023-12-06 01:27:54 +00002543/**
2544 * Test whether each provider of type
2545 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002546 * stopped with Unicast hardware encoding config
2547 */
2548TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2549 StartAndEndLeAudioOutputSessionWithPossibleUnicastConfig) {
2550 if (!IsOffloadOutputSupported()) {
2551 return;
2552 }
2553
2554 auto lc3_codec_configs =
2555 GetUnicastLc3SupportedList(false /* decoding */, true /* supported */);
2556 LeAudioConfiguration le_audio_config = {
2557 .codecType = CodecType::LC3,
2558 .peerDelayUs = 0,
2559 };
2560
2561 for (auto& lc3_config : lc3_codec_configs) {
2562 le_audio_config.leAudioCodecConfig
2563 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2564 DataMQDesc mq_desc;
2565 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002566 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2567 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002568
2569 ASSERT_TRUE(aidl_retval.isOk());
2570 EXPECT_TRUE(audio_provider_->endSession().isOk());
2571 }
2572}
2573
2574/**
2575 * Test whether each provider of type
2576 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2577 * stopped with Unicast hardware encoding config
2578 *
2579 * Disabled since offload codec checking is not ready
2580 */
2581TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2582 DISABLED_StartAndEndLeAudioOutputSessionWithInvalidAudioConfiguration) {
2583 if (!IsOffloadOutputSupported()) {
2584 return;
2585 }
2586
2587 auto lc3_codec_configs =
2588 GetUnicastLc3SupportedList(false /* decoding */, false /* supported */);
2589 LeAudioConfiguration le_audio_config = {
2590 .codecType = CodecType::LC3,
2591 .peerDelayUs = 0,
2592 };
2593
2594 for (auto& lc3_config : lc3_codec_configs) {
2595 le_audio_config.leAudioCodecConfig
2596 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2597 DataMQDesc mq_desc;
2598 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002599 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2600 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002601
2602 // AIDL call should fail on invalid codec
2603 ASSERT_FALSE(aidl_retval.isOk());
2604 EXPECT_TRUE(audio_provider_->endSession().isOk());
2605 }
2606}
2607
Sagar Verma62df9102022-12-07 17:56:04 +05302608static std::vector<uint8_t> vendorMetadata = {0x0B, // Length
2609 0xFF, // Type: Vendor-specific
2610 0x0A, 0x00, // Company_ID
2611 0x01, 0x02, 0x03, 0x04, // Data
2612 0x05, 0x06, 0x07, 0x08};
2613
2614/**
2615 * Test whether each provider of type
2616 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2617 * stopped with Unicast hardware encoding config
2618 */
2619TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2620 StartAndEndLeAudioOutputSessionWithAptxAdaptiveLeUnicastConfig) {
2621 if (!IsOffloadOutputSupported()) {
2622 return;
2623 }
2624 for (auto codec_type :
2625 {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
2626 bool is_le_extended = (codec_type == CodecType::APTX_ADAPTIVE_LEX);
2627 auto aptx_adaptive_le_codec_configs =
2628 GetUnicastAptxAdaptiveLeSupportedList(false, true, is_le_extended);
2629 LeAudioConfiguration le_audio_config = {
2630 .codecType = codec_type,
2631 .peerDelayUs = 0,
2632 .vendorSpecificMetadata = vendorMetadata,
2633 };
2634
2635 for (auto& aptx_adaptive_le_config : aptx_adaptive_le_codec_configs) {
2636 le_audio_config.leAudioCodecConfig
2637 .set<LeAudioCodecConfiguration::aptxAdaptiveLeConfig>(
2638 aptx_adaptive_le_config);
2639 DataMQDesc mq_desc;
2640 auto aidl_retval = audio_provider_->startSession(
2641 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2642 &mq_desc);
2643
2644 ASSERT_TRUE(aidl_retval.isOk());
2645 EXPECT_TRUE(audio_provider_->endSession().isOk());
2646 }
2647 }
2648}
2649
2650/**
2651 * Test whether each provider of type
2652 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2653 * stopped with Unicast hardware encoding config
2654 */
2655TEST_P(
2656 BluetoothAudioProviderLeAudioOutputHardwareAidl,
2657 BluetoothAudioProviderLeAudioOutputHardwareAidl_StartAndEndLeAudioOutputSessionWithInvalidAptxAdaptiveLeAudioConfiguration) {
2658 if (!IsOffloadOutputSupported()) {
2659 return;
2660 }
2661
2662 for (auto codec_type :
2663 {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
2664 bool is_le_extended = (codec_type == CodecType::APTX_ADAPTIVE_LEX);
2665 auto aptx_adaptive_le_codec_configs =
2666 GetUnicastAptxAdaptiveLeSupportedList(false, true, is_le_extended);
2667 LeAudioConfiguration le_audio_config = {
2668 .codecType = codec_type,
2669 .peerDelayUs = 0,
2670 .vendorSpecificMetadata = vendorMetadata,
2671 };
2672
2673 for (auto& aptx_adaptive_le_config : aptx_adaptive_le_codec_configs) {
2674 le_audio_config.leAudioCodecConfig
2675 .set<LeAudioCodecConfiguration::aptxAdaptiveLeConfig>(
2676 aptx_adaptive_le_config);
2677 DataMQDesc mq_desc;
2678 auto aidl_retval = audio_provider_->startSession(
2679 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2680 &mq_desc);
2681
2682 // AIDL call should fail on invalid codec
2683 ASSERT_FALSE(aidl_retval.isOk());
2684 EXPECT_TRUE(audio_provider_->endSession().isOk());
2685 }
2686 }
2687}
2688
Josh Wu049e2cd2022-01-12 05:42:58 -08002689/**
2690 * openProvider LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH
2691 */
2692class BluetoothAudioProviderLeAudioInputHardwareAidl
2693 : public BluetoothAudioProviderLeAudioOutputHardwareAidl {
2694 public:
2695 virtual void SetUp() override {
2696 BluetoothAudioProviderFactoryAidl::SetUp();
2697 GetProviderCapabilitiesHelper(
2698 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
Bao Doc36897d2023-12-06 01:27:54 +00002699 GetProviderInfoHelper(
2700 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
Josh Wu049e2cd2022-01-12 05:42:58 -08002701 OpenProviderHelper(
2702 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
2703 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
2704 audio_provider_ != nullptr);
2705 }
2706
2707 bool IsOffloadInputSupported() {
2708 for (auto& capability : temp_provider_capabilities_) {
2709 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2710 continue;
2711 }
2712 auto& le_audio_capability =
2713 capability.get<AudioCapabilities::leAudioCapabilities>();
2714 if (le_audio_capability.unicastDecodeCapability.codecType !=
2715 CodecType::UNKNOWN)
2716 return true;
2717 }
2718 return false;
2719 }
2720
2721 virtual void TearDown() override {
2722 audio_port_ = nullptr;
2723 audio_provider_ = nullptr;
2724 BluetoothAudioProviderFactoryAidl::TearDown();
2725 }
2726};
2727
2728/**
2729 * Test whether each provider of type
Bao Doc36897d2023-12-06 01:27:54 +00002730 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002731 * stopped
2732 */
2733TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
2734 OpenLeAudioInputHardwareProvider) {}
2735
2736/**
2737 * Test whether each provider of type
Bao Doc36897d2023-12-06 01:27:54 +00002738 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
2739 * stopped with Unicast hardware encoding config taken from provider info
2740 */
2741TEST_P(
2742 BluetoothAudioProviderLeAudioInputHardwareAidl,
2743 StartAndEndLeAudioInputSessionWithPossibleUnicastConfigFromProviderInfo) {
2744 if (!IsOffloadOutputProviderInfoSupported()) {
2745 return;
2746 }
2747
2748 auto lc3_codec_configs = GetUnicastLc3SupportedListFromProviderInfo();
2749 LeAudioConfiguration le_audio_config = {
2750 .codecType = CodecType::LC3,
2751 .peerDelayUs = 0,
2752 };
2753
2754 for (auto& lc3_config : lc3_codec_configs) {
2755 le_audio_config.leAudioCodecConfig
2756 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2757 DataMQDesc mq_desc;
2758 auto aidl_retval = audio_provider_->startSession(
2759 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2760 &mq_desc);
2761
2762 ASSERT_TRUE(aidl_retval.isOk());
2763 EXPECT_TRUE(audio_provider_->endSession().isOk());
2764 }
2765}
2766
2767/**
2768 * Test whether each provider of type
2769 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002770 * stopped with Unicast hardware encoding config
2771 */
2772TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
2773 StartAndEndLeAudioInputSessionWithPossibleUnicastConfig) {
2774 if (!IsOffloadInputSupported()) {
2775 return;
2776 }
2777
2778 auto lc3_codec_configs =
2779 GetUnicastLc3SupportedList(true /* decoding */, true /* supported */);
2780 LeAudioConfiguration le_audio_config = {
2781 .codecType = CodecType::LC3,
2782 .peerDelayUs = 0,
2783 };
2784
2785 for (auto& lc3_config : lc3_codec_configs) {
2786 le_audio_config.leAudioCodecConfig
2787 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2788 DataMQDesc mq_desc;
2789 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002790 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2791 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002792
2793 ASSERT_TRUE(aidl_retval.isOk());
2794 EXPECT_TRUE(audio_provider_->endSession().isOk());
2795 }
2796}
2797
2798/**
2799 * Test whether each provider of type
Bao Doc36897d2023-12-06 01:27:54 +00002800 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002801 * stopped with Unicast hardware encoding config
2802 *
2803 * Disabled since offload codec checking is not ready
2804 */
2805TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
2806 DISABLED_StartAndEndLeAudioInputSessionWithInvalidAudioConfiguration) {
2807 if (!IsOffloadInputSupported()) {
2808 return;
2809 }
2810
2811 auto lc3_codec_configs =
2812 GetUnicastLc3SupportedList(true /* decoding */, false /* supported */);
2813 LeAudioConfiguration le_audio_config = {
2814 .codecType = CodecType::LC3,
2815 .peerDelayUs = 0,
2816 };
2817
2818 for (auto& lc3_config : lc3_codec_configs) {
2819 le_audio_config.leAudioCodecConfig
2820 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2821
2822 DataMQDesc mq_desc;
2823 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002824 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2825 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002826
2827 // AIDL call should fail on invalid codec
2828 ASSERT_FALSE(aidl_retval.isOk());
2829 EXPECT_TRUE(audio_provider_->endSession().isOk());
2830 }
2831}
2832
2833/**
2834 * openProvider LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH
2835 */
2836class BluetoothAudioProviderLeAudioBroadcastSoftwareAidl
2837 : public BluetoothAudioProviderFactoryAidl {
2838 public:
2839 virtual void SetUp() override {
2840 BluetoothAudioProviderFactoryAidl::SetUp();
2841 GetProviderCapabilitiesHelper(
2842 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
2843 OpenProviderHelper(
2844 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
2845 ASSERT_NE(audio_provider_, nullptr);
2846 }
2847
2848 virtual void TearDown() override {
2849 audio_port_ = nullptr;
2850 audio_provider_ = nullptr;
2851 BluetoothAudioProviderFactoryAidl::TearDown();
2852 }
2853
2854 static constexpr int32_t le_audio_output_sample_rates_[] = {
2855 0, 8000, 16000, 24000, 32000, 44100, 48000,
2856 };
2857 static constexpr int8_t le_audio_output_bits_per_samples_[] = {0, 16, 24};
2858 static constexpr ChannelMode le_audio_output_channel_modes_[] = {
2859 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
2860 static constexpr int32_t le_audio_output_data_interval_us_[] = {
2861 0 /* Invalid */, 10000 /* Valid 10ms */};
2862};
2863
2864/**
2865 * Test whether each provider of type
2866 * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started and
2867 * stopped
2868 */
2869TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
Josh Wu3202eab2022-02-17 18:09:05 -08002870 OpenLeAudioOutputSoftwareProvider) {}
Josh Wu049e2cd2022-01-12 05:42:58 -08002871
2872/**
2873 * Test whether each provider of type
2874 * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started and
2875 * stopped with different PCM config
2876 */
2877TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
Josh Wu3202eab2022-02-17 18:09:05 -08002878 StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
Josh Wu049e2cd2022-01-12 05:42:58 -08002879 for (auto sample_rate : le_audio_output_sample_rates_) {
2880 for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
2881 for (auto channel_mode : le_audio_output_channel_modes_) {
2882 for (auto data_interval_us : le_audio_output_data_interval_us_) {
2883 PcmConfiguration pcm_config{
2884 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08002885 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00002886 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08002887 .dataIntervalUs = data_interval_us,
2888 };
Josh Wu8a1be762022-02-15 09:37:29 -08002889 bool is_codec_config_valid =
2890 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
Josh Wu049e2cd2022-01-12 05:42:58 -08002891 DataMQDesc mq_desc;
2892 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002893 audio_port_, AudioConfiguration(pcm_config), latency_modes,
2894 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002895 DataMQ data_mq(mq_desc);
2896
2897 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
2898 if (is_codec_config_valid) {
2899 EXPECT_TRUE(data_mq.isValid());
2900 }
2901 EXPECT_TRUE(audio_provider_->endSession().isOk());
2902 }
2903 }
2904 }
2905 }
2906}
2907
Alice Kuo336d90c2022-02-16 09:09:59 +08002908/**
2909 * openProvider LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH
2910 */
2911class BluetoothAudioProviderLeAudioBroadcastHardwareAidl
2912 : public BluetoothAudioProviderFactoryAidl {
2913 public:
2914 virtual void SetUp() override {
2915 BluetoothAudioProviderFactoryAidl::SetUp();
2916 GetProviderCapabilitiesHelper(
2917 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
Bao Doc36897d2023-12-06 01:27:54 +00002918 GetProviderInfoHelper(
2919 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
Alice Kuo336d90c2022-02-16 09:09:59 +08002920 OpenProviderHelper(
2921 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
2922 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
2923 audio_provider_ != nullptr);
2924 }
2925
2926 virtual void TearDown() override {
2927 audio_port_ = nullptr;
2928 audio_provider_ = nullptr;
2929 BluetoothAudioProviderFactoryAidl::TearDown();
2930 }
2931
2932 bool IsBroadcastOffloadSupported() {
2933 for (auto& capability : temp_provider_capabilities_) {
2934 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2935 continue;
2936 }
2937 auto& le_audio_capability =
2938 capability.get<AudioCapabilities::leAudioCapabilities>();
2939 if (le_audio_capability.broadcastCapability.codecType !=
2940 CodecType::UNKNOWN)
2941 return true;
2942 }
2943 return false;
2944 }
2945
Bao Doc36897d2023-12-06 01:27:54 +00002946 bool IsBroadcastOffloadProviderInfoSupported() {
2947 if (!temp_provider_info_.has_value()) return false;
2948 if (temp_provider_info_.value().codecInfos.empty()) return false;
2949 // Check if all codec info is of LeAudio type
2950 for (auto& codec_info : temp_provider_info_.value().codecInfos) {
2951 if (codec_info.transport.getTag() != CodecInfo::Transport::leAudio)
2952 return false;
2953 }
2954 return true;
2955 }
2956
2957 std::vector<Lc3Configuration> GetBroadcastLc3SupportedListFromProviderInfo() {
2958 std::vector<Lc3Configuration> le_audio_codec_configs;
2959 for (auto& codec_info : temp_provider_info_.value().codecInfos) {
2960 // Only gets LC3 codec information
2961 if (codec_info.id != CodecId::Core::LC3) continue;
2962 // Combine those parameters into one list of Lc3Configuration
2963 auto& transport =
2964 codec_info.transport.get<CodecInfo::Transport::Tag::leAudio>();
2965 for (int32_t samplingFrequencyHz : transport.samplingFrequencyHz) {
2966 for (int32_t frameDurationUs : transport.frameDurationUs) {
2967 for (int32_t octetsPerFrame : transport.bitdepth) {
2968 Lc3Configuration lc3_config = {
2969 .samplingFrequencyHz = samplingFrequencyHz,
2970 .frameDurationUs = frameDurationUs,
2971 .octetsPerFrame = octetsPerFrame,
2972 };
2973 le_audio_codec_configs.push_back(lc3_config);
2974 }
2975 }
2976 }
2977 }
2978
2979 return le_audio_codec_configs;
2980 }
2981
Alice Kuo336d90c2022-02-16 09:09:59 +08002982 std::vector<Lc3Configuration> GetBroadcastLc3SupportedList(bool supported) {
2983 std::vector<Lc3Configuration> le_audio_codec_configs;
2984 if (!supported) {
shihchienc3ab9f5e2022-09-23 08:18:05 +00002985 Lc3Configuration lc3_config{.pcmBitDepth = 0, .samplingFrequencyHz = 0};
Alice Kuo336d90c2022-02-16 09:09:59 +08002986 le_audio_codec_configs.push_back(lc3_config);
2987 return le_audio_codec_configs;
2988 }
2989
2990 // There might be more than one LeAudioCodecCapabilitiesSetting
2991 std::vector<Lc3Capabilities> lc3_capabilities;
2992 for (auto& capability : temp_provider_capabilities_) {
2993 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2994 continue;
2995 }
2996 auto& le_audio_capability =
2997 capability.get<AudioCapabilities::leAudioCapabilities>();
2998 auto& broadcast_capability = le_audio_capability.broadcastCapability;
2999 if (broadcast_capability.codecType != CodecType::LC3) {
3000 continue;
3001 }
3002 auto& lc3_capability = broadcast_capability.leAudioCodecCapabilities.get<
3003 BroadcastCapability::LeAudioCodecCapabilities::lc3Capabilities>();
3004 for (int idx = 0; idx < lc3_capability->size(); idx++)
3005 lc3_capabilities.push_back(*lc3_capability->at(idx));
3006 }
3007
3008 // Combine those parameters into one list of LeAudioCodecConfiguration
3009 // This seems horrible, but usually each Lc3Capability only contains a
3010 // single Lc3Configuration, which means every array has a length of 1.
3011 for (auto& lc3_capability : lc3_capabilities) {
3012 for (int32_t samplingFrequencyHz : lc3_capability.samplingFrequencyHz) {
3013 for (int32_t frameDurationUs : lc3_capability.frameDurationUs) {
3014 for (int32_t octetsPerFrame : lc3_capability.octetsPerFrame) {
3015 Lc3Configuration lc3_config = {
3016 .samplingFrequencyHz = samplingFrequencyHz,
3017 .frameDurationUs = frameDurationUs,
3018 .octetsPerFrame = octetsPerFrame,
3019 };
3020 le_audio_codec_configs.push_back(lc3_config);
3021 }
3022 }
3023 }
3024 }
3025
3026 return le_audio_codec_configs;
3027 }
3028
3029 LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
3030};
3031
3032/**
3033 * Test whether each provider of type
3034 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
3035 * started and stopped
3036 */
3037TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3038 OpenLeAudioOutputHardwareProvider) {}
3039
3040/**
3041 * Test whether each provider of type
3042 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
Bao Doc36897d2023-12-06 01:27:54 +00003043 * started and stopped with broadcast hardware encoding config taken from
3044 * provider info
3045 */
3046TEST_P(
3047 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3048 StartAndEndLeAudioBroadcastSessionWithPossibleUnicastConfigFromProviderInfo) {
3049 if (!IsBroadcastOffloadProviderInfoSupported()) {
3050 return;
3051 }
3052
3053 auto lc3_codec_configs = GetBroadcastLc3SupportedListFromProviderInfo();
3054 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
3055 .codecType = CodecType::LC3,
3056 .streamMap = {},
3057 };
3058
3059 for (auto& lc3_config : lc3_codec_configs) {
3060 le_audio_broadcast_config.streamMap.resize(1);
3061 le_audio_broadcast_config.streamMap[0]
3062 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
3063 lc3_config);
3064 le_audio_broadcast_config.streamMap[0].streamHandle = 0x0;
3065 le_audio_broadcast_config.streamMap[0].pcmStreamId = 0x0;
3066 le_audio_broadcast_config.streamMap[0].audioChannelAllocation = 0x1 << 0;
3067
3068 DataMQDesc mq_desc;
3069 auto aidl_retval = audio_provider_->startSession(
3070 audio_port_, AudioConfiguration(le_audio_broadcast_config),
3071 latency_modes, &mq_desc);
3072
3073 ASSERT_TRUE(aidl_retval.isOk());
3074 EXPECT_TRUE(audio_provider_->endSession().isOk());
3075 }
3076}
3077
Bao Do5b2fdab2023-11-20 08:02:55 +00003078TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3079 GetEmptyBroadcastConfigurationEmptyCapability) {
3080 std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
3081 IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement
3082 empty_requirement;
3083
3084 IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting* configuration =
3085 new IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting();
3086
3087 // Check empty capability for source direction
3088 auto aidl_retval = audio_provider_->getLeAudioBroadcastConfiguration(
3089 empty_capability, empty_requirement, configuration);
3090
3091 ASSERT_TRUE(aidl_retval.isOk());
3092}
3093
Bao Doc36897d2023-12-06 01:27:54 +00003094/**
3095 * Test whether each provider of type
3096 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
Alice Kuo336d90c2022-02-16 09:09:59 +08003097 * started and stopped with broadcast hardware encoding config
3098 */
3099TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3100 StartAndEndLeAudioBroadcastSessionWithPossibleBroadcastConfig) {
3101 if (!IsBroadcastOffloadSupported()) {
3102 return;
3103 }
3104
3105 auto lc3_codec_configs = GetBroadcastLc3SupportedList(true /* supported */);
3106 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
3107 .codecType = CodecType::LC3,
3108 .streamMap = {},
3109 };
3110
3111 for (auto& lc3_config : lc3_codec_configs) {
Patty Huangac077ef2022-11-23 14:45:15 +08003112 le_audio_broadcast_config.streamMap.resize(1);
Alice Kuo336d90c2022-02-16 09:09:59 +08003113 le_audio_broadcast_config.streamMap[0]
3114 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
3115 lc3_config);
Rongxuan Liuc1aea322023-01-26 17:14:54 +00003116 le_audio_broadcast_config.streamMap[0].streamHandle = 0x0;
3117 le_audio_broadcast_config.streamMap[0].pcmStreamId = 0x0;
3118 le_audio_broadcast_config.streamMap[0].audioChannelAllocation = 0x1 << 0;
3119
Alice Kuo336d90c2022-02-16 09:09:59 +08003120 DataMQDesc mq_desc;
3121 auto aidl_retval = audio_provider_->startSession(
Chen Chen60d52e42022-02-16 12:19:12 -08003122 audio_port_, AudioConfiguration(le_audio_broadcast_config),
3123 latency_modes, &mq_desc);
Alice Kuo336d90c2022-02-16 09:09:59 +08003124
3125 ASSERT_TRUE(aidl_retval.isOk());
3126 EXPECT_TRUE(audio_provider_->endSession().isOk());
3127 }
3128}
3129
3130/**
3131 * Test whether each provider of type
3132 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
3133 * started and stopped with Broadcast hardware encoding config
3134 *
3135 * Disabled since offload codec checking is not ready
3136 */
3137TEST_P(
3138 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3139 DISABLED_StartAndEndLeAudioBroadcastSessionWithInvalidAudioConfiguration) {
3140 if (!IsBroadcastOffloadSupported()) {
3141 return;
3142 }
3143
3144 auto lc3_codec_configs = GetBroadcastLc3SupportedList(false /* supported */);
3145 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
3146 .codecType = CodecType::LC3,
3147 .streamMap = {},
3148 };
3149
3150 for (auto& lc3_config : lc3_codec_configs) {
3151 le_audio_broadcast_config.streamMap[0]
3152 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
3153 lc3_config);
3154 DataMQDesc mq_desc;
3155 auto aidl_retval = audio_provider_->startSession(
Chen Chen60d52e42022-02-16 12:19:12 -08003156 audio_port_, AudioConfiguration(le_audio_broadcast_config),
3157 latency_modes, &mq_desc);
Alice Kuo336d90c2022-02-16 09:09:59 +08003158
3159 // AIDL call should fail on invalid codec
3160 ASSERT_FALSE(aidl_retval.isOk());
3161 EXPECT_TRUE(audio_provider_->endSession().isOk());
3162 }
3163}
3164
Alice Kuoadcceec2022-03-28 13:28:43 +08003165/**
3166 * openProvider A2DP_SOFTWARE_DECODING_DATAPATH
3167 */
3168class BluetoothAudioProviderA2dpDecodingSoftwareAidl
3169 : public BluetoothAudioProviderFactoryAidl {
3170 public:
3171 virtual void SetUp() override {
3172 BluetoothAudioProviderFactoryAidl::SetUp();
3173 GetProviderCapabilitiesHelper(SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
3174 OpenProviderHelper(SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
3175 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
3176 audio_provider_ != nullptr);
3177 }
3178
3179 virtual void TearDown() override {
3180 audio_port_ = nullptr;
3181 audio_provider_ = nullptr;
3182 BluetoothAudioProviderFactoryAidl::TearDown();
3183 }
3184};
3185
3186/**
3187 * Test whether we can open a provider of type
3188 */
3189TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,
3190 OpenA2dpDecodingSoftwareProvider) {}
3191
3192/**
3193 * Test whether each provider of type
3194 * SessionType::A2DP_SOFTWARE_DECODING_DATAPATH can be started and stopped with
3195 * different PCM config
3196 */
3197TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,
3198 StartAndEndA2dpDecodingSoftwareSessionWithPossiblePcmConfig) {
3199 for (auto sample_rate : a2dp_sample_rates) {
3200 for (auto bits_per_sample : a2dp_bits_per_samples) {
3201 for (auto channel_mode : a2dp_channel_modes) {
3202 PcmConfiguration pcm_config{
3203 .sampleRateHz = sample_rate,
Alice Kuoadcceec2022-03-28 13:28:43 +08003204 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00003205 .bitsPerSample = bits_per_sample,
Alice Kuoadcceec2022-03-28 13:28:43 +08003206 };
3207 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
3208 DataMQDesc mq_desc;
3209 auto aidl_retval = audio_provider_->startSession(
3210 audio_port_, AudioConfiguration(pcm_config), latency_modes,
3211 &mq_desc);
3212 DataMQ data_mq(mq_desc);
3213
3214 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
3215 if (is_codec_config_valid) {
3216 EXPECT_TRUE(data_mq.isValid());
3217 }
3218 EXPECT_TRUE(audio_provider_->endSession().isOk());
3219 }
3220 }
3221 }
3222}
3223
3224/**
3225 * openProvider A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH
3226 */
3227class BluetoothAudioProviderA2dpDecodingHardwareAidl
3228 : public BluetoothAudioProviderFactoryAidl {
3229 public:
3230 virtual void SetUp() override {
3231 BluetoothAudioProviderFactoryAidl::SetUp();
3232 GetProviderCapabilitiesHelper(
3233 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
3234 OpenProviderHelper(SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
3235 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
3236 audio_provider_ != nullptr);
3237 }
3238
3239 virtual void TearDown() override {
3240 audio_port_ = nullptr;
3241 audio_provider_ = nullptr;
3242 BluetoothAudioProviderFactoryAidl::TearDown();
3243 }
3244
3245 bool IsOffloadSupported() { return (temp_provider_capabilities_.size() > 0); }
3246};
3247
3248/**
3249 * Test whether we can open a provider of type
3250 */
3251TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3252 OpenA2dpDecodingHardwareProvider) {}
3253
3254/**
3255 * Test whether each provider of type
3256 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
3257 * SBC hardware encoding config
3258 */
3259TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3260 StartAndEndA2dpSbcDecodingHardwareSession) {
3261 if (!IsOffloadSupported()) {
3262 return;
3263 }
3264
3265 CodecConfiguration codec_config = {
3266 .codecType = CodecType::SBC,
3267 .encodedAudioBitrate = 328000,
3268 .peerMtu = 1005,
3269 .isScmstEnabled = false,
3270 };
3271 auto sbc_codec_specifics = GetSbcCodecSpecificSupportedList(true);
3272
3273 for (auto& codec_specific : sbc_codec_specifics) {
3274 copy_codec_specific(codec_config.config, codec_specific);
3275 DataMQDesc mq_desc;
3276 auto aidl_retval = audio_provider_->startSession(
3277 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
3278
3279 ASSERT_TRUE(aidl_retval.isOk());
3280 EXPECT_TRUE(audio_provider_->endSession().isOk());
3281 }
3282}
3283
3284/**
3285 * Test whether each provider of type
3286 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
3287 * AAC hardware encoding config
3288 */
3289TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3290 StartAndEndA2dpAacDecodingHardwareSession) {
3291 if (!IsOffloadSupported()) {
3292 return;
3293 }
3294
3295 CodecConfiguration codec_config = {
3296 .codecType = CodecType::AAC,
3297 .encodedAudioBitrate = 320000,
3298 .peerMtu = 1005,
3299 .isScmstEnabled = false,
3300 };
3301 auto aac_codec_specifics = GetAacCodecSpecificSupportedList(true);
3302
3303 for (auto& codec_specific : aac_codec_specifics) {
3304 copy_codec_specific(codec_config.config, codec_specific);
3305 DataMQDesc mq_desc;
3306 auto aidl_retval = audio_provider_->startSession(
3307 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
3308
3309 ASSERT_TRUE(aidl_retval.isOk());
3310 EXPECT_TRUE(audio_provider_->endSession().isOk());
3311 }
3312}
3313
3314/**
3315 * Test whether each provider of type
3316 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
3317 * LDAC hardware encoding config
3318 */
3319TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3320 StartAndEndA2dpLdacDecodingHardwareSession) {
3321 if (!IsOffloadSupported()) {
3322 return;
3323 }
3324
3325 CodecConfiguration codec_config = {
3326 .codecType = CodecType::LDAC,
3327 .encodedAudioBitrate = 990000,
3328 .peerMtu = 1005,
3329 .isScmstEnabled = false,
3330 };
3331 auto ldac_codec_specifics = GetLdacCodecSpecificSupportedList(true);
3332
3333 for (auto& codec_specific : ldac_codec_specifics) {
3334 copy_codec_specific(codec_config.config, codec_specific);
3335 DataMQDesc mq_desc;
3336 auto aidl_retval = audio_provider_->startSession(
3337 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
3338
3339 ASSERT_TRUE(aidl_retval.isOk());
3340 EXPECT_TRUE(audio_provider_->endSession().isOk());
3341 }
3342}
3343
3344/**
3345 * Test whether each provider of type
3346 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
Omer Osmana2587da2022-05-01 03:54:11 +00003347 * Opus hardware encoding config
Alice Kuoadcceec2022-03-28 13:28:43 +08003348 */
3349TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
Omer Osmana2587da2022-05-01 03:54:11 +00003350 StartAndEndA2dpOpusDecodingHardwareSession) {
Alice Kuoadcceec2022-03-28 13:28:43 +08003351 if (!IsOffloadSupported()) {
3352 return;
3353 }
3354
3355 CodecConfiguration codec_config = {
Omer Osmana2587da2022-05-01 03:54:11 +00003356 .codecType = CodecType::OPUS,
Alice Kuoadcceec2022-03-28 13:28:43 +08003357 .encodedAudioBitrate = 990000,
3358 .peerMtu = 1005,
3359 .isScmstEnabled = false,
3360 };
Omer Osmana2587da2022-05-01 03:54:11 +00003361 auto opus_codec_specifics = GetOpusCodecSpecificSupportedList(true);
Alice Kuoadcceec2022-03-28 13:28:43 +08003362
Omer Osmana2587da2022-05-01 03:54:11 +00003363 for (auto& codec_specific : opus_codec_specifics) {
Alice Kuoadcceec2022-03-28 13:28:43 +08003364 copy_codec_specific(codec_config.config, codec_specific);
3365 DataMQDesc mq_desc;
3366 auto aidl_retval = audio_provider_->startSession(
3367 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
3368
3369 ASSERT_TRUE(aidl_retval.isOk());
3370 EXPECT_TRUE(audio_provider_->endSession().isOk());
3371 }
3372}
3373
3374/**
3375 * Test whether each provider of type
3376 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
3377 * AptX hardware encoding config
3378 */
3379TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3380 StartAndEndA2dpAptxDecodingHardwareSession) {
3381 if (!IsOffloadSupported()) {
3382 return;
3383 }
3384
3385 for (auto codec_type : {CodecType::APTX, CodecType::APTX_HD}) {
3386 CodecConfiguration codec_config = {
3387 .codecType = codec_type,
3388 .encodedAudioBitrate =
3389 (codec_type == CodecType::APTX ? 352000 : 576000),
3390 .peerMtu = 1005,
3391 .isScmstEnabled = false,
3392 };
3393
3394 auto aptx_codec_specifics = GetAptxCodecSpecificSupportedList(
3395 (codec_type == CodecType::APTX_HD ? true : false), true);
3396
3397 for (auto& codec_specific : aptx_codec_specifics) {
3398 copy_codec_specific(codec_config.config, codec_specific);
3399 DataMQDesc mq_desc;
3400 auto aidl_retval = audio_provider_->startSession(
3401 audio_port_, AudioConfiguration(codec_config), latency_modes,
3402 &mq_desc);
3403
3404 ASSERT_TRUE(aidl_retval.isOk());
3405 EXPECT_TRUE(audio_provider_->endSession().isOk());
3406 }
3407 }
3408}
3409
3410/**
3411 * Test whether each provider of type
3412 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
3413 * an invalid codec config
3414 */
3415TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3416 StartAndEndA2dpDecodingHardwareSessionInvalidCodecConfig) {
3417 if (!IsOffloadSupported()) {
3418 return;
3419 }
3420 ASSERT_NE(audio_provider_, nullptr);
3421
3422 std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
Sagar Verma62df9102022-12-07 17:56:04 +05303423 for (auto codec_type : ndk::enum_range<CodecType>()) {
Alice Kuoadcceec2022-03-28 13:28:43 +08003424 switch (codec_type) {
3425 case CodecType::SBC:
3426 codec_specifics = GetSbcCodecSpecificSupportedList(false);
3427 break;
3428 case CodecType::AAC:
3429 codec_specifics = GetAacCodecSpecificSupportedList(false);
3430 break;
3431 case CodecType::LDAC:
3432 codec_specifics = GetLdacCodecSpecificSupportedList(false);
3433 break;
3434 case CodecType::APTX:
3435 codec_specifics = GetAptxCodecSpecificSupportedList(false, false);
3436 break;
3437 case CodecType::APTX_HD:
3438 codec_specifics = GetAptxCodecSpecificSupportedList(true, false);
3439 break;
Omer Osmana2587da2022-05-01 03:54:11 +00003440 case CodecType::OPUS:
3441 codec_specifics = GetOpusCodecSpecificSupportedList(false);
Alice Kuoadcceec2022-03-28 13:28:43 +08003442 continue;
3443 case CodecType::APTX_ADAPTIVE:
Sagar Verma62df9102022-12-07 17:56:04 +05303444 case CodecType::APTX_ADAPTIVE_LE:
3445 case CodecType::APTX_ADAPTIVE_LEX:
Omer Osmana2587da2022-05-01 03:54:11 +00003446 case CodecType::LC3:
Alice Kuoadcceec2022-03-28 13:28:43 +08003447 case CodecType::VENDOR:
3448 case CodecType::UNKNOWN:
3449 codec_specifics.clear();
3450 break;
3451 }
3452 if (codec_specifics.empty()) {
3453 continue;
3454 }
3455
3456 CodecConfiguration codec_config = {
3457 .codecType = codec_type,
3458 .encodedAudioBitrate = 328000,
3459 .peerMtu = 1005,
3460 .isScmstEnabled = false,
3461 };
3462 for (auto codec_specific : codec_specifics) {
3463 copy_codec_specific(codec_config.config, codec_specific);
3464 DataMQDesc mq_desc;
3465 auto aidl_retval = audio_provider_->startSession(
3466 audio_port_, AudioConfiguration(codec_config), latency_modes,
3467 &mq_desc);
3468
3469 // AIDL call should fail on invalid codec
3470 ASSERT_FALSE(aidl_retval.isOk());
3471 EXPECT_TRUE(audio_provider_->endSession().isOk());
3472 }
3473 }
3474}
3475
Josh Wu049e2cd2022-01-12 05:42:58 -08003476GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3477 BluetoothAudioProviderFactoryAidl);
3478INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderFactoryAidl,
3479 testing::ValuesIn(android::getAidlHalInstanceNames(
3480 IBluetoothAudioProviderFactory::descriptor)),
3481 android::PrintInstanceNameToString);
3482
Antoine SOULIER33c4e5a2023-09-28 21:59:19 +00003483GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothAudioProviderAidl);
3484INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderAidl,
3485 testing::ValuesIn(android::getAidlHalInstanceNames(
3486 IBluetoothAudioProviderFactory::descriptor)),
3487 android::PrintInstanceNameToString);
3488
Josh Wu049e2cd2022-01-12 05:42:58 -08003489GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
Alice Kuoadcceec2022-03-28 13:28:43 +08003490 BluetoothAudioProviderA2dpEncodingSoftwareAidl);
3491INSTANTIATE_TEST_SUITE_P(PerInstance,
3492 BluetoothAudioProviderA2dpEncodingSoftwareAidl,
Josh Wu049e2cd2022-01-12 05:42:58 -08003493 testing::ValuesIn(android::getAidlHalInstanceNames(
3494 IBluetoothAudioProviderFactory::descriptor)),
3495 android::PrintInstanceNameToString);
3496
3497GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
Alice Kuoadcceec2022-03-28 13:28:43 +08003498 BluetoothAudioProviderA2dpEncodingHardwareAidl);
3499INSTANTIATE_TEST_SUITE_P(PerInstance,
3500 BluetoothAudioProviderA2dpEncodingHardwareAidl,
Josh Wu049e2cd2022-01-12 05:42:58 -08003501 testing::ValuesIn(android::getAidlHalInstanceNames(
3502 IBluetoothAudioProviderFactory::descriptor)),
3503 android::PrintInstanceNameToString);
3504
3505GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3506 BluetoothAudioProviderHearingAidSoftwareAidl);
3507INSTANTIATE_TEST_SUITE_P(PerInstance,
3508 BluetoothAudioProviderHearingAidSoftwareAidl,
3509 testing::ValuesIn(android::getAidlHalInstanceNames(
3510 IBluetoothAudioProviderFactory::descriptor)),
3511 android::PrintInstanceNameToString);
3512
3513GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3514 BluetoothAudioProviderLeAudioOutputSoftwareAidl);
3515INSTANTIATE_TEST_SUITE_P(PerInstance,
3516 BluetoothAudioProviderLeAudioOutputSoftwareAidl,
3517 testing::ValuesIn(android::getAidlHalInstanceNames(
3518 IBluetoothAudioProviderFactory::descriptor)),
3519 android::PrintInstanceNameToString);
3520
3521GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3522 BluetoothAudioProviderLeAudioInputSoftwareAidl);
3523INSTANTIATE_TEST_SUITE_P(PerInstance,
3524 BluetoothAudioProviderLeAudioInputSoftwareAidl,
3525 testing::ValuesIn(android::getAidlHalInstanceNames(
3526 IBluetoothAudioProviderFactory::descriptor)),
3527 android::PrintInstanceNameToString);
3528
3529GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3530 BluetoothAudioProviderLeAudioOutputHardwareAidl);
3531INSTANTIATE_TEST_SUITE_P(PerInstance,
3532 BluetoothAudioProviderLeAudioOutputHardwareAidl,
3533 testing::ValuesIn(android::getAidlHalInstanceNames(
3534 IBluetoothAudioProviderFactory::descriptor)),
3535 android::PrintInstanceNameToString);
3536
3537GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3538 BluetoothAudioProviderLeAudioInputHardwareAidl);
3539INSTANTIATE_TEST_SUITE_P(PerInstance,
3540 BluetoothAudioProviderLeAudioInputHardwareAidl,
3541 testing::ValuesIn(android::getAidlHalInstanceNames(
3542 IBluetoothAudioProviderFactory::descriptor)),
3543 android::PrintInstanceNameToString);
3544
3545GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3546 BluetoothAudioProviderLeAudioBroadcastSoftwareAidl);
3547INSTANTIATE_TEST_SUITE_P(PerInstance,
3548 BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
3549 testing::ValuesIn(android::getAidlHalInstanceNames(
3550 IBluetoothAudioProviderFactory::descriptor)),
3551 android::PrintInstanceNameToString);
3552
Alice Kuo336d90c2022-02-16 09:09:59 +08003553GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3554 BluetoothAudioProviderLeAudioBroadcastHardwareAidl);
3555INSTANTIATE_TEST_SUITE_P(PerInstance,
3556 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3557 testing::ValuesIn(android::getAidlHalInstanceNames(
3558 IBluetoothAudioProviderFactory::descriptor)),
3559 android::PrintInstanceNameToString);
Josh Wu049e2cd2022-01-12 05:42:58 -08003560
Alice Kuoadcceec2022-03-28 13:28:43 +08003561GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3562 BluetoothAudioProviderA2dpDecodingSoftwareAidl);
3563INSTANTIATE_TEST_SUITE_P(PerInstance,
3564 BluetoothAudioProviderA2dpDecodingSoftwareAidl,
3565 testing::ValuesIn(android::getAidlHalInstanceNames(
3566 IBluetoothAudioProviderFactory::descriptor)),
3567 android::PrintInstanceNameToString);
3568
3569GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3570 BluetoothAudioProviderA2dpDecodingHardwareAidl);
3571INSTANTIATE_TEST_SUITE_P(PerInstance,
3572 BluetoothAudioProviderA2dpDecodingHardwareAidl,
3573 testing::ValuesIn(android::getAidlHalInstanceNames(
3574 IBluetoothAudioProviderFactory::descriptor)),
3575 android::PrintInstanceNameToString);
3576
Bao Do72399432023-11-09 08:13:05 +00003577GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3578 BluetoothAudioProviderHfpHardwareAidl);
3579INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderHfpHardwareAidl,
3580 testing::ValuesIn(android::getAidlHalInstanceNames(
3581 IBluetoothAudioProviderFactory::descriptor)),
3582 android::PrintInstanceNameToString);
3583
3584GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3585 BluetoothAudioProviderHfpSoftwareDecodingAidl);
3586INSTANTIATE_TEST_SUITE_P(PerInstance,
3587 BluetoothAudioProviderHfpSoftwareDecodingAidl,
3588 testing::ValuesIn(android::getAidlHalInstanceNames(
3589 IBluetoothAudioProviderFactory::descriptor)),
3590 android::PrintInstanceNameToString);
3591
3592GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3593 BluetoothAudioProviderHfpSoftwareEncodingAidl);
3594INSTANTIATE_TEST_SUITE_P(PerInstance,
3595 BluetoothAudioProviderHfpSoftwareEncodingAidl,
3596 testing::ValuesIn(android::getAidlHalInstanceNames(
3597 IBluetoothAudioProviderFactory::descriptor)),
3598 android::PrintInstanceNameToString);
3599
Josh Wu049e2cd2022-01-12 05:42:58 -08003600int main(int argc, char** argv) {
3601 ::testing::InitGoogleTest(&argc, argv);
3602 ABinderProcess_setThreadPoolMaxThreadCount(1);
3603 ABinderProcess_startThreadPool();
3604 return RUN_ALL_TESTS();
3605}