blob: bdcfbd7b709919d3fc8573b8a23b6c151986aa24 [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()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00001667 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08001668 }
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()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00001697 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08001698 }
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()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00001727 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08001728 }
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()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00001757 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08001758 }
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()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00001787 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08001788 }
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()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00001823 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08001824 }
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()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002423 GTEST_SKIP();
Bao Doc36897d2023-12-06 01:27:54 +00002424 }
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}
2509/**
2510 * Test whether each provider of type
2511 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002512 * stopped with Unicast hardware encoding config
2513 */
2514TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2515 StartAndEndLeAudioOutputSessionWithPossibleUnicastConfig) {
2516 if (!IsOffloadOutputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002517 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08002518 }
2519
2520 auto lc3_codec_configs =
2521 GetUnicastLc3SupportedList(false /* decoding */, true /* supported */);
2522 LeAudioConfiguration le_audio_config = {
2523 .codecType = CodecType::LC3,
2524 .peerDelayUs = 0,
2525 };
2526
2527 for (auto& lc3_config : lc3_codec_configs) {
2528 le_audio_config.leAudioCodecConfig
2529 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2530 DataMQDesc mq_desc;
2531 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002532 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2533 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002534
2535 ASSERT_TRUE(aidl_retval.isOk());
2536 EXPECT_TRUE(audio_provider_->endSession().isOk());
2537 }
2538}
2539
2540/**
2541 * Test whether each provider of type
2542 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2543 * stopped with Unicast hardware encoding config
2544 *
2545 * Disabled since offload codec checking is not ready
2546 */
2547TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2548 DISABLED_StartAndEndLeAudioOutputSessionWithInvalidAudioConfiguration) {
2549 if (!IsOffloadOutputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002550 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08002551 }
2552
2553 auto lc3_codec_configs =
2554 GetUnicastLc3SupportedList(false /* decoding */, false /* supported */);
2555 LeAudioConfiguration le_audio_config = {
2556 .codecType = CodecType::LC3,
2557 .peerDelayUs = 0,
2558 };
2559
2560 for (auto& lc3_config : lc3_codec_configs) {
2561 le_audio_config.leAudioCodecConfig
2562 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2563 DataMQDesc mq_desc;
2564 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002565 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2566 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002567
2568 // AIDL call should fail on invalid codec
2569 ASSERT_FALSE(aidl_retval.isOk());
2570 EXPECT_TRUE(audio_provider_->endSession().isOk());
2571 }
2572}
2573
Sagar Verma62df9102022-12-07 17:56:04 +05302574static std::vector<uint8_t> vendorMetadata = {0x0B, // Length
2575 0xFF, // Type: Vendor-specific
2576 0x0A, 0x00, // Company_ID
2577 0x01, 0x02, 0x03, 0x04, // Data
2578 0x05, 0x06, 0x07, 0x08};
2579
2580/**
2581 * Test whether each provider of type
2582 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2583 * stopped with Unicast hardware encoding config
2584 */
2585TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2586 StartAndEndLeAudioOutputSessionWithAptxAdaptiveLeUnicastConfig) {
2587 if (!IsOffloadOutputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002588 GTEST_SKIP();
Sagar Verma62df9102022-12-07 17:56:04 +05302589 }
2590 for (auto codec_type :
2591 {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
2592 bool is_le_extended = (codec_type == CodecType::APTX_ADAPTIVE_LEX);
2593 auto aptx_adaptive_le_codec_configs =
2594 GetUnicastAptxAdaptiveLeSupportedList(false, true, is_le_extended);
2595 LeAudioConfiguration le_audio_config = {
2596 .codecType = codec_type,
2597 .peerDelayUs = 0,
2598 .vendorSpecificMetadata = vendorMetadata,
2599 };
2600
2601 for (auto& aptx_adaptive_le_config : aptx_adaptive_le_codec_configs) {
2602 le_audio_config.leAudioCodecConfig
2603 .set<LeAudioCodecConfiguration::aptxAdaptiveLeConfig>(
2604 aptx_adaptive_le_config);
2605 DataMQDesc mq_desc;
2606 auto aidl_retval = audio_provider_->startSession(
2607 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2608 &mq_desc);
2609
2610 ASSERT_TRUE(aidl_retval.isOk());
2611 EXPECT_TRUE(audio_provider_->endSession().isOk());
2612 }
2613 }
2614}
2615
2616/**
2617 * Test whether each provider of type
2618 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2619 * stopped with Unicast hardware encoding config
2620 */
2621TEST_P(
2622 BluetoothAudioProviderLeAudioOutputHardwareAidl,
2623 BluetoothAudioProviderLeAudioOutputHardwareAidl_StartAndEndLeAudioOutputSessionWithInvalidAptxAdaptiveLeAudioConfiguration) {
2624 if (!IsOffloadOutputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002625 GTEST_SKIP();
Sagar Verma62df9102022-12-07 17:56:04 +05302626 }
2627
2628 for (auto codec_type :
2629 {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
2630 bool is_le_extended = (codec_type == CodecType::APTX_ADAPTIVE_LEX);
2631 auto aptx_adaptive_le_codec_configs =
2632 GetUnicastAptxAdaptiveLeSupportedList(false, true, is_le_extended);
2633 LeAudioConfiguration le_audio_config = {
2634 .codecType = codec_type,
2635 .peerDelayUs = 0,
2636 .vendorSpecificMetadata = vendorMetadata,
2637 };
2638
2639 for (auto& aptx_adaptive_le_config : aptx_adaptive_le_codec_configs) {
2640 le_audio_config.leAudioCodecConfig
2641 .set<LeAudioCodecConfiguration::aptxAdaptiveLeConfig>(
2642 aptx_adaptive_le_config);
2643 DataMQDesc mq_desc;
2644 auto aidl_retval = audio_provider_->startSession(
2645 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2646 &mq_desc);
2647
2648 // AIDL call should fail on invalid codec
2649 ASSERT_FALSE(aidl_retval.isOk());
2650 EXPECT_TRUE(audio_provider_->endSession().isOk());
2651 }
2652 }
2653}
2654
Josh Wu049e2cd2022-01-12 05:42:58 -08002655/**
2656 * openProvider LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH
2657 */
2658class BluetoothAudioProviderLeAudioInputHardwareAidl
2659 : public BluetoothAudioProviderLeAudioOutputHardwareAidl {
2660 public:
2661 virtual void SetUp() override {
2662 BluetoothAudioProviderFactoryAidl::SetUp();
2663 GetProviderCapabilitiesHelper(
2664 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
Bao Doc36897d2023-12-06 01:27:54 +00002665 GetProviderInfoHelper(
2666 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
Josh Wu049e2cd2022-01-12 05:42:58 -08002667 OpenProviderHelper(
2668 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
2669 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
2670 audio_provider_ != nullptr);
2671 }
2672
2673 bool IsOffloadInputSupported() {
2674 for (auto& capability : temp_provider_capabilities_) {
2675 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2676 continue;
2677 }
2678 auto& le_audio_capability =
2679 capability.get<AudioCapabilities::leAudioCapabilities>();
2680 if (le_audio_capability.unicastDecodeCapability.codecType !=
2681 CodecType::UNKNOWN)
2682 return true;
2683 }
2684 return false;
2685 }
2686
2687 virtual void TearDown() override {
2688 audio_port_ = nullptr;
2689 audio_provider_ = nullptr;
2690 BluetoothAudioProviderFactoryAidl::TearDown();
2691 }
2692};
2693
2694/**
2695 * Test whether each provider of type
Bao Doc36897d2023-12-06 01:27:54 +00002696 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002697 * stopped
2698 */
2699TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
2700 OpenLeAudioInputHardwareProvider) {}
2701
2702/**
2703 * Test whether each provider of type
Bao Doc36897d2023-12-06 01:27:54 +00002704 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
2705 * stopped with Unicast hardware encoding config taken from provider info
2706 */
2707TEST_P(
2708 BluetoothAudioProviderLeAudioInputHardwareAidl,
2709 StartAndEndLeAudioInputSessionWithPossibleUnicastConfigFromProviderInfo) {
2710 if (!IsOffloadOutputProviderInfoSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002711 GTEST_SKIP();
Bao Doc36897d2023-12-06 01:27:54 +00002712 }
2713
2714 auto lc3_codec_configs = GetUnicastLc3SupportedListFromProviderInfo();
2715 LeAudioConfiguration le_audio_config = {
2716 .codecType = CodecType::LC3,
2717 .peerDelayUs = 0,
2718 };
2719
2720 for (auto& lc3_config : lc3_codec_configs) {
2721 le_audio_config.leAudioCodecConfig
2722 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2723 DataMQDesc mq_desc;
2724 auto aidl_retval = audio_provider_->startSession(
2725 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2726 &mq_desc);
2727
2728 ASSERT_TRUE(aidl_retval.isOk());
2729 EXPECT_TRUE(audio_provider_->endSession().isOk());
2730 }
2731}
2732
2733/**
2734 * Test whether each provider of type
2735 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002736 * stopped with Unicast hardware encoding config
2737 */
2738TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
2739 StartAndEndLeAudioInputSessionWithPossibleUnicastConfig) {
2740 if (!IsOffloadInputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002741 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08002742 }
2743
2744 auto lc3_codec_configs =
2745 GetUnicastLc3SupportedList(true /* decoding */, true /* supported */);
2746 LeAudioConfiguration le_audio_config = {
2747 .codecType = CodecType::LC3,
2748 .peerDelayUs = 0,
2749 };
2750
2751 for (auto& lc3_config : lc3_codec_configs) {
2752 le_audio_config.leAudioCodecConfig
2753 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2754 DataMQDesc mq_desc;
2755 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002756 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2757 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002758
2759 ASSERT_TRUE(aidl_retval.isOk());
2760 EXPECT_TRUE(audio_provider_->endSession().isOk());
2761 }
2762}
2763
2764/**
2765 * Test whether each provider of type
Bao Doc36897d2023-12-06 01:27:54 +00002766 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002767 * stopped with Unicast hardware encoding config
2768 *
2769 * Disabled since offload codec checking is not ready
2770 */
2771TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
2772 DISABLED_StartAndEndLeAudioInputSessionWithInvalidAudioConfiguration) {
2773 if (!IsOffloadInputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002774 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08002775 }
2776
2777 auto lc3_codec_configs =
2778 GetUnicastLc3SupportedList(true /* decoding */, false /* supported */);
2779 LeAudioConfiguration le_audio_config = {
2780 .codecType = CodecType::LC3,
2781 .peerDelayUs = 0,
2782 };
2783
2784 for (auto& lc3_config : lc3_codec_configs) {
2785 le_audio_config.leAudioCodecConfig
2786 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2787
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 // AIDL call should fail on invalid codec
2794 ASSERT_FALSE(aidl_retval.isOk());
2795 EXPECT_TRUE(audio_provider_->endSession().isOk());
2796 }
2797}
2798
2799/**
2800 * openProvider LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH
2801 */
2802class BluetoothAudioProviderLeAudioBroadcastSoftwareAidl
2803 : public BluetoothAudioProviderFactoryAidl {
2804 public:
2805 virtual void SetUp() override {
2806 BluetoothAudioProviderFactoryAidl::SetUp();
2807 GetProviderCapabilitiesHelper(
2808 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
2809 OpenProviderHelper(
2810 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
2811 ASSERT_NE(audio_provider_, nullptr);
2812 }
2813
2814 virtual void TearDown() override {
2815 audio_port_ = nullptr;
2816 audio_provider_ = nullptr;
2817 BluetoothAudioProviderFactoryAidl::TearDown();
2818 }
2819
2820 static constexpr int32_t le_audio_output_sample_rates_[] = {
2821 0, 8000, 16000, 24000, 32000, 44100, 48000,
2822 };
2823 static constexpr int8_t le_audio_output_bits_per_samples_[] = {0, 16, 24};
2824 static constexpr ChannelMode le_audio_output_channel_modes_[] = {
2825 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
2826 static constexpr int32_t le_audio_output_data_interval_us_[] = {
2827 0 /* Invalid */, 10000 /* Valid 10ms */};
2828};
2829
2830/**
2831 * Test whether each provider of type
2832 * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started and
2833 * stopped
2834 */
2835TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
Josh Wu3202eab2022-02-17 18:09:05 -08002836 OpenLeAudioOutputSoftwareProvider) {}
Josh Wu049e2cd2022-01-12 05:42:58 -08002837
2838/**
2839 * Test whether each provider of type
2840 * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started and
2841 * stopped with different PCM config
2842 */
2843TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
Josh Wu3202eab2022-02-17 18:09:05 -08002844 StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
Josh Wu049e2cd2022-01-12 05:42:58 -08002845 for (auto sample_rate : le_audio_output_sample_rates_) {
2846 for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
2847 for (auto channel_mode : le_audio_output_channel_modes_) {
2848 for (auto data_interval_us : le_audio_output_data_interval_us_) {
2849 PcmConfiguration pcm_config{
2850 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08002851 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00002852 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08002853 .dataIntervalUs = data_interval_us,
2854 };
Josh Wu8a1be762022-02-15 09:37:29 -08002855 bool is_codec_config_valid =
2856 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
Josh Wu049e2cd2022-01-12 05:42:58 -08002857 DataMQDesc mq_desc;
2858 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002859 audio_port_, AudioConfiguration(pcm_config), latency_modes,
2860 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002861 DataMQ data_mq(mq_desc);
2862
2863 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
2864 if (is_codec_config_valid) {
2865 EXPECT_TRUE(data_mq.isValid());
2866 }
2867 EXPECT_TRUE(audio_provider_->endSession().isOk());
2868 }
2869 }
2870 }
2871 }
2872}
2873
Alice Kuo336d90c2022-02-16 09:09:59 +08002874/**
2875 * openProvider LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH
2876 */
2877class BluetoothAudioProviderLeAudioBroadcastHardwareAidl
2878 : public BluetoothAudioProviderFactoryAidl {
2879 public:
2880 virtual void SetUp() override {
2881 BluetoothAudioProviderFactoryAidl::SetUp();
2882 GetProviderCapabilitiesHelper(
2883 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
Bao Doc36897d2023-12-06 01:27:54 +00002884 GetProviderInfoHelper(
2885 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
Alice Kuo336d90c2022-02-16 09:09:59 +08002886 OpenProviderHelper(
2887 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
2888 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
2889 audio_provider_ != nullptr);
2890 }
2891
2892 virtual void TearDown() override {
2893 audio_port_ = nullptr;
2894 audio_provider_ = nullptr;
2895 BluetoothAudioProviderFactoryAidl::TearDown();
2896 }
2897
2898 bool IsBroadcastOffloadSupported() {
2899 for (auto& capability : temp_provider_capabilities_) {
2900 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2901 continue;
2902 }
2903 auto& le_audio_capability =
2904 capability.get<AudioCapabilities::leAudioCapabilities>();
2905 if (le_audio_capability.broadcastCapability.codecType !=
2906 CodecType::UNKNOWN)
2907 return true;
2908 }
2909 return false;
2910 }
2911
Bao Doc36897d2023-12-06 01:27:54 +00002912 bool IsBroadcastOffloadProviderInfoSupported() {
2913 if (!temp_provider_info_.has_value()) return false;
2914 if (temp_provider_info_.value().codecInfos.empty()) return false;
2915 // Check if all codec info is of LeAudio type
2916 for (auto& codec_info : temp_provider_info_.value().codecInfos) {
2917 if (codec_info.transport.getTag() != CodecInfo::Transport::leAudio)
2918 return false;
2919 }
2920 return true;
2921 }
2922
2923 std::vector<Lc3Configuration> GetBroadcastLc3SupportedListFromProviderInfo() {
2924 std::vector<Lc3Configuration> le_audio_codec_configs;
2925 for (auto& codec_info : temp_provider_info_.value().codecInfos) {
2926 // Only gets LC3 codec information
2927 if (codec_info.id != CodecId::Core::LC3) continue;
2928 // Combine those parameters into one list of Lc3Configuration
2929 auto& transport =
2930 codec_info.transport.get<CodecInfo::Transport::Tag::leAudio>();
2931 for (int32_t samplingFrequencyHz : transport.samplingFrequencyHz) {
2932 for (int32_t frameDurationUs : transport.frameDurationUs) {
2933 for (int32_t octetsPerFrame : transport.bitdepth) {
2934 Lc3Configuration lc3_config = {
2935 .samplingFrequencyHz = samplingFrequencyHz,
2936 .frameDurationUs = frameDurationUs,
2937 .octetsPerFrame = octetsPerFrame,
2938 };
2939 le_audio_codec_configs.push_back(lc3_config);
2940 }
2941 }
2942 }
2943 }
2944
2945 return le_audio_codec_configs;
2946 }
2947
Alice Kuo336d90c2022-02-16 09:09:59 +08002948 std::vector<Lc3Configuration> GetBroadcastLc3SupportedList(bool supported) {
2949 std::vector<Lc3Configuration> le_audio_codec_configs;
2950 if (!supported) {
shihchienc3ab9f5e2022-09-23 08:18:05 +00002951 Lc3Configuration lc3_config{.pcmBitDepth = 0, .samplingFrequencyHz = 0};
Alice Kuo336d90c2022-02-16 09:09:59 +08002952 le_audio_codec_configs.push_back(lc3_config);
2953 return le_audio_codec_configs;
2954 }
2955
2956 // There might be more than one LeAudioCodecCapabilitiesSetting
2957 std::vector<Lc3Capabilities> lc3_capabilities;
2958 for (auto& capability : temp_provider_capabilities_) {
2959 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2960 continue;
2961 }
2962 auto& le_audio_capability =
2963 capability.get<AudioCapabilities::leAudioCapabilities>();
2964 auto& broadcast_capability = le_audio_capability.broadcastCapability;
2965 if (broadcast_capability.codecType != CodecType::LC3) {
2966 continue;
2967 }
2968 auto& lc3_capability = broadcast_capability.leAudioCodecCapabilities.get<
2969 BroadcastCapability::LeAudioCodecCapabilities::lc3Capabilities>();
2970 for (int idx = 0; idx < lc3_capability->size(); idx++)
2971 lc3_capabilities.push_back(*lc3_capability->at(idx));
2972 }
2973
2974 // Combine those parameters into one list of LeAudioCodecConfiguration
2975 // This seems horrible, but usually each Lc3Capability only contains a
2976 // single Lc3Configuration, which means every array has a length of 1.
2977 for (auto& lc3_capability : lc3_capabilities) {
2978 for (int32_t samplingFrequencyHz : lc3_capability.samplingFrequencyHz) {
2979 for (int32_t frameDurationUs : lc3_capability.frameDurationUs) {
2980 for (int32_t octetsPerFrame : lc3_capability.octetsPerFrame) {
2981 Lc3Configuration lc3_config = {
2982 .samplingFrequencyHz = samplingFrequencyHz,
2983 .frameDurationUs = frameDurationUs,
2984 .octetsPerFrame = octetsPerFrame,
2985 };
2986 le_audio_codec_configs.push_back(lc3_config);
2987 }
2988 }
2989 }
2990 }
2991
2992 return le_audio_codec_configs;
2993 }
2994
2995 LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
2996};
2997
2998/**
2999 * Test whether each provider of type
3000 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
3001 * started and stopped
3002 */
3003TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3004 OpenLeAudioOutputHardwareProvider) {}
3005
3006/**
3007 * Test whether each provider of type
3008 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
Bao Doc36897d2023-12-06 01:27:54 +00003009 * started and stopped with broadcast hardware encoding config taken from
3010 * provider info
3011 */
3012TEST_P(
3013 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3014 StartAndEndLeAudioBroadcastSessionWithPossibleUnicastConfigFromProviderInfo) {
3015 if (!IsBroadcastOffloadProviderInfoSupported()) {
3016 return;
3017 }
3018
3019 auto lc3_codec_configs = GetBroadcastLc3SupportedListFromProviderInfo();
3020 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
3021 .codecType = CodecType::LC3,
3022 .streamMap = {},
3023 };
3024
3025 for (auto& lc3_config : lc3_codec_configs) {
3026 le_audio_broadcast_config.streamMap.resize(1);
3027 le_audio_broadcast_config.streamMap[0]
3028 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
3029 lc3_config);
3030 le_audio_broadcast_config.streamMap[0].streamHandle = 0x0;
3031 le_audio_broadcast_config.streamMap[0].pcmStreamId = 0x0;
3032 le_audio_broadcast_config.streamMap[0].audioChannelAllocation = 0x1 << 0;
3033
3034 DataMQDesc mq_desc;
3035 auto aidl_retval = audio_provider_->startSession(
3036 audio_port_, AudioConfiguration(le_audio_broadcast_config),
3037 latency_modes, &mq_desc);
3038
3039 ASSERT_TRUE(aidl_retval.isOk());
3040 EXPECT_TRUE(audio_provider_->endSession().isOk());
3041 }
3042}
3043
Bao Do5b2fdab2023-11-20 08:02:55 +00003044TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3045 GetEmptyBroadcastConfigurationEmptyCapability) {
3046 std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
3047 IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement
3048 empty_requirement;
3049
3050 IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting* configuration =
3051 new IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting();
3052
3053 // Check empty capability for source direction
3054 auto aidl_retval = audio_provider_->getLeAudioBroadcastConfiguration(
3055 empty_capability, empty_requirement, configuration);
3056
3057 ASSERT_TRUE(aidl_retval.isOk());
3058}
3059
Bao Doc36897d2023-12-06 01:27:54 +00003060/**
3061 * Test whether each provider of type
3062 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
Alice Kuo336d90c2022-02-16 09:09:59 +08003063 * started and stopped with broadcast hardware encoding config
3064 */
3065TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3066 StartAndEndLeAudioBroadcastSessionWithPossibleBroadcastConfig) {
3067 if (!IsBroadcastOffloadSupported()) {
3068 return;
3069 }
3070
3071 auto lc3_codec_configs = GetBroadcastLc3SupportedList(true /* supported */);
3072 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
3073 .codecType = CodecType::LC3,
3074 .streamMap = {},
3075 };
3076
3077 for (auto& lc3_config : lc3_codec_configs) {
Patty Huangac077ef2022-11-23 14:45:15 +08003078 le_audio_broadcast_config.streamMap.resize(1);
Alice Kuo336d90c2022-02-16 09:09:59 +08003079 le_audio_broadcast_config.streamMap[0]
3080 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
3081 lc3_config);
Rongxuan Liuc1aea322023-01-26 17:14:54 +00003082 le_audio_broadcast_config.streamMap[0].streamHandle = 0x0;
3083 le_audio_broadcast_config.streamMap[0].pcmStreamId = 0x0;
3084 le_audio_broadcast_config.streamMap[0].audioChannelAllocation = 0x1 << 0;
3085
Alice Kuo336d90c2022-02-16 09:09:59 +08003086 DataMQDesc mq_desc;
3087 auto aidl_retval = audio_provider_->startSession(
Chen Chen60d52e42022-02-16 12:19:12 -08003088 audio_port_, AudioConfiguration(le_audio_broadcast_config),
3089 latency_modes, &mq_desc);
Alice Kuo336d90c2022-02-16 09:09:59 +08003090
3091 ASSERT_TRUE(aidl_retval.isOk());
3092 EXPECT_TRUE(audio_provider_->endSession().isOk());
3093 }
3094}
3095
3096/**
3097 * Test whether each provider of type
3098 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
3099 * started and stopped with Broadcast hardware encoding config
3100 *
3101 * Disabled since offload codec checking is not ready
3102 */
3103TEST_P(
3104 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3105 DISABLED_StartAndEndLeAudioBroadcastSessionWithInvalidAudioConfiguration) {
3106 if (!IsBroadcastOffloadSupported()) {
3107 return;
3108 }
3109
3110 auto lc3_codec_configs = GetBroadcastLc3SupportedList(false /* supported */);
3111 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
3112 .codecType = CodecType::LC3,
3113 .streamMap = {},
3114 };
3115
3116 for (auto& lc3_config : lc3_codec_configs) {
3117 le_audio_broadcast_config.streamMap[0]
3118 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
3119 lc3_config);
3120 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 // AIDL call should fail on invalid codec
3126 ASSERT_FALSE(aidl_retval.isOk());
3127 EXPECT_TRUE(audio_provider_->endSession().isOk());
3128 }
3129}
3130
Alice Kuoadcceec2022-03-28 13:28:43 +08003131/**
3132 * openProvider A2DP_SOFTWARE_DECODING_DATAPATH
3133 */
3134class BluetoothAudioProviderA2dpDecodingSoftwareAidl
3135 : public BluetoothAudioProviderFactoryAidl {
3136 public:
3137 virtual void SetUp() override {
3138 BluetoothAudioProviderFactoryAidl::SetUp();
3139 GetProviderCapabilitiesHelper(SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
3140 OpenProviderHelper(SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
3141 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
3142 audio_provider_ != nullptr);
3143 }
3144
3145 virtual void TearDown() override {
3146 audio_port_ = nullptr;
3147 audio_provider_ = nullptr;
3148 BluetoothAudioProviderFactoryAidl::TearDown();
3149 }
3150};
3151
3152/**
3153 * Test whether we can open a provider of type
3154 */
3155TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,
3156 OpenA2dpDecodingSoftwareProvider) {}
3157
3158/**
3159 * Test whether each provider of type
3160 * SessionType::A2DP_SOFTWARE_DECODING_DATAPATH can be started and stopped with
3161 * different PCM config
3162 */
3163TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,
3164 StartAndEndA2dpDecodingSoftwareSessionWithPossiblePcmConfig) {
3165 for (auto sample_rate : a2dp_sample_rates) {
3166 for (auto bits_per_sample : a2dp_bits_per_samples) {
3167 for (auto channel_mode : a2dp_channel_modes) {
3168 PcmConfiguration pcm_config{
3169 .sampleRateHz = sample_rate,
Alice Kuoadcceec2022-03-28 13:28:43 +08003170 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00003171 .bitsPerSample = bits_per_sample,
Alice Kuoadcceec2022-03-28 13:28:43 +08003172 };
3173 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
3174 DataMQDesc mq_desc;
3175 auto aidl_retval = audio_provider_->startSession(
3176 audio_port_, AudioConfiguration(pcm_config), latency_modes,
3177 &mq_desc);
3178 DataMQ data_mq(mq_desc);
3179
3180 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
3181 if (is_codec_config_valid) {
3182 EXPECT_TRUE(data_mq.isValid());
3183 }
3184 EXPECT_TRUE(audio_provider_->endSession().isOk());
3185 }
3186 }
3187 }
3188}
3189
3190/**
3191 * openProvider A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH
3192 */
3193class BluetoothAudioProviderA2dpDecodingHardwareAidl
3194 : public BluetoothAudioProviderFactoryAidl {
3195 public:
3196 virtual void SetUp() override {
3197 BluetoothAudioProviderFactoryAidl::SetUp();
3198 GetProviderCapabilitiesHelper(
3199 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
3200 OpenProviderHelper(SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
3201 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
3202 audio_provider_ != nullptr);
3203 }
3204
3205 virtual void TearDown() override {
3206 audio_port_ = nullptr;
3207 audio_provider_ = nullptr;
3208 BluetoothAudioProviderFactoryAidl::TearDown();
3209 }
3210
3211 bool IsOffloadSupported() { return (temp_provider_capabilities_.size() > 0); }
3212};
3213
3214/**
3215 * Test whether we can open a provider of type
3216 */
3217TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3218 OpenA2dpDecodingHardwareProvider) {}
3219
3220/**
3221 * Test whether each provider of type
3222 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
3223 * SBC hardware encoding config
3224 */
3225TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3226 StartAndEndA2dpSbcDecodingHardwareSession) {
3227 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003228 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08003229 }
3230
3231 CodecConfiguration codec_config = {
3232 .codecType = CodecType::SBC,
3233 .encodedAudioBitrate = 328000,
3234 .peerMtu = 1005,
3235 .isScmstEnabled = false,
3236 };
3237 auto sbc_codec_specifics = GetSbcCodecSpecificSupportedList(true);
3238
3239 for (auto& codec_specific : sbc_codec_specifics) {
3240 copy_codec_specific(codec_config.config, codec_specific);
3241 DataMQDesc mq_desc;
3242 auto aidl_retval = audio_provider_->startSession(
3243 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
3244
3245 ASSERT_TRUE(aidl_retval.isOk());
3246 EXPECT_TRUE(audio_provider_->endSession().isOk());
3247 }
3248}
3249
3250/**
3251 * Test whether each provider of type
3252 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
3253 * AAC hardware encoding config
3254 */
3255TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3256 StartAndEndA2dpAacDecodingHardwareSession) {
3257 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003258 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08003259 }
3260
3261 CodecConfiguration codec_config = {
3262 .codecType = CodecType::AAC,
3263 .encodedAudioBitrate = 320000,
3264 .peerMtu = 1005,
3265 .isScmstEnabled = false,
3266 };
3267 auto aac_codec_specifics = GetAacCodecSpecificSupportedList(true);
3268
3269 for (auto& codec_specific : aac_codec_specifics) {
3270 copy_codec_specific(codec_config.config, codec_specific);
3271 DataMQDesc mq_desc;
3272 auto aidl_retval = audio_provider_->startSession(
3273 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
3274
3275 ASSERT_TRUE(aidl_retval.isOk());
3276 EXPECT_TRUE(audio_provider_->endSession().isOk());
3277 }
3278}
3279
3280/**
3281 * Test whether each provider of type
3282 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
3283 * LDAC hardware encoding config
3284 */
3285TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3286 StartAndEndA2dpLdacDecodingHardwareSession) {
3287 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003288 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08003289 }
3290
3291 CodecConfiguration codec_config = {
3292 .codecType = CodecType::LDAC,
3293 .encodedAudioBitrate = 990000,
3294 .peerMtu = 1005,
3295 .isScmstEnabled = false,
3296 };
3297 auto ldac_codec_specifics = GetLdacCodecSpecificSupportedList(true);
3298
3299 for (auto& codec_specific : ldac_codec_specifics) {
3300 copy_codec_specific(codec_config.config, codec_specific);
3301 DataMQDesc mq_desc;
3302 auto aidl_retval = audio_provider_->startSession(
3303 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
3304
3305 ASSERT_TRUE(aidl_retval.isOk());
3306 EXPECT_TRUE(audio_provider_->endSession().isOk());
3307 }
3308}
3309
3310/**
3311 * Test whether each provider of type
3312 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
Omer Osmana2587da2022-05-01 03:54:11 +00003313 * Opus hardware encoding config
Alice Kuoadcceec2022-03-28 13:28:43 +08003314 */
3315TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
Omer Osmana2587da2022-05-01 03:54:11 +00003316 StartAndEndA2dpOpusDecodingHardwareSession) {
Alice Kuoadcceec2022-03-28 13:28:43 +08003317 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003318 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08003319 }
3320
3321 CodecConfiguration codec_config = {
Omer Osmana2587da2022-05-01 03:54:11 +00003322 .codecType = CodecType::OPUS,
Alice Kuoadcceec2022-03-28 13:28:43 +08003323 .encodedAudioBitrate = 990000,
3324 .peerMtu = 1005,
3325 .isScmstEnabled = false,
3326 };
Omer Osmana2587da2022-05-01 03:54:11 +00003327 auto opus_codec_specifics = GetOpusCodecSpecificSupportedList(true);
Alice Kuoadcceec2022-03-28 13:28:43 +08003328
Omer Osmana2587da2022-05-01 03:54:11 +00003329 for (auto& codec_specific : opus_codec_specifics) {
Alice Kuoadcceec2022-03-28 13:28:43 +08003330 copy_codec_specific(codec_config.config, codec_specific);
3331 DataMQDesc mq_desc;
3332 auto aidl_retval = audio_provider_->startSession(
3333 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
3334
3335 ASSERT_TRUE(aidl_retval.isOk());
3336 EXPECT_TRUE(audio_provider_->endSession().isOk());
3337 }
3338}
3339
3340/**
3341 * Test whether each provider of type
3342 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
3343 * AptX hardware encoding config
3344 */
3345TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3346 StartAndEndA2dpAptxDecodingHardwareSession) {
3347 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003348 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08003349 }
3350
3351 for (auto codec_type : {CodecType::APTX, CodecType::APTX_HD}) {
3352 CodecConfiguration codec_config = {
3353 .codecType = codec_type,
3354 .encodedAudioBitrate =
3355 (codec_type == CodecType::APTX ? 352000 : 576000),
3356 .peerMtu = 1005,
3357 .isScmstEnabled = false,
3358 };
3359
3360 auto aptx_codec_specifics = GetAptxCodecSpecificSupportedList(
3361 (codec_type == CodecType::APTX_HD ? true : false), true);
3362
3363 for (auto& codec_specific : aptx_codec_specifics) {
3364 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,
3368 &mq_desc);
3369
3370 ASSERT_TRUE(aidl_retval.isOk());
3371 EXPECT_TRUE(audio_provider_->endSession().isOk());
3372 }
3373 }
3374}
3375
3376/**
3377 * Test whether each provider of type
3378 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
3379 * an invalid codec config
3380 */
3381TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3382 StartAndEndA2dpDecodingHardwareSessionInvalidCodecConfig) {
3383 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003384 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08003385 }
3386 ASSERT_NE(audio_provider_, nullptr);
3387
3388 std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
Sagar Verma62df9102022-12-07 17:56:04 +05303389 for (auto codec_type : ndk::enum_range<CodecType>()) {
Alice Kuoadcceec2022-03-28 13:28:43 +08003390 switch (codec_type) {
3391 case CodecType::SBC:
3392 codec_specifics = GetSbcCodecSpecificSupportedList(false);
3393 break;
3394 case CodecType::AAC:
3395 codec_specifics = GetAacCodecSpecificSupportedList(false);
3396 break;
3397 case CodecType::LDAC:
3398 codec_specifics = GetLdacCodecSpecificSupportedList(false);
3399 break;
3400 case CodecType::APTX:
3401 codec_specifics = GetAptxCodecSpecificSupportedList(false, false);
3402 break;
3403 case CodecType::APTX_HD:
3404 codec_specifics = GetAptxCodecSpecificSupportedList(true, false);
3405 break;
Omer Osmana2587da2022-05-01 03:54:11 +00003406 case CodecType::OPUS:
3407 codec_specifics = GetOpusCodecSpecificSupportedList(false);
Alice Kuoadcceec2022-03-28 13:28:43 +08003408 continue;
3409 case CodecType::APTX_ADAPTIVE:
Sagar Verma62df9102022-12-07 17:56:04 +05303410 case CodecType::APTX_ADAPTIVE_LE:
3411 case CodecType::APTX_ADAPTIVE_LEX:
Omer Osmana2587da2022-05-01 03:54:11 +00003412 case CodecType::LC3:
Alice Kuoadcceec2022-03-28 13:28:43 +08003413 case CodecType::VENDOR:
3414 case CodecType::UNKNOWN:
3415 codec_specifics.clear();
3416 break;
3417 }
3418 if (codec_specifics.empty()) {
3419 continue;
3420 }
3421
3422 CodecConfiguration codec_config = {
3423 .codecType = codec_type,
3424 .encodedAudioBitrate = 328000,
3425 .peerMtu = 1005,
3426 .isScmstEnabled = false,
3427 };
3428 for (auto codec_specific : codec_specifics) {
3429 copy_codec_specific(codec_config.config, codec_specific);
3430 DataMQDesc mq_desc;
3431 auto aidl_retval = audio_provider_->startSession(
3432 audio_port_, AudioConfiguration(codec_config), latency_modes,
3433 &mq_desc);
3434
3435 // AIDL call should fail on invalid codec
3436 ASSERT_FALSE(aidl_retval.isOk());
3437 EXPECT_TRUE(audio_provider_->endSession().isOk());
3438 }
3439 }
3440}
3441
Josh Wu049e2cd2022-01-12 05:42:58 -08003442GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3443 BluetoothAudioProviderFactoryAidl);
3444INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderFactoryAidl,
3445 testing::ValuesIn(android::getAidlHalInstanceNames(
3446 IBluetoothAudioProviderFactory::descriptor)),
3447 android::PrintInstanceNameToString);
3448
Antoine SOULIER33c4e5a2023-09-28 21:59:19 +00003449GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothAudioProviderAidl);
3450INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderAidl,
3451 testing::ValuesIn(android::getAidlHalInstanceNames(
3452 IBluetoothAudioProviderFactory::descriptor)),
3453 android::PrintInstanceNameToString);
3454
Josh Wu049e2cd2022-01-12 05:42:58 -08003455GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
Alice Kuoadcceec2022-03-28 13:28:43 +08003456 BluetoothAudioProviderA2dpEncodingSoftwareAidl);
3457INSTANTIATE_TEST_SUITE_P(PerInstance,
3458 BluetoothAudioProviderA2dpEncodingSoftwareAidl,
Josh Wu049e2cd2022-01-12 05:42:58 -08003459 testing::ValuesIn(android::getAidlHalInstanceNames(
3460 IBluetoothAudioProviderFactory::descriptor)),
3461 android::PrintInstanceNameToString);
3462
3463GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
Alice Kuoadcceec2022-03-28 13:28:43 +08003464 BluetoothAudioProviderA2dpEncodingHardwareAidl);
3465INSTANTIATE_TEST_SUITE_P(PerInstance,
3466 BluetoothAudioProviderA2dpEncodingHardwareAidl,
Josh Wu049e2cd2022-01-12 05:42:58 -08003467 testing::ValuesIn(android::getAidlHalInstanceNames(
3468 IBluetoothAudioProviderFactory::descriptor)),
3469 android::PrintInstanceNameToString);
3470
3471GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3472 BluetoothAudioProviderHearingAidSoftwareAidl);
3473INSTANTIATE_TEST_SUITE_P(PerInstance,
3474 BluetoothAudioProviderHearingAidSoftwareAidl,
3475 testing::ValuesIn(android::getAidlHalInstanceNames(
3476 IBluetoothAudioProviderFactory::descriptor)),
3477 android::PrintInstanceNameToString);
3478
3479GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3480 BluetoothAudioProviderLeAudioOutputSoftwareAidl);
3481INSTANTIATE_TEST_SUITE_P(PerInstance,
3482 BluetoothAudioProviderLeAudioOutputSoftwareAidl,
3483 testing::ValuesIn(android::getAidlHalInstanceNames(
3484 IBluetoothAudioProviderFactory::descriptor)),
3485 android::PrintInstanceNameToString);
3486
3487GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3488 BluetoothAudioProviderLeAudioInputSoftwareAidl);
3489INSTANTIATE_TEST_SUITE_P(PerInstance,
3490 BluetoothAudioProviderLeAudioInputSoftwareAidl,
3491 testing::ValuesIn(android::getAidlHalInstanceNames(
3492 IBluetoothAudioProviderFactory::descriptor)),
3493 android::PrintInstanceNameToString);
3494
3495GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3496 BluetoothAudioProviderLeAudioOutputHardwareAidl);
3497INSTANTIATE_TEST_SUITE_P(PerInstance,
3498 BluetoothAudioProviderLeAudioOutputHardwareAidl,
3499 testing::ValuesIn(android::getAidlHalInstanceNames(
3500 IBluetoothAudioProviderFactory::descriptor)),
3501 android::PrintInstanceNameToString);
3502
3503GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3504 BluetoothAudioProviderLeAudioInputHardwareAidl);
3505INSTANTIATE_TEST_SUITE_P(PerInstance,
3506 BluetoothAudioProviderLeAudioInputHardwareAidl,
3507 testing::ValuesIn(android::getAidlHalInstanceNames(
3508 IBluetoothAudioProviderFactory::descriptor)),
3509 android::PrintInstanceNameToString);
3510
3511GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3512 BluetoothAudioProviderLeAudioBroadcastSoftwareAidl);
3513INSTANTIATE_TEST_SUITE_P(PerInstance,
3514 BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
3515 testing::ValuesIn(android::getAidlHalInstanceNames(
3516 IBluetoothAudioProviderFactory::descriptor)),
3517 android::PrintInstanceNameToString);
3518
Alice Kuo336d90c2022-02-16 09:09:59 +08003519GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3520 BluetoothAudioProviderLeAudioBroadcastHardwareAidl);
3521INSTANTIATE_TEST_SUITE_P(PerInstance,
3522 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3523 testing::ValuesIn(android::getAidlHalInstanceNames(
3524 IBluetoothAudioProviderFactory::descriptor)),
3525 android::PrintInstanceNameToString);
Josh Wu049e2cd2022-01-12 05:42:58 -08003526
Alice Kuoadcceec2022-03-28 13:28:43 +08003527GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3528 BluetoothAudioProviderA2dpDecodingSoftwareAidl);
3529INSTANTIATE_TEST_SUITE_P(PerInstance,
3530 BluetoothAudioProviderA2dpDecodingSoftwareAidl,
3531 testing::ValuesIn(android::getAidlHalInstanceNames(
3532 IBluetoothAudioProviderFactory::descriptor)),
3533 android::PrintInstanceNameToString);
3534
3535GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3536 BluetoothAudioProviderA2dpDecodingHardwareAidl);
3537INSTANTIATE_TEST_SUITE_P(PerInstance,
3538 BluetoothAudioProviderA2dpDecodingHardwareAidl,
3539 testing::ValuesIn(android::getAidlHalInstanceNames(
3540 IBluetoothAudioProviderFactory::descriptor)),
3541 android::PrintInstanceNameToString);
3542
Bao Do72399432023-11-09 08:13:05 +00003543GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3544 BluetoothAudioProviderHfpHardwareAidl);
3545INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderHfpHardwareAidl,
3546 testing::ValuesIn(android::getAidlHalInstanceNames(
3547 IBluetoothAudioProviderFactory::descriptor)),
3548 android::PrintInstanceNameToString);
3549
3550GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3551 BluetoothAudioProviderHfpSoftwareDecodingAidl);
3552INSTANTIATE_TEST_SUITE_P(PerInstance,
3553 BluetoothAudioProviderHfpSoftwareDecodingAidl,
3554 testing::ValuesIn(android::getAidlHalInstanceNames(
3555 IBluetoothAudioProviderFactory::descriptor)),
3556 android::PrintInstanceNameToString);
3557
3558GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3559 BluetoothAudioProviderHfpSoftwareEncodingAidl);
3560INSTANTIATE_TEST_SUITE_P(PerInstance,
3561 BluetoothAudioProviderHfpSoftwareEncodingAidl,
3562 testing::ValuesIn(android::getAidlHalInstanceNames(
3563 IBluetoothAudioProviderFactory::descriptor)),
3564 android::PrintInstanceNameToString);
3565
Josh Wu049e2cd2022-01-12 05:42:58 -08003566int main(int argc, char** argv) {
3567 ::testing::InitGoogleTest(&argc, argv);
3568 ABinderProcess_setThreadPoolMaxThreadCount(1);
3569 ABinderProcess_startThreadPool();
3570 return RUN_ALL_TESTS();
3571}