blob: b59804453598b02e62fcf54c0da290cfd1f271d6 [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.
Jakub Tyszkowski06781c02024-01-08 13:16:42 +0000739 ASSERT_EQ(codec_info.transport.getTag(), CodecInfo::Transport::leAudio);
Antoine SOULIER8c90f1f2023-09-26 18:55:17 +0000740 }
741 }
742}
743
Antoine SOULIER33c4e5a2023-09-28 21:59:19 +0000744class BluetoothAudioProviderAidl : public BluetoothAudioProviderFactoryAidl {
745 protected:
746 std::optional<IBluetoothAudioProviderFactory::ProviderInfo>
747 a2dp_encoding_provider_info_{};
748 std::optional<IBluetoothAudioProviderFactory::ProviderInfo>
749 a2dp_decoding_provider_info_{};
750 std::shared_ptr<IBluetoothAudioProvider> a2dp_encoding_provider_{nullptr};
751 std::shared_ptr<IBluetoothAudioProvider> a2dp_decoding_provider_{nullptr};
752
753 public:
754 void SetUp() override {
755 BluetoothAudioProviderFactoryAidl::SetUp();
756 audio_port_ = ndk::SharedRefBase::make<BluetoothAudioPort>();
757
758 (void)provider_factory_->getProviderInfo(
759 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
760 &a2dp_encoding_provider_info_);
761
762 (void)provider_factory_->getProviderInfo(
763 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
764 &a2dp_decoding_provider_info_);
765
766 (void)provider_factory_->openProvider(
767 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
768 &a2dp_encoding_provider_);
769
770 (void)provider_factory_->openProvider(
771 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
772 &a2dp_decoding_provider_);
773 }
774};
775
776/**
777 * Calling parseA2dpConfiguration on a session of a different type than
778 * A2DP_HARDWARE_OFFLOAD_(ENCODING|DECODING)_DATAPATH must fail.
779 */
780TEST_P(BluetoothAudioProviderAidl, parseA2dpConfiguration_invalidSessionType) {
781 static constexpr SessionType kInvalidSessionTypes[] = {
782 SessionType::UNKNOWN,
783 SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
784 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
785 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
786 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
787 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
788 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
789 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
790 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
791 SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
792 };
793
794 for (auto session_type : kInvalidSessionTypes) {
795 // Open a BluetoothAudioProvider instance of the selected session type.
796 // Skip validation if the provider cannot be opened.
797 std::shared_ptr<IBluetoothAudioProvider> provider{nullptr};
798 (void)provider_factory_->openProvider(session_type, &provider);
799 if (provider == nullptr) {
800 continue;
801 }
802
803 // parseA2dpConfiguration must fail without returning an A2dpStatus.
804 CodecId codec_id(CodecId::A2dp::SBC);
805 CodecParameters codec_parameters;
806 A2dpStatus a2dp_status = A2dpStatus::OK;
807 auto aidl_retval = provider->parseA2dpConfiguration(
808 codec_id, std::vector<uint8_t>{}, &codec_parameters, &a2dp_status);
809 EXPECT_FALSE(aidl_retval.isOk());
810 }
811}
812
813/**
814 * Calling parseA2dpConfiguration with an unknown codec must fail
815 * with the A2dpStatus code INVALID_CODEC_TYPE or NOT_SUPPORTED_CODEC_TYPE.
816 */
817TEST_P(BluetoothAudioProviderAidl,
818 parseA2dpConfiguration_unsupportedCodecType) {
819 CodecId unsupported_core_id(CodecId::Core::CVSD);
820 CodecId unsupported_vendor_id(
821 CodecId::Vendor(0xFCB1, 0x42)); // Google Codec #42
822
823 for (auto& provider : {a2dp_encoding_provider_, a2dp_decoding_provider_}) {
824 if (provider == nullptr) {
825 continue;
826 }
827
828 CodecParameters codec_parameters;
829 A2dpStatus a2dp_status = A2dpStatus::OK;
830 ::ndk::ScopedAStatus aidl_retval;
831
832 // Test with two invalid codec identifiers: vendor or core.
833 aidl_retval = provider->parseA2dpConfiguration(
834 unsupported_core_id, std::vector<uint8_t>{}, &codec_parameters,
835 &a2dp_status);
836 EXPECT_TRUE(!aidl_retval.isOk() ||
837 a2dp_status == A2dpStatus::NOT_SUPPORTED_CODEC_TYPE);
838
839 aidl_retval = provider->parseA2dpConfiguration(
840 unsupported_vendor_id, std::vector<uint8_t>{}, &codec_parameters,
841 &a2dp_status);
842 EXPECT_TRUE(!aidl_retval.isOk() ||
843 a2dp_status == A2dpStatus::NOT_SUPPORTED_CODEC_TYPE);
844 }
845}
846
847/**
848 * Calling parseA2dpConfiguration with a known codec and invalid configuration
849 * must fail with an A2dpStatus code different from INVALID_CODEC_TYPE or
850 * NOT_SUPPORTED_CODEC_TYPE.
851 */
852TEST_P(BluetoothAudioProviderAidl,
853 parseA2dpConfiguration_invalidConfiguration) {
854 for (auto& [provider, provider_info] :
855 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
856 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
857 if (provider == nullptr || !provider_info.has_value() ||
858 provider_info->codecInfos.empty()) {
859 continue;
860 }
861
862 CodecParameters codec_parameters;
863 A2dpStatus a2dp_status = A2dpStatus::OK;
864 ::ndk::ScopedAStatus aidl_retval;
865
866 // Test with the first available codec in the provider info for testing.
867 // The test runs with an empty parameters array, anything more specific
868 // would need understanding the codec.
869 aidl_retval = provider->parseA2dpConfiguration(
870 provider_info->codecInfos[0].id, std::vector<uint8_t>{},
871 &codec_parameters, &a2dp_status);
872 ASSERT_TRUE(aidl_retval.isOk());
873 EXPECT_TRUE(a2dp_status != A2dpStatus::OK &&
874 a2dp_status != A2dpStatus::NOT_SUPPORTED_CODEC_TYPE &&
875 a2dp_status != A2dpStatus::INVALID_CODEC_TYPE);
876 }
877}
878
879/**
880 * Calling parseA2dpConfiguration with a known codec and valid parameters
881 * must return with A2dpStatus OK.
882 */
883TEST_P(BluetoothAudioProviderAidl, parseA2dpConfiguration_valid) {
884 for (auto& [provider, provider_info] :
885 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
886 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
887 if (provider == nullptr || !provider_info.has_value() ||
888 provider_info->codecInfos.empty()) {
889 continue;
890 }
891
892 CodecParameters codec_parameters;
893 A2dpStatus a2dp_status = A2dpStatus::OK;
894 ::ndk::ScopedAStatus aidl_retval;
895
896 // Test with the first available codec in the provider info for testing.
897 // To get a valid configuration (the capabilities array in the provider
898 // info is not a selection), getA2dpConfiguration is used with the
899 // selected codec parameters as input.
900 auto const& codec_info = provider_info->codecInfos[0];
901 auto transport = codec_info.transport.get<CodecInfo::Transport::a2dp>();
902 A2dpRemoteCapabilities remote_capabilities(/*seid*/ 0, codec_info.id,
903 transport.capabilities);
904 std::optional<A2dpConfiguration> configuration;
905 aidl_retval = provider->getA2dpConfiguration(
906 std::vector<A2dpRemoteCapabilities>{remote_capabilities},
907 A2dpConfigurationHint(), &configuration);
908 ASSERT_TRUE(aidl_retval.isOk());
909 ASSERT_TRUE(configuration.has_value());
910
911 aidl_retval = provider->parseA2dpConfiguration(
912 configuration->id, configuration->configuration, &codec_parameters,
913 &a2dp_status);
914 ASSERT_TRUE(aidl_retval.isOk());
915 EXPECT_TRUE(a2dp_status == A2dpStatus::OK);
916 EXPECT_EQ(codec_parameters, configuration->parameters);
917 }
918}
919
920/**
921 * Calling getA2dpConfiguration on a session of a different type than
922 * A2DP_HARDWARE_OFFLOAD_(ENCODING|DECODING)_DATAPATH must fail.
923 */
924TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_invalidSessionType) {
925 static constexpr SessionType kInvalidSessionTypes[] = {
926 SessionType::UNKNOWN,
927 SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
928 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
929 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
930 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
931 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
932 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
933 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
934 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
935 SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
936 };
937
938 for (auto session_type : kInvalidSessionTypes) {
939 // Open a BluetoothAudioProvider instance of the selected session type.
940 // Skip validation if the provider cannot be opened.
941 std::shared_ptr<IBluetoothAudioProvider> provider{nullptr};
942 auto aidl_retval = provider_factory_->openProvider(session_type, &provider);
943 if (provider == nullptr) {
944 continue;
945 }
946
947 // getA2dpConfiguration must fail without returning a configuration.
948 std::optional<A2dpConfiguration> configuration;
949 aidl_retval =
950 provider->getA2dpConfiguration(std::vector<A2dpRemoteCapabilities>{},
951 A2dpConfigurationHint(), &configuration);
952 EXPECT_FALSE(aidl_retval.isOk());
953 }
954}
955
956/**
957 * Calling getA2dpConfiguration with empty or unknown remote capabilities
958 * must return an empty configuration.
959 */
960TEST_P(BluetoothAudioProviderAidl,
961 getA2dpConfiguration_unknownRemoteCapabilities) {
962 for (auto& [provider, provider_info] :
963 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
964 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
965 if (provider == nullptr || !provider_info.has_value() ||
966 provider_info->codecInfos.empty()) {
967 continue;
968 }
969
970 std::optional<A2dpConfiguration> configuration;
971 ::ndk::ScopedAStatus aidl_retval;
972
973 // Test with empty remote capabilities.
974 aidl_retval =
975 provider->getA2dpConfiguration(std::vector<A2dpRemoteCapabilities>{},
976 A2dpConfigurationHint(), &configuration);
977 ASSERT_TRUE(aidl_retval.isOk());
978 EXPECT_FALSE(configuration.has_value());
979
980 // Test with unknown remote capabilities.
981 A2dpRemoteCapabilities unknown_core_remote_capabilities(
982 /*seid*/ 0, CodecId::Core::CVSD, std::vector<uint8_t>{1, 2, 3});
983 A2dpRemoteCapabilities unknown_vendor_remote_capabilities(
984 /*seid*/ 1,
985 /* Google Codec #42 */ CodecId::Vendor(0xFCB1, 0x42),
986 std::vector<uint8_t>{1, 2, 3});
987 aidl_retval = provider->getA2dpConfiguration(
988 std::vector<A2dpRemoteCapabilities>{
989 unknown_core_remote_capabilities,
990 unknown_vendor_remote_capabilities,
991 },
992 A2dpConfigurationHint(), &configuration);
993 ASSERT_TRUE(aidl_retval.isOk());
994 EXPECT_FALSE(configuration.has_value());
995 }
996}
997
998/**
999 * Calling getA2dpConfiguration with invalid remote capabilities
1000 * must return an empty configuration.
1001 */
1002TEST_P(BluetoothAudioProviderAidl,
1003 getA2dpConfiguration_invalidRemoteCapabilities) {
1004 for (auto& [provider, provider_info] :
1005 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1006 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1007 if (provider == nullptr || !provider_info.has_value() ||
1008 provider_info->codecInfos.empty()) {
1009 continue;
1010 }
1011
1012 std::optional<A2dpConfiguration> configuration;
1013 ::ndk::ScopedAStatus aidl_retval;
1014
1015 // Use the first available codec in the provider info for testing.
1016 // The capabilities are modified to make them invalid.
1017 auto const& codec_info = provider_info->codecInfos[0];
1018 auto transport = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1019 std::vector<uint8_t> invalid_capabilities = transport.capabilities;
1020 invalid_capabilities.push_back(0x42); // adding bytes should be invalid.
1021 aidl_retval = provider->getA2dpConfiguration(
1022 std::vector<A2dpRemoteCapabilities>{
1023 A2dpRemoteCapabilities(/*seid*/ 0, codec_info.id,
1024 std::vector<uint8_t>()),
1025 A2dpRemoteCapabilities(/*seid*/ 1, codec_info.id,
1026 invalid_capabilities),
1027 },
1028 A2dpConfigurationHint(), &configuration);
1029 ASSERT_TRUE(aidl_retval.isOk());
1030 EXPECT_FALSE(configuration.has_value());
1031 }
1032}
1033
1034/**
1035 * Calling getA2dpConfiguration with valid remote capabilities
1036 * must return a valid configuration. The selected parameters must
1037 * be contained in the original capabilities. The returned configuration
1038 * must match the returned parameters. The returned SEID must match the
1039 * input SEID.
1040 */
1041TEST_P(BluetoothAudioProviderAidl,
1042 getA2dpConfiguration_validRemoteCapabilities) {
1043 for (auto& [provider, provider_info] :
1044 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1045 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1046 if (provider == nullptr || !provider_info.has_value() ||
1047 provider_info->codecInfos.empty()) {
1048 continue;
1049 }
1050
1051 // Test with all available codecs in the provider info.
1052 for (auto const& codec_info : provider_info->codecInfos) {
1053 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1054 std::optional<A2dpConfiguration> configuration{};
1055 ::ndk::ScopedAStatus aidl_retval;
1056
1057 aidl_retval = provider->getA2dpConfiguration(
1058 std::vector<A2dpRemoteCapabilities>{
1059 A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
1060 a2dp_info.capabilities),
1061 },
1062 A2dpConfigurationHint(), &configuration);
1063
1064 ASSERT_TRUE(aidl_retval.isOk());
1065 ASSERT_TRUE(configuration.has_value());
1066
1067 // Returned configuration must have the same codec id
1068 // as the remote capability.
1069 EXPECT_EQ(configuration->id, codec_info.id);
1070
1071 // Returned configuration must have the same SEID
1072 // as the remote capability.
1073 EXPECT_EQ(configuration->remoteSeid, 42);
1074
1075 // Returned codec parameters must be in the range of input
1076 // parameters.
1077 EXPECT_NE(
1078 std::find(a2dp_info.channelMode.begin(), a2dp_info.channelMode.end(),
1079 configuration->parameters.channelMode),
1080 a2dp_info.channelMode.end());
1081 EXPECT_NE(std::find(a2dp_info.samplingFrequencyHz.begin(),
1082 a2dp_info.samplingFrequencyHz.end(),
1083 configuration->parameters.samplingFrequencyHz),
1084 a2dp_info.samplingFrequencyHz.end());
1085 EXPECT_NE(std::find(a2dp_info.bitdepth.begin(), a2dp_info.bitdepth.end(),
1086 configuration->parameters.bitdepth),
1087 a2dp_info.bitdepth.end());
1088 EXPECT_EQ(a2dp_info.lossless, configuration->parameters.lossless);
1089 EXPECT_TRUE(configuration->parameters.minBitrate <=
1090 configuration->parameters.maxBitrate);
1091
1092 // Returned configuration must be parsable by parseA2dpParameters
1093 // and match the codec parameters.
1094 CodecParameters codec_parameters;
1095 A2dpStatus a2dp_status = A2dpStatus::OK;
1096 aidl_retval = provider->parseA2dpConfiguration(
1097 configuration->id, configuration->configuration, &codec_parameters,
1098 &a2dp_status);
1099 ASSERT_TRUE(aidl_retval.isOk());
1100 EXPECT_TRUE(a2dp_status == A2dpStatus::OK);
1101 EXPECT_EQ(codec_parameters, configuration->parameters);
1102 }
1103 }
1104}
1105
1106/**
1107 * Calling getA2dpConfiguration with valid remote capabilities
1108 * with various hinted codec ids.
1109 */
1110TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_hintCodecId) {
1111 for (auto& [provider, provider_info] :
1112 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1113 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1114 if (provider == nullptr || !provider_info.has_value() ||
1115 provider_info->codecInfos.empty()) {
1116 continue;
1117 }
1118
1119 // Build the remote capabilities with all supported codecs.
1120 std::vector<A2dpRemoteCapabilities> remote_capabilities;
1121 for (size_t n = 0; n < provider_info->codecInfos.size(); n++) {
1122 auto const& codec_info = provider_info->codecInfos[n];
1123 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1124 remote_capabilities.push_back(A2dpRemoteCapabilities(
1125 /*seid*/ n, codec_info.id, a2dp_info.capabilities));
1126 }
1127
1128 // Test with all supported codec identifiers,
1129 for (auto const& codec_info : provider_info->codecInfos) {
1130 std::optional<A2dpConfiguration> configuration{};
1131 ::ndk::ScopedAStatus aidl_retval;
1132
1133 A2dpConfigurationHint hint;
1134 hint.codecId = codec_info.id;
1135
1136 aidl_retval = provider->getA2dpConfiguration(remote_capabilities, hint,
1137 &configuration);
1138
1139 ASSERT_TRUE(aidl_retval.isOk());
1140 ASSERT_TRUE(configuration.has_value());
1141 EXPECT_EQ(configuration->id, codec_info.id);
1142 }
1143
1144 // Test with unknown codec identifiers: either core or vendor.
1145 for (auto& codec_id :
1146 {CodecId(CodecId::Core::CVSD),
1147 CodecId(CodecId::Vendor(0xFCB1, 0x42)) /*Google Codec #42*/}) {
1148 std::optional<A2dpConfiguration> configuration{};
1149 ::ndk::ScopedAStatus aidl_retval;
1150
1151 A2dpConfigurationHint hint;
1152 hint.codecId = codec_id;
1153
1154 aidl_retval = provider->getA2dpConfiguration(remote_capabilities, hint,
1155 &configuration);
1156
1157 ASSERT_TRUE(aidl_retval.isOk());
1158 ASSERT_TRUE(configuration.has_value());
1159 EXPECT_NE(configuration->id, codec_id);
1160 }
1161 }
1162}
1163
1164/**
1165 * Calling getA2dpConfiguration with valid remote capabilities
1166 * with various hinted channel modes.
1167 */
1168TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_hintChannelMode) {
1169 for (auto& [provider, provider_info] :
1170 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1171 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1172 if (provider == nullptr || !provider_info.has_value() ||
1173 provider_info->codecInfos.empty()) {
1174 continue;
1175 }
1176
1177 // Test with all available codecs in the provider info.
1178 for (auto const& codec_info : provider_info->codecInfos) {
1179 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1180 std::optional<A2dpConfiguration> configuration{};
1181 ::ndk::ScopedAStatus aidl_retval;
1182
1183 for (auto& channel_mode :
1184 {ChannelMode::STEREO, ChannelMode::MONO, ChannelMode::DUALMONO}) {
1185 // Add the hint for the channel mode.
1186 A2dpConfigurationHint hint;
1187 auto& codec_parameters = hint.codecParameters.emplace();
1188 codec_parameters.channelMode = channel_mode;
1189
1190 aidl_retval = provider->getA2dpConfiguration(
1191 std::vector<A2dpRemoteCapabilities>{
1192 A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
1193 a2dp_info.capabilities),
1194 },
1195 hint, &configuration);
1196
1197 ASSERT_TRUE(aidl_retval.isOk());
1198 ASSERT_TRUE(configuration.has_value());
1199
1200 // The hint must be ignored if the channel mode is not supported
1201 // by the codec, and applied otherwise.
1202 ASSERT_EQ(configuration->parameters.channelMode == channel_mode,
1203 std::find(a2dp_info.channelMode.begin(),
1204 a2dp_info.channelMode.end(),
1205 channel_mode) != a2dp_info.channelMode.end());
1206 }
1207 }
1208 }
1209}
1210
1211/**
1212 * Calling getA2dpConfiguration with valid remote capabilities
1213 * with various hinted sampling frequencies.
1214 */
1215TEST_P(BluetoothAudioProviderAidl,
1216 getA2dpConfiguration_hintSamplingFrequencyHz) {
1217 for (auto& [provider, provider_info] :
1218 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1219 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1220 if (provider == nullptr || !provider_info.has_value() ||
1221 provider_info->codecInfos.empty()) {
1222 continue;
1223 }
1224
1225 // Test with all available codecs in the provider info.
1226 for (auto const& codec_info : provider_info->codecInfos) {
1227 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1228 std::optional<A2dpConfiguration> configuration{};
1229 ::ndk::ScopedAStatus aidl_retval;
1230
1231 for (auto& sampling_frequency_hz : {
1232 0,
1233 1,
1234 8000,
1235 16000,
1236 24000,
1237 32000,
1238 44100,
1239 48000,
1240 88200,
1241 96000,
1242 176400,
1243 192000,
1244 }) {
1245 // Add the hint for the sampling frequency.
1246 A2dpConfigurationHint hint;
1247 auto& codec_parameters = hint.codecParameters.emplace();
1248 codec_parameters.samplingFrequencyHz = sampling_frequency_hz;
1249
1250 aidl_retval = provider->getA2dpConfiguration(
1251 std::vector<A2dpRemoteCapabilities>{
1252 A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
1253 a2dp_info.capabilities),
1254 },
1255 hint, &configuration);
1256
1257 ASSERT_TRUE(aidl_retval.isOk());
1258 ASSERT_TRUE(configuration.has_value());
1259
1260 // The hint must be ignored if the sampling frequency is not supported
1261 // by the codec, and applied otherwise.
1262 ASSERT_EQ(configuration->parameters.samplingFrequencyHz ==
1263 sampling_frequency_hz,
1264 std::find(a2dp_info.samplingFrequencyHz.begin(),
1265 a2dp_info.samplingFrequencyHz.end(),
1266 sampling_frequency_hz) !=
1267 a2dp_info.samplingFrequencyHz.end());
1268 }
1269 }
1270 }
1271}
1272
1273/**
1274 * Calling getA2dpConfiguration with valid remote capabilities
1275 * with various hinted sampling bit-depths.
1276 */
1277TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_hintBitdepth) {
1278 for (auto& [provider, provider_info] :
1279 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1280 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1281 if (provider == nullptr || !provider_info.has_value() ||
1282 provider_info->codecInfos.empty()) {
1283 continue;
1284 }
1285
1286 // Test with all available codecs in the provider info.
1287 for (auto const& codec_info : provider_info->codecInfos) {
1288 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1289 std::optional<A2dpConfiguration> configuration{};
1290 ::ndk::ScopedAStatus aidl_retval;
1291
1292 for (auto& bitdepth : {0, 1, 16, 24, 32}) {
1293 // Add the hint for the bit depth.
1294 A2dpConfigurationHint hint;
1295 auto& codec_parameters = hint.codecParameters.emplace();
1296 codec_parameters.bitdepth = bitdepth;
1297
1298 aidl_retval = provider->getA2dpConfiguration(
1299 std::vector<A2dpRemoteCapabilities>{
1300 A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
1301 a2dp_info.capabilities),
1302 },
1303 hint, &configuration);
1304
1305 ASSERT_TRUE(aidl_retval.isOk());
1306 ASSERT_TRUE(configuration.has_value());
1307
1308 // The hint must be ignored if the bitdepth is not supported
1309 // by the codec, and applied otherwise.
1310 ASSERT_EQ(
1311 configuration->parameters.bitdepth == bitdepth,
1312 std::find(a2dp_info.bitdepth.begin(), a2dp_info.bitdepth.end(),
1313 bitdepth) != a2dp_info.bitdepth.end());
1314 }
1315 }
1316 }
1317}
1318
1319/**
1320 * Calling startSession with an unknown codec id must fail.
1321 */
1322TEST_P(BluetoothAudioProviderAidl, startSession_unknownCodecId) {
1323 for (auto& [provider, provider_info] :
1324 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1325 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1326 if (provider == nullptr || !provider_info.has_value() ||
1327 provider_info->codecInfos.empty()) {
1328 continue;
1329 }
1330
1331 for (auto& codec_id :
1332 {CodecId(CodecId::Core::CVSD),
1333 CodecId(CodecId::Vendor(0xFCB1, 0x42) /*Google Codec #42*/)}) {
1334 A2dpStreamConfiguration a2dp_config;
1335 DataMQDesc data_mq_desc;
1336
1337 a2dp_config.codecId = codec_id;
1338 a2dp_config.configuration = std::vector<uint8_t>{1, 2, 3};
1339
1340 auto aidl_retval =
1341 provider->startSession(audio_port_, AudioConfiguration(a2dp_config),
1342 std::vector<LatencyMode>{}, &data_mq_desc);
1343
1344 EXPECT_FALSE(aidl_retval.isOk());
1345 }
1346 }
1347}
1348
1349/**
1350 * Calling startSession with a known codec and a valid configuration
1351 * must succeed.
1352 */
1353TEST_P(BluetoothAudioProviderAidl, startSession_valid) {
1354 for (auto& [provider, provider_info] :
1355 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1356 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1357 if (provider == nullptr || !provider_info.has_value() ||
1358 provider_info->codecInfos.empty()) {
1359 continue;
1360 }
1361
1362 // Use the first available codec in the provider info for testing.
1363 // To get a valid configuration (the capabilities array in the provider
1364 // info is not a selection), getA2dpConfiguration is used with the
1365 // selected codec parameters as input.
1366 auto const& codec_info = provider_info->codecInfos[0];
1367 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1368 ::ndk::ScopedAStatus aidl_retval;
1369 A2dpRemoteCapabilities remote_capabilities(/*seid*/ 0, codec_info.id,
1370 a2dp_info.capabilities);
1371 std::optional<A2dpConfiguration> configuration;
1372 aidl_retval = provider->getA2dpConfiguration(
1373 std::vector<A2dpRemoteCapabilities>{remote_capabilities},
1374 A2dpConfigurationHint(), &configuration);
1375 ASSERT_TRUE(aidl_retval.isOk());
1376 ASSERT_TRUE(configuration.has_value());
1377
1378 // Build the stream configuration.
1379 A2dpStreamConfiguration a2dp_config;
1380 DataMQDesc data_mq_desc;
1381
1382 a2dp_config.codecId = codec_info.id;
1383 a2dp_config.configuration = configuration->configuration;
1384
1385 aidl_retval =
1386 provider->startSession(audio_port_, AudioConfiguration(a2dp_config),
1387 std::vector<LatencyMode>{}, &data_mq_desc);
1388
1389 EXPECT_TRUE(aidl_retval.isOk());
1390 }
1391}
1392
1393/**
1394 * Calling startSession with a known codec but an invalid configuration
1395 * must fail.
1396 */
1397TEST_P(BluetoothAudioProviderAidl, startSession_invalidConfiguration) {
1398 for (auto& [provider, provider_info] :
1399 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1400 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1401 if (provider == nullptr || !provider_info.has_value() ||
1402 provider_info->codecInfos.empty()) {
1403 continue;
1404 }
1405
1406 // Use the first available codec in the provider info for testing.
1407 // To get a valid configuration (the capabilities array in the provider
1408 // info is not a selection), getA2dpConfiguration is used with the
1409 // selected codec parameters as input.
1410 ::ndk::ScopedAStatus aidl_retval;
1411 auto const& codec_info = provider_info->codecInfos[0];
1412 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1413 A2dpRemoteCapabilities remote_capabilities(/*seid*/ 0, codec_info.id,
1414 a2dp_info.capabilities);
1415 std::optional<A2dpConfiguration> configuration;
1416 aidl_retval = provider->getA2dpConfiguration(
1417 std::vector<A2dpRemoteCapabilities>{remote_capabilities},
1418 A2dpConfigurationHint(), &configuration);
1419 ASSERT_TRUE(aidl_retval.isOk());
1420 ASSERT_TRUE(configuration.has_value());
1421
1422 // Build the stream configuration but edit the configuration bytes
1423 // to make it invalid.
1424 A2dpStreamConfiguration a2dp_config;
1425 DataMQDesc data_mq_desc;
1426
1427 a2dp_config.codecId = codec_info.id;
1428 a2dp_config.configuration = configuration->configuration;
1429 a2dp_config.configuration.push_back(42);
1430
1431 aidl_retval =
1432 provider->startSession(audio_port_, AudioConfiguration(a2dp_config),
1433 std::vector<LatencyMode>{}, &data_mq_desc);
1434
1435 EXPECT_FALSE(aidl_retval.isOk());
1436 }
1437}
1438
Antoine SOULIER8c90f1f2023-09-26 18:55:17 +00001439/**
Alice Kuoadcceec2022-03-28 13:28:43 +08001440 * openProvider A2DP_SOFTWARE_ENCODING_DATAPATH
1441 */
1442class BluetoothAudioProviderA2dpEncodingSoftwareAidl
1443 : public BluetoothAudioProviderFactoryAidl {
1444 public:
1445 virtual void SetUp() override {
1446 BluetoothAudioProviderFactoryAidl::SetUp();
1447 GetProviderCapabilitiesHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
1448 OpenProviderHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
1449 ASSERT_NE(audio_provider_, nullptr);
1450 }
1451
1452 virtual void TearDown() override {
1453 audio_port_ = nullptr;
1454 audio_provider_ = nullptr;
1455 BluetoothAudioProviderFactoryAidl::TearDown();
1456 }
Josh Wu049e2cd2022-01-12 05:42:58 -08001457};
1458
1459/**
1460 * Test whether we can open a provider of type
1461 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001462TEST_P(BluetoothAudioProviderA2dpEncodingSoftwareAidl,
1463 OpenA2dpEncodingSoftwareProvider) {}
1464
1465/**
1466 * Test whether each provider of type
1467 * SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH can be started and stopped with
1468 * different PCM config
1469 */
1470TEST_P(BluetoothAudioProviderA2dpEncodingSoftwareAidl,
1471 StartAndEndA2dpEncodingSoftwareSessionWithPossiblePcmConfig) {
1472 for (auto sample_rate : a2dp_sample_rates) {
1473 for (auto bits_per_sample : a2dp_bits_per_samples) {
1474 for (auto channel_mode : a2dp_channel_modes) {
1475 PcmConfiguration pcm_config{
1476 .sampleRateHz = sample_rate,
Alice Kuoadcceec2022-03-28 13:28:43 +08001477 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00001478 .bitsPerSample = bits_per_sample,
Alice Kuoadcceec2022-03-28 13:28:43 +08001479 };
1480 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
1481 DataMQDesc mq_desc;
1482 auto aidl_retval = audio_provider_->startSession(
1483 audio_port_, AudioConfiguration(pcm_config), latency_modes,
1484 &mq_desc);
1485 DataMQ data_mq(mq_desc);
1486
1487 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
1488 if (is_codec_config_valid) {
1489 EXPECT_TRUE(data_mq.isValid());
1490 }
1491 EXPECT_TRUE(audio_provider_->endSession().isOk());
1492 }
1493 }
1494 }
1495}
1496
1497/**
Bao Do72399432023-11-09 08:13:05 +00001498 * openProvider HFP_SOFTWARE_ENCODING_DATAPATH
1499 */
1500class BluetoothAudioProviderHfpSoftwareEncodingAidl
1501 : public BluetoothAudioProviderFactoryAidl {
1502 public:
1503 virtual void SetUp() override {
1504 BluetoothAudioProviderFactoryAidl::SetUp();
1505 GetProviderCapabilitiesHelper(SessionType::HFP_SOFTWARE_ENCODING_DATAPATH);
1506 OpenProviderHelper(SessionType::HFP_SOFTWARE_ENCODING_DATAPATH);
1507 ASSERT_NE(audio_provider_, nullptr);
1508 }
1509
1510 virtual void TearDown() override {
1511 audio_port_ = nullptr;
1512 audio_provider_ = nullptr;
1513 BluetoothAudioProviderFactoryAidl::TearDown();
1514 }
1515
1516 bool OpenSession(int32_t sample_rate, int8_t bits_per_sample,
Bao Do5b2fdab2023-11-20 08:02:55 +00001517 ChannelMode channel_mode, int32_t data_interval_us) {
Bao Do72399432023-11-09 08:13:05 +00001518 PcmConfiguration pcm_config{
1519 .sampleRateHz = sample_rate,
1520 .channelMode = channel_mode,
1521 .bitsPerSample = bits_per_sample,
1522 .dataIntervalUs = data_interval_us,
1523 };
1524 // Checking against provider capability from getProviderCapabilities
1525 // For HFP software, it's
1526 // BluetoothAudioCodecs::GetSoftwarePcmCapabilities();
1527 DataMQDesc mq_desc;
1528 auto aidl_retval = audio_provider_->startSession(
1529 audio_port_, AudioConfiguration(pcm_config), latency_modes, &mq_desc);
1530 DataMQ data_mq(mq_desc);
1531
1532 if (!aidl_retval.isOk()) return false;
1533 if (!data_mq.isValid()) return false;
1534 return true;
1535 }
1536};
1537
1538/**
1539 * Test whether we can open a provider of type
1540 */
1541TEST_P(BluetoothAudioProviderHfpSoftwareEncodingAidl,
1542 OpenHfpSoftwareEncodingProvider) {}
1543
1544/**
1545 * Test whether each provider of type
1546 * SessionType::HFP_SOFTWARE_ENCODING_DATAPATH can be started and stopped with
1547 * different PCM config
1548 */
1549TEST_P(BluetoothAudioProviderHfpSoftwareEncodingAidl,
1550 StartAndEndHfpEncodingSoftwareSessionWithPossiblePcmConfig) {
1551 for (auto sample_rate : hfp_sample_rates_) {
1552 for (auto bits_per_sample : hfp_bits_per_samples_) {
1553 for (auto channel_mode : hfp_channel_modes_) {
Bao Do5b2fdab2023-11-20 08:02:55 +00001554 for (auto data_interval_us : hfp_data_interval_us_) {
1555 EXPECT_TRUE(OpenSession(sample_rate, bits_per_sample, channel_mode,
1556 data_interval_us));
Bao Do72399432023-11-09 08:13:05 +00001557 EXPECT_TRUE(audio_provider_->endSession().isOk());
1558 }
1559 }
1560 }
1561 }
1562}
1563
1564/**
1565 * openProvider HFP_SOFTWARE_DECODING_DATAPATH
1566 */
1567class BluetoothAudioProviderHfpSoftwareDecodingAidl
1568 : public BluetoothAudioProviderFactoryAidl {
1569 public:
1570 virtual void SetUp() override {
1571 BluetoothAudioProviderFactoryAidl::SetUp();
1572 GetProviderCapabilitiesHelper(SessionType::HFP_SOFTWARE_DECODING_DATAPATH);
1573 OpenProviderHelper(SessionType::HFP_SOFTWARE_DECODING_DATAPATH);
1574 ASSERT_NE(audio_provider_, nullptr);
1575 }
1576
1577 virtual void TearDown() override {
1578 audio_port_ = nullptr;
1579 audio_provider_ = nullptr;
1580 BluetoothAudioProviderFactoryAidl::TearDown();
1581 }
1582
1583 bool OpenSession(int32_t sample_rate, int8_t bits_per_sample,
Bao Do5b2fdab2023-11-20 08:02:55 +00001584 ChannelMode channel_mode, int32_t data_interval_us) {
Bao Do72399432023-11-09 08:13:05 +00001585 PcmConfiguration pcm_config{
1586 .sampleRateHz = sample_rate,
1587 .channelMode = channel_mode,
1588 .bitsPerSample = bits_per_sample,
1589 .dataIntervalUs = data_interval_us,
1590 };
1591 DataMQDesc mq_desc;
1592 auto aidl_retval = audio_provider_->startSession(
1593 audio_port_, AudioConfiguration(pcm_config), latency_modes, &mq_desc);
1594 DataMQ data_mq(mq_desc);
1595
1596 if (!aidl_retval.isOk()) return false;
1597 if (!data_mq.isValid()) return false;
1598 return true;
1599 }
1600};
1601
1602/**
1603 * Test whether we can open a provider of type
1604 */
1605TEST_P(BluetoothAudioProviderHfpSoftwareDecodingAidl,
1606 OpenHfpSoftwareDecodingProvider) {}
1607
1608/**
1609 * Test whether each provider of type
1610 * SessionType::HFP_SOFTWARE_DECODING_DATAPATH can be started and stopped with
1611 * different PCM config
1612 */
1613TEST_P(BluetoothAudioProviderHfpSoftwareDecodingAidl,
1614 StartAndEndHfpDecodingSoftwareSessionWithPossiblePcmConfig) {
1615 for (auto sample_rate : hfp_sample_rates_) {
1616 for (auto bits_per_sample : hfp_bits_per_samples_) {
1617 for (auto channel_mode : hfp_channel_modes_) {
Bao Do5b2fdab2023-11-20 08:02:55 +00001618 for (auto data_interval_us : hfp_data_interval_us_) {
1619 EXPECT_TRUE(OpenSession(sample_rate, bits_per_sample, channel_mode,
1620 data_interval_us));
1621 EXPECT_TRUE(audio_provider_->endSession().isOk());
Bao Do72399432023-11-09 08:13:05 +00001622 }
1623 }
1624 }
1625 }
1626}
1627
1628/**
Alice Kuoadcceec2022-03-28 13:28:43 +08001629 * openProvider A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH
1630 */
1631class BluetoothAudioProviderA2dpEncodingHardwareAidl
1632 : public BluetoothAudioProviderFactoryAidl {
1633 public:
1634 virtual void SetUp() override {
1635 BluetoothAudioProviderFactoryAidl::SetUp();
1636 GetProviderCapabilitiesHelper(
1637 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
1638 OpenProviderHelper(SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
1639 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
1640 audio_provider_ != nullptr);
1641 }
1642
1643 virtual void TearDown() override {
1644 audio_port_ = nullptr;
1645 audio_provider_ = nullptr;
1646 BluetoothAudioProviderFactoryAidl::TearDown();
1647 }
1648
1649 bool IsOffloadSupported() { return (temp_provider_capabilities_.size() > 0); }
1650};
1651
1652/**
1653 * Test whether we can open a provider of type
1654 */
1655TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1656 OpenA2dpEncodingHardwareProvider) {}
Josh Wu049e2cd2022-01-12 05:42:58 -08001657
1658/**
1659 * Test whether each provider of type
1660 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
1661 * SBC hardware encoding config
1662 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001663TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1664 StartAndEndA2dpSbcEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001665 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00001666 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08001667 }
1668
1669 CodecConfiguration codec_config = {
1670 .codecType = CodecType::SBC,
1671 .encodedAudioBitrate = 328000,
1672 .peerMtu = 1005,
1673 .isScmstEnabled = false,
1674 };
1675 auto sbc_codec_specifics = GetSbcCodecSpecificSupportedList(true);
1676
1677 for (auto& codec_specific : sbc_codec_specifics) {
1678 copy_codec_specific(codec_config.config, codec_specific);
1679 DataMQDesc mq_desc;
1680 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001681 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001682
1683 ASSERT_TRUE(aidl_retval.isOk());
1684 EXPECT_TRUE(audio_provider_->endSession().isOk());
1685 }
1686}
1687
1688/**
1689 * Test whether each provider of type
1690 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
1691 * AAC hardware encoding config
1692 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001693TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1694 StartAndEndA2dpAacEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001695 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00001696 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08001697 }
1698
1699 CodecConfiguration codec_config = {
1700 .codecType = CodecType::AAC,
1701 .encodedAudioBitrate = 320000,
1702 .peerMtu = 1005,
1703 .isScmstEnabled = false,
1704 };
1705 auto aac_codec_specifics = GetAacCodecSpecificSupportedList(true);
1706
1707 for (auto& codec_specific : aac_codec_specifics) {
1708 copy_codec_specific(codec_config.config, codec_specific);
1709 DataMQDesc mq_desc;
1710 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001711 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001712
1713 ASSERT_TRUE(aidl_retval.isOk());
1714 EXPECT_TRUE(audio_provider_->endSession().isOk());
1715 }
1716}
1717
1718/**
1719 * Test whether each provider of type
1720 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
1721 * LDAC hardware encoding config
1722 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001723TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1724 StartAndEndA2dpLdacEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001725 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00001726 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08001727 }
1728
1729 CodecConfiguration codec_config = {
1730 .codecType = CodecType::LDAC,
1731 .encodedAudioBitrate = 990000,
1732 .peerMtu = 1005,
1733 .isScmstEnabled = false,
1734 };
1735 auto ldac_codec_specifics = GetLdacCodecSpecificSupportedList(true);
1736
1737 for (auto& codec_specific : ldac_codec_specifics) {
1738 copy_codec_specific(codec_config.config, codec_specific);
1739 DataMQDesc mq_desc;
1740 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001741 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001742
1743 ASSERT_TRUE(aidl_retval.isOk());
1744 EXPECT_TRUE(audio_provider_->endSession().isOk());
1745 }
1746}
1747
1748/**
1749 * Test whether each provider of type
1750 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
Omer Osmana2587da2022-05-01 03:54:11 +00001751 * Opus hardware encoding config
Josh Wu049e2cd2022-01-12 05:42:58 -08001752 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001753TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
Omer Osmana2587da2022-05-01 03:54:11 +00001754 StartAndEndA2dpOpusEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001755 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00001756 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08001757 }
1758
1759 CodecConfiguration codec_config = {
Omer Osmana2587da2022-05-01 03:54:11 +00001760 .codecType = CodecType::OPUS,
Josh Wu049e2cd2022-01-12 05:42:58 -08001761 .encodedAudioBitrate = 990000,
1762 .peerMtu = 1005,
1763 .isScmstEnabled = false,
1764 };
Omer Osmana2587da2022-05-01 03:54:11 +00001765 auto opus_codec_specifics = GetOpusCodecSpecificSupportedList(true);
Josh Wu049e2cd2022-01-12 05:42:58 -08001766
Omer Osmana2587da2022-05-01 03:54:11 +00001767 for (auto& codec_specific : opus_codec_specifics) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001768 copy_codec_specific(codec_config.config, codec_specific);
1769 DataMQDesc mq_desc;
1770 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001771 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001772
1773 ASSERT_TRUE(aidl_retval.isOk());
1774 EXPECT_TRUE(audio_provider_->endSession().isOk());
1775 }
1776}
1777
1778/**
1779 * Test whether each provider of type
1780 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
1781 * AptX hardware encoding config
1782 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001783TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1784 StartAndEndA2dpAptxEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001785 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00001786 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08001787 }
1788
1789 for (auto codec_type : {CodecType::APTX, CodecType::APTX_HD}) {
1790 CodecConfiguration codec_config = {
1791 .codecType = codec_type,
1792 .encodedAudioBitrate =
1793 (codec_type == CodecType::APTX ? 352000 : 576000),
1794 .peerMtu = 1005,
1795 .isScmstEnabled = false,
1796 };
1797
1798 auto aptx_codec_specifics = GetAptxCodecSpecificSupportedList(
1799 (codec_type == CodecType::APTX_HD ? true : false), true);
1800
1801 for (auto& codec_specific : aptx_codec_specifics) {
1802 copy_codec_specific(codec_config.config, codec_specific);
1803 DataMQDesc mq_desc;
1804 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001805 audio_port_, AudioConfiguration(codec_config), latency_modes,
1806 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001807
1808 ASSERT_TRUE(aidl_retval.isOk());
1809 EXPECT_TRUE(audio_provider_->endSession().isOk());
1810 }
1811 }
1812}
1813
1814/**
1815 * Test whether each provider of type
1816 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
1817 * an invalid codec config
1818 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001819TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1820 StartAndEndA2dpEncodingHardwareSessionInvalidCodecConfig) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001821 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00001822 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08001823 }
1824 ASSERT_NE(audio_provider_, nullptr);
1825
1826 std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
Sagar Verma62df9102022-12-07 17:56:04 +05301827 for (auto codec_type : ndk::enum_range<CodecType>()) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001828 switch (codec_type) {
1829 case CodecType::SBC:
1830 codec_specifics = GetSbcCodecSpecificSupportedList(false);
1831 break;
1832 case CodecType::AAC:
1833 codec_specifics = GetAacCodecSpecificSupportedList(false);
1834 break;
1835 case CodecType::LDAC:
1836 codec_specifics = GetLdacCodecSpecificSupportedList(false);
1837 break;
1838 case CodecType::APTX:
1839 codec_specifics = GetAptxCodecSpecificSupportedList(false, false);
1840 break;
1841 case CodecType::APTX_HD:
1842 codec_specifics = GetAptxCodecSpecificSupportedList(true, false);
1843 break;
Omer Osmana2587da2022-05-01 03:54:11 +00001844 case CodecType::OPUS:
1845 codec_specifics = GetOpusCodecSpecificSupportedList(false);
Josh Wu049e2cd2022-01-12 05:42:58 -08001846 continue;
1847 case CodecType::APTX_ADAPTIVE:
Sagar Verma62df9102022-12-07 17:56:04 +05301848 case CodecType::APTX_ADAPTIVE_LE:
1849 case CodecType::APTX_ADAPTIVE_LEX:
Omer Osmana2587da2022-05-01 03:54:11 +00001850 case CodecType::LC3:
Josh Wu049e2cd2022-01-12 05:42:58 -08001851 case CodecType::VENDOR:
1852 case CodecType::UNKNOWN:
1853 codec_specifics.clear();
1854 break;
1855 }
1856 if (codec_specifics.empty()) {
1857 continue;
1858 }
1859
1860 CodecConfiguration codec_config = {
1861 .codecType = codec_type,
1862 .encodedAudioBitrate = 328000,
1863 .peerMtu = 1005,
1864 .isScmstEnabled = false,
1865 };
1866 for (auto codec_specific : codec_specifics) {
1867 copy_codec_specific(codec_config.config, codec_specific);
1868 DataMQDesc mq_desc;
1869 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001870 audio_port_, AudioConfiguration(codec_config), latency_modes,
1871 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001872
1873 // AIDL call should fail on invalid codec
1874 ASSERT_FALSE(aidl_retval.isOk());
1875 EXPECT_TRUE(audio_provider_->endSession().isOk());
1876 }
1877 }
1878}
1879
1880/**
Bao Do72399432023-11-09 08:13:05 +00001881 * openProvider HFP_HARDWARE_OFFLOAD_DATAPATH
1882 */
1883class BluetoothAudioProviderHfpHardwareAidl
1884 : public BluetoothAudioProviderFactoryAidl {
1885 public:
1886 virtual void SetUp() override {
1887 BluetoothAudioProviderFactoryAidl::SetUp();
1888 OpenProviderHelper(SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH);
1889 // Can open or empty capability
1890 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
1891 audio_provider_ != nullptr);
1892 }
1893
1894 virtual void TearDown() override {
1895 audio_port_ = nullptr;
1896 audio_provider_ = nullptr;
1897 BluetoothAudioProviderFactoryAidl::TearDown();
1898 }
1899
1900 bool OpenSession(CodecId codec_id, int connection_handle, bool nrec,
Bao Do5b2fdab2023-11-20 08:02:55 +00001901 bool controller_codec) {
Bao Do72399432023-11-09 08:13:05 +00001902 // Check if can open session with a Hfp configuration
1903 HfpConfiguration hfp_configuration{
1904 .codecId = codec_id,
1905 .connectionHandle = connection_handle,
1906 .nrec = nrec,
1907 .controllerCodec = controller_codec,
1908 };
1909 DataMQDesc mq_desc;
1910 auto aidl_retval = audio_provider_->startSession(
1911 audio_port_, AudioConfiguration(hfp_configuration), latency_modes,
1912 &mq_desc);
1913
1914 // Only check if aidl is ok to start session.
1915 return aidl_retval.isOk();
1916 }
1917};
1918
1919/**
1920 * Test whether we can open a provider of type
1921 */
1922TEST_P(BluetoothAudioProviderHfpHardwareAidl, OpenHfpHardwareProvider) {}
1923
1924/**
1925 * Test whether each provider of type
1926 * SessionType::HFP_SOFTWARE_DECODING_DATAPATH can be started and stopped with
1927 * different HFP config
1928 */
1929TEST_P(BluetoothAudioProviderHfpHardwareAidl,
1930 StartAndEndHfpHardwareSessionWithPossiblePcmConfig) {
1931 // Try to open with a sample configuration
1932 EXPECT_TRUE(OpenSession(CodecId::Core::CVSD, 6, false, true));
1933 EXPECT_TRUE(audio_provider_->endSession().isOk());
1934}
1935
1936/**
Josh Wu049e2cd2022-01-12 05:42:58 -08001937 * openProvider HEARING_AID_SOFTWARE_ENCODING_DATAPATH
1938 */
1939class BluetoothAudioProviderHearingAidSoftwareAidl
1940 : public BluetoothAudioProviderFactoryAidl {
1941 public:
1942 virtual void SetUp() override {
1943 BluetoothAudioProviderFactoryAidl::SetUp();
1944 GetProviderCapabilitiesHelper(
1945 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
1946 OpenProviderHelper(SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
1947 ASSERT_NE(audio_provider_, nullptr);
1948 }
1949
1950 virtual void TearDown() override {
1951 audio_port_ = nullptr;
1952 audio_provider_ = nullptr;
1953 BluetoothAudioProviderFactoryAidl::TearDown();
1954 }
1955
1956 static constexpr int32_t hearing_aid_sample_rates_[] = {0, 16000, 24000};
1957 static constexpr int8_t hearing_aid_bits_per_samples_[] = {0, 16, 24};
1958 static constexpr ChannelMode hearing_aid_channel_modes_[] = {
1959 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
1960};
1961
1962/**
1963 * Test whether we can open a provider of type
1964 */
1965TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl,
1966 OpenHearingAidSoftwareProvider) {}
1967
1968/**
1969 * Test whether each provider of type
1970 * SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH can be started and
1971 * stopped with different PCM config
1972 */
1973TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl,
1974 StartAndEndHearingAidSessionWithPossiblePcmConfig) {
1975 for (int32_t sample_rate : hearing_aid_sample_rates_) {
1976 for (int8_t bits_per_sample : hearing_aid_bits_per_samples_) {
1977 for (auto channel_mode : hearing_aid_channel_modes_) {
1978 PcmConfiguration pcm_config{
1979 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08001980 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00001981 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08001982 };
1983 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
1984 DataMQDesc mq_desc;
1985 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001986 audio_port_, AudioConfiguration(pcm_config), latency_modes,
1987 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001988 DataMQ data_mq(mq_desc);
1989
1990 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
1991 if (is_codec_config_valid) {
1992 EXPECT_TRUE(data_mq.isValid());
1993 }
1994 EXPECT_TRUE(audio_provider_->endSession().isOk());
1995 }
1996 }
1997 }
1998}
1999
2000/**
2001 * openProvider LE_AUDIO_SOFTWARE_ENCODING_DATAPATH
2002 */
2003class BluetoothAudioProviderLeAudioOutputSoftwareAidl
2004 : public BluetoothAudioProviderFactoryAidl {
2005 public:
2006 virtual void SetUp() override {
2007 BluetoothAudioProviderFactoryAidl::SetUp();
2008 GetProviderCapabilitiesHelper(
2009 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
2010 OpenProviderHelper(SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
2011 ASSERT_NE(audio_provider_, nullptr);
2012 }
2013
2014 virtual void TearDown() override {
2015 audio_port_ = nullptr;
2016 audio_provider_ = nullptr;
2017 BluetoothAudioProviderFactoryAidl::TearDown();
2018 }
2019
2020 static constexpr int32_t le_audio_output_sample_rates_[] = {
2021 0, 8000, 16000, 24000, 32000, 44100, 48000,
2022 };
2023 static constexpr int8_t le_audio_output_bits_per_samples_[] = {0, 16, 24};
2024 static constexpr ChannelMode le_audio_output_channel_modes_[] = {
2025 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
2026 static constexpr int32_t le_audio_output_data_interval_us_[] = {
2027 0 /* Invalid */, 10000 /* Valid 10ms */};
2028};
2029
2030/**
2031 * Test whether each provider of type
2032 * SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH can be started and
2033 * stopped
2034 */
2035TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl,
2036 OpenLeAudioOutputSoftwareProvider) {}
2037
2038/**
2039 * Test whether each provider of type
2040 * SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH can be started and
2041 * stopped with different PCM config
2042 */
2043TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl,
2044 StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
2045 for (auto sample_rate : le_audio_output_sample_rates_) {
2046 for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
2047 for (auto channel_mode : le_audio_output_channel_modes_) {
2048 for (auto data_interval_us : le_audio_output_data_interval_us_) {
2049 PcmConfiguration pcm_config{
2050 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08002051 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00002052 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08002053 .dataIntervalUs = data_interval_us,
2054 };
Josh Wu8a1be762022-02-15 09:37:29 -08002055 bool is_codec_config_valid =
2056 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
Josh Wu049e2cd2022-01-12 05:42:58 -08002057 DataMQDesc mq_desc;
2058 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002059 audio_port_, AudioConfiguration(pcm_config), latency_modes,
2060 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002061 DataMQ data_mq(mq_desc);
2062
2063 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
2064 if (is_codec_config_valid) {
2065 EXPECT_TRUE(data_mq.isValid());
2066 }
2067 EXPECT_TRUE(audio_provider_->endSession().isOk());
2068 }
2069 }
2070 }
2071 }
2072}
2073
2074/**
Alice Kuo04a399a2022-02-16 09:19:56 +08002075 * openProvider LE_AUDIO_SOFTWARE_DECODING_DATAPATH
Josh Wu049e2cd2022-01-12 05:42:58 -08002076 */
2077class BluetoothAudioProviderLeAudioInputSoftwareAidl
2078 : public BluetoothAudioProviderFactoryAidl {
2079 public:
2080 virtual void SetUp() override {
2081 BluetoothAudioProviderFactoryAidl::SetUp();
2082 GetProviderCapabilitiesHelper(
2083 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH);
2084 OpenProviderHelper(SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH);
2085 ASSERT_NE(audio_provider_, nullptr);
2086 }
2087
2088 virtual void TearDown() override {
2089 audio_port_ = nullptr;
2090 audio_provider_ = nullptr;
2091 BluetoothAudioProviderFactoryAidl::TearDown();
2092 }
2093
2094 static constexpr int32_t le_audio_input_sample_rates_[] = {
2095 0, 8000, 16000, 24000, 32000, 44100, 48000};
2096 static constexpr int8_t le_audio_input_bits_per_samples_[] = {0, 16, 24};
2097 static constexpr ChannelMode le_audio_input_channel_modes_[] = {
2098 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
2099 static constexpr int32_t le_audio_input_data_interval_us_[] = {
2100 0 /* Invalid */, 10000 /* Valid 10ms */};
2101};
2102
2103/**
2104 * Test whether each provider of type
Alice Kuo04a399a2022-02-16 09:19:56 +08002105 * SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002106 * stopped
2107 */
2108TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl,
2109 OpenLeAudioInputSoftwareProvider) {}
2110
2111/**
2112 * Test whether each provider of type
Alice Kuo04a399a2022-02-16 09:19:56 +08002113 * SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002114 * stopped with different PCM config
2115 */
2116TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl,
2117 StartAndEndLeAudioInputSessionWithPossiblePcmConfig) {
2118 for (auto sample_rate : le_audio_input_sample_rates_) {
2119 for (auto bits_per_sample : le_audio_input_bits_per_samples_) {
2120 for (auto channel_mode : le_audio_input_channel_modes_) {
2121 for (auto data_interval_us : le_audio_input_data_interval_us_) {
2122 PcmConfiguration pcm_config{
2123 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08002124 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00002125 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08002126 .dataIntervalUs = data_interval_us,
2127 };
Josh Wu8a1be762022-02-15 09:37:29 -08002128 bool is_codec_config_valid =
2129 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
Josh Wu049e2cd2022-01-12 05:42:58 -08002130 DataMQDesc mq_desc;
2131 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002132 audio_port_, AudioConfiguration(pcm_config), latency_modes,
2133 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002134 DataMQ data_mq(mq_desc);
2135
2136 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
2137 if (is_codec_config_valid) {
2138 EXPECT_TRUE(data_mq.isValid());
2139 }
2140 EXPECT_TRUE(audio_provider_->endSession().isOk());
2141 }
2142 }
2143 }
2144 }
2145}
2146
2147/**
Alice Kuo04a399a2022-02-16 09:19:56 +08002148 * openProvider LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH
Josh Wu049e2cd2022-01-12 05:42:58 -08002149 */
2150class BluetoothAudioProviderLeAudioOutputHardwareAidl
2151 : public BluetoothAudioProviderFactoryAidl {
2152 public:
2153 virtual void SetUp() override {
2154 BluetoothAudioProviderFactoryAidl::SetUp();
2155 GetProviderCapabilitiesHelper(
2156 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
Bao Doc36897d2023-12-06 01:27:54 +00002157 GetProviderInfoHelper(
2158 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
Josh Wu049e2cd2022-01-12 05:42:58 -08002159 OpenProviderHelper(
2160 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
2161 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
2162 audio_provider_ != nullptr);
2163 }
2164
2165 virtual void TearDown() override {
2166 audio_port_ = nullptr;
2167 audio_provider_ = nullptr;
2168 BluetoothAudioProviderFactoryAidl::TearDown();
2169 }
2170
2171 bool IsOffloadOutputSupported() {
2172 for (auto& capability : temp_provider_capabilities_) {
2173 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2174 continue;
2175 }
2176 auto& le_audio_capability =
2177 capability.get<AudioCapabilities::leAudioCapabilities>();
2178 if (le_audio_capability.unicastEncodeCapability.codecType !=
2179 CodecType::UNKNOWN)
2180 return true;
2181 }
2182 return false;
2183 }
2184
Bao Doc36897d2023-12-06 01:27:54 +00002185 bool IsOffloadOutputProviderInfoSupported() {
2186 if (!temp_provider_info_.has_value()) return false;
2187 if (temp_provider_info_.value().codecInfos.empty()) return false;
2188 // Check if all codec info is of LeAudio type
2189 for (auto& codec_info : temp_provider_info_.value().codecInfos) {
2190 if (codec_info.transport.getTag() != CodecInfo::Transport::leAudio)
2191 return false;
2192 }
2193 return true;
2194 }
2195
2196 std::vector<Lc3Configuration> GetUnicastLc3SupportedListFromProviderInfo() {
2197 std::vector<Lc3Configuration> le_audio_codec_configs;
2198 for (auto& codec_info : temp_provider_info_.value().codecInfos) {
2199 // Only gets LC3 codec information
2200 if (codec_info.id != CodecId::Core::LC3) continue;
2201 // Combine those parameters into one list of Lc3Configuration
2202 auto& transport =
2203 codec_info.transport.get<CodecInfo::Transport::Tag::leAudio>();
2204 for (int32_t samplingFrequencyHz : transport.samplingFrequencyHz) {
2205 for (int32_t frameDurationUs : transport.frameDurationUs) {
2206 for (int32_t octetsPerFrame : transport.bitdepth) {
2207 Lc3Configuration lc3_config = {
2208 .samplingFrequencyHz = samplingFrequencyHz,
2209 .frameDurationUs = frameDurationUs,
2210 .octetsPerFrame = octetsPerFrame,
2211 };
2212 le_audio_codec_configs.push_back(lc3_config);
2213 }
2214 }
2215 }
2216 }
2217
2218 return le_audio_codec_configs;
2219 }
2220
2221 AudioContext GetAudioContext(int32_t bitmask) {
2222 AudioContext media_audio_context;
2223 media_audio_context.bitmask = bitmask;
2224 return media_audio_context;
2225 }
2226
2227 LeAudioDeviceCapabilities GetDefaultRemoteCapability() {
2228 // Create a capability
2229 LeAudioDeviceCapabilities capability;
2230
2231 capability.codecId = CodecId::Core::LC3;
2232
2233 auto pref_context_metadata = MetadataLtv::PreferredAudioContexts();
2234 pref_context_metadata.values = GetAudioContext(AudioContext::MEDIA);
2235 capability.metadata = {pref_context_metadata};
2236
2237 auto sampling_rate =
2238 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies();
2239 sampling_rate.bitmask =
2240 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ8000;
2241 auto frame_duration =
2242 CodecSpecificCapabilitiesLtv::SupportedFrameDurations();
2243 frame_duration.bitmask =
2244 CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US7500;
2245 auto octets = CodecSpecificCapabilitiesLtv::SupportedOctetsPerCodecFrame();
2246 octets.minimum = 0;
2247 octets.maximum = 60;
2248 auto frames = CodecSpecificCapabilitiesLtv::SupportedMaxCodecFramesPerSDU();
2249 frames.value = 2;
2250 capability.codecSpecificCapabilities = {sampling_rate, frame_duration,
2251 octets, frames};
2252 return capability;
2253 }
2254
2255 LeAudioConfigurationRequirement GetDefaultRequirement(
2256 bool is_source_requriement) {
2257 // Create a requirements
2258 LeAudioConfigurationRequirement requirement;
2259 requirement.audioContext = GetAudioContext(AudioContext::MEDIA);
2260
2261 auto direction_ase_requriement = AseDirectionRequirement();
2262 direction_ase_requriement.aseConfiguration.codecId = CodecId::Core::LC3;
2263 direction_ase_requriement.aseConfiguration.targetLatency =
2264 LeAudioAseConfiguration::TargetLatency::BALANCED_LATENCY_RELIABILITY;
2265
2266 // Mismatch sampling frequency
2267 direction_ase_requriement.aseConfiguration.codecConfiguration = {
2268 CodecSpecificConfigurationLtv::SamplingFrequency::HZ11025,
2269 CodecSpecificConfigurationLtv::FrameDuration::US7500,
2270 };
2271 if (is_source_requriement)
2272 requirement.sourceAseRequirement = {direction_ase_requriement};
2273 else
2274 requirement.sinkAseRequirement = {direction_ase_requriement};
2275 return requirement;
2276 }
2277
Josh Wu049e2cd2022-01-12 05:42:58 -08002278 std::vector<Lc3Configuration> GetUnicastLc3SupportedList(bool decoding,
2279 bool supported) {
2280 std::vector<Lc3Configuration> le_audio_codec_configs;
2281 if (!supported) {
shihchienc3ab9f5e2022-09-23 08:18:05 +00002282 Lc3Configuration lc3_config{.pcmBitDepth = 0, .samplingFrequencyHz = 0};
Josh Wu049e2cd2022-01-12 05:42:58 -08002283 le_audio_codec_configs.push_back(lc3_config);
2284 return le_audio_codec_configs;
2285 }
2286
2287 // There might be more than one LeAudioCodecCapabilitiesSetting
2288 std::vector<Lc3Capabilities> lc3_capabilities;
2289 for (auto& capability : temp_provider_capabilities_) {
2290 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2291 continue;
2292 }
2293 auto& le_audio_capability =
2294 capability.get<AudioCapabilities::leAudioCapabilities>();
2295 auto& unicast_capability =
2296 decoding ? le_audio_capability.unicastDecodeCapability
2297 : le_audio_capability.unicastEncodeCapability;
2298 if (unicast_capability.codecType != CodecType::LC3) {
2299 continue;
2300 }
2301 auto& lc3_capability = unicast_capability.leAudioCodecCapabilities.get<
2302 UnicastCapability::LeAudioCodecCapabilities::lc3Capabilities>();
2303 lc3_capabilities.push_back(lc3_capability);
2304 }
2305
2306 // Combine those parameters into one list of LeAudioCodecConfiguration
2307 // This seems horrible, but usually each Lc3Capability only contains a
2308 // single Lc3Configuration, which means every array has a length of 1.
2309 for (auto& lc3_capability : lc3_capabilities) {
2310 for (int32_t samplingFrequencyHz : lc3_capability.samplingFrequencyHz) {
2311 for (int32_t frameDurationUs : lc3_capability.frameDurationUs) {
2312 for (int32_t octetsPerFrame : lc3_capability.octetsPerFrame) {
2313 Lc3Configuration lc3_config = {
2314 .samplingFrequencyHz = samplingFrequencyHz,
2315 .frameDurationUs = frameDurationUs,
2316 .octetsPerFrame = octetsPerFrame,
2317 };
2318 le_audio_codec_configs.push_back(lc3_config);
2319 }
2320 }
2321 }
2322 }
2323
2324 return le_audio_codec_configs;
2325 }
2326
Sagar Verma62df9102022-12-07 17:56:04 +05302327 static constexpr int32_t apx_adaptive_le_config_codec_modes[] = {0, 1, 2, 3};
2328
2329 std::vector<AptxAdaptiveLeConfiguration>
2330 GetUnicastAptxAdaptiveLeSupportedList(bool decoding, bool supported,
2331 bool is_le_extended) {
2332 std::vector<AptxAdaptiveLeConfiguration> le_audio_codec_configs;
2333 if (!supported) {
2334 AptxAdaptiveLeConfiguration aptx_adaptive_le_config{
2335 .pcmBitDepth = 0, .samplingFrequencyHz = 0};
2336 le_audio_codec_configs.push_back(aptx_adaptive_le_config);
2337 return le_audio_codec_configs;
2338 }
2339
2340 // There might be more than one LeAudioCodecCapabilitiesSetting
2341 std::vector<AptxAdaptiveLeCapabilities> aptx_adaptive_le_capabilities;
2342 for (auto& capability : temp_provider_capabilities_) {
2343 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2344 continue;
2345 }
2346 auto& le_audio_capability =
2347 capability.get<AudioCapabilities::leAudioCapabilities>();
2348 auto& unicast_capability =
2349 decoding ? le_audio_capability.unicastDecodeCapability
2350 : le_audio_capability.unicastEncodeCapability;
2351 if ((!is_le_extended &&
2352 unicast_capability.codecType != CodecType::APTX_ADAPTIVE_LE) ||
2353 (is_le_extended &&
2354 unicast_capability.codecType != CodecType::APTX_ADAPTIVE_LEX)) {
2355 continue;
2356 }
2357
2358 auto& aptx_adaptive_le_capability =
2359 unicast_capability.leAudioCodecCapabilities
2360 .get<UnicastCapability::LeAudioCodecCapabilities::
2361 aptxAdaptiveLeCapabilities>();
2362
2363 aptx_adaptive_le_capabilities.push_back(aptx_adaptive_le_capability);
2364 }
2365
2366 for (auto& aptx_adaptive_le_capability : aptx_adaptive_le_capabilities) {
2367 for (int32_t samplingFrequencyHz :
2368 aptx_adaptive_le_capability.samplingFrequencyHz) {
2369 for (int32_t frameDurationUs :
2370 aptx_adaptive_le_capability.frameDurationUs) {
2371 for (int32_t octetsPerFrame :
2372 aptx_adaptive_le_capability.octetsPerFrame) {
2373 for (int8_t blocksPerSdu :
2374 aptx_adaptive_le_capability.blocksPerSdu) {
2375 for (int32_t codecMode : apx_adaptive_le_config_codec_modes) {
2376 AptxAdaptiveLeConfiguration aptx_adaptive_le_config = {
2377 .samplingFrequencyHz = samplingFrequencyHz,
2378 .frameDurationUs = frameDurationUs,
2379 .octetsPerFrame = octetsPerFrame,
2380 .blocksPerSdu = blocksPerSdu,
2381 .codecMode = codecMode,
2382 };
2383 le_audio_codec_configs.push_back(aptx_adaptive_le_config);
2384 }
2385 }
2386 }
2387 }
2388 }
2389 }
2390
2391 return le_audio_codec_configs;
2392 }
2393
Josh Wu049e2cd2022-01-12 05:42:58 -08002394 LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
Bao Doc36897d2023-12-06 01:27:54 +00002395 std::vector<int32_t> all_context_bitmasks = {
2396 AudioContext::UNSPECIFIED, AudioContext::CONVERSATIONAL,
2397 AudioContext::MEDIA, AudioContext::GAME,
2398 AudioContext::INSTRUCTIONAL, AudioContext::VOICE_ASSISTANTS,
2399 AudioContext::LIVE_AUDIO, AudioContext::SOUND_EFFECTS,
2400 AudioContext::NOTIFICATIONS, AudioContext::RINGTONE_ALERTS,
2401 AudioContext::ALERTS, AudioContext::EMERGENCY_ALARM,
2402 };
Josh Wu049e2cd2022-01-12 05:42:58 -08002403};
2404
2405/**
2406 * Test whether each provider of type
2407 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2408 * stopped
2409 */
2410TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2411 OpenLeAudioOutputHardwareProvider) {}
2412
2413/**
2414 * Test whether each provider of type
2415 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
Bao Doc36897d2023-12-06 01:27:54 +00002416 * stopped with Unicast hardware encoding config taken from provider info
2417 */
2418TEST_P(
2419 BluetoothAudioProviderLeAudioOutputHardwareAidl,
2420 StartAndEndLeAudioOutputSessionWithPossibleUnicastConfigFromProviderInfo) {
2421 if (!IsOffloadOutputProviderInfoSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002422 GTEST_SKIP();
Bao Doc36897d2023-12-06 01:27:54 +00002423 }
2424
2425 auto lc3_codec_configs = GetUnicastLc3SupportedListFromProviderInfo();
2426 LeAudioConfiguration le_audio_config = {
2427 .codecType = CodecType::LC3,
2428 .peerDelayUs = 0,
2429 };
2430
2431 for (auto& lc3_config : lc3_codec_configs) {
2432 le_audio_config.leAudioCodecConfig
2433 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2434 DataMQDesc mq_desc;
2435 auto aidl_retval = audio_provider_->startSession(
2436 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2437 &mq_desc);
2438
2439 ASSERT_TRUE(aidl_retval.isOk());
2440 EXPECT_TRUE(audio_provider_->endSession().isOk());
2441 }
2442}
2443
2444TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2445 GetEmptyAseConfigurationEmptyCapability) {
2446 std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
2447 std::vector<LeAudioConfigurationRequirement> empty_requirement;
2448 std::vector<LeAudioAseConfigurationSetting> configurations;
2449
2450 // Check empty capability for source direction
2451 auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
2452 std::nullopt, empty_capability, empty_requirement, &configurations);
2453
2454 ASSERT_TRUE(aidl_retval.isOk());
2455 ASSERT_TRUE(configurations.empty());
2456
2457 // Check empty capability for sink direction
2458 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
2459 empty_capability, std::nullopt, empty_requirement, &configurations);
2460
2461 ASSERT_TRUE(aidl_retval.isOk());
2462 ASSERT_TRUE(configurations.empty());
2463}
2464
2465TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2466 GetEmptyAseConfigurationMismatchedRequirement) {
2467 std::vector<std::optional<LeAudioDeviceCapabilities>> capabilities = {
2468 GetDefaultRemoteCapability()};
2469
2470 // Check empty capability for source direction
2471 std::vector<LeAudioAseConfigurationSetting> configurations;
2472 std::vector<LeAudioConfigurationRequirement> source_requirements = {
2473 GetDefaultRequirement(true)};
2474 auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
2475 std::nullopt, capabilities, source_requirements, &configurations);
2476
2477 ASSERT_TRUE(aidl_retval.isOk());
2478 ASSERT_TRUE(configurations.empty());
2479
2480 // Check empty capability for sink direction
2481 std::vector<LeAudioConfigurationRequirement> sink_requirements = {
2482 GetDefaultRequirement(false)};
2483 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
2484 capabilities, std::nullopt, source_requirements, &configurations);
2485
2486 ASSERT_TRUE(aidl_retval.isOk());
2487 ASSERT_TRUE(configurations.empty());
2488}
2489
2490TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl, GetQoSConfiguration) {
2491 IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement requirement;
2492 std::vector<IBluetoothAudioProvider::LeAudioAseQosConfiguration>
2493 QoSConfigurations;
2494 for (auto bitmask : all_context_bitmasks) {
2495 requirement.contextType = GetAudioContext(bitmask);
2496 IBluetoothAudioProvider::LeAudioAseQosConfigurationPair result;
2497 auto aidl_retval =
2498 audio_provider_->getLeAudioAseQosConfiguration(requirement, &result);
2499 ASSERT_TRUE(aidl_retval.isOk());
2500 if (result.sinkQosConfiguration.has_value())
2501 QoSConfigurations.push_back(result.sinkQosConfiguration.value());
2502 if (result.sourceQosConfiguration.has_value())
2503 QoSConfigurations.push_back(result.sourceQosConfiguration.value());
2504 }
2505 // QoS Configurations should not be empty, as we searched for all contexts
2506 ASSERT_FALSE(QoSConfigurations.empty());
2507}
Jakub Tyszkowskic8a62242024-01-05 15:25:49 +00002508
2509TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2510 GetDataPathConfiguration) {
2511 IBluetoothAudioProvider::StreamConfig sink_requirement;
2512 IBluetoothAudioProvider::StreamConfig source_requirement;
2513 std::vector<IBluetoothAudioProvider::LeAudioDataPathConfiguration>
2514 DataPathConfigurations;
2515 bool is_supported = false;
2516
2517 for (auto bitmask : all_context_bitmasks) {
2518 sink_requirement.context = GetAudioContext(bitmask);
2519 source_requirement.context = GetAudioContext(bitmask);
2520 IBluetoothAudioProvider::LeAudioDataPathConfigurationPair result;
2521 auto aidl_retval = audio_provider_->getLeAudioAseDatapathConfiguration(
2522 sink_requirement, source_requirement, &result);
2523 if (!aidl_retval.isOk()) {
2524 // If not OK, then it could be not supported, as it is an optional feature
2525 ASSERT_EQ(aidl_retval.getExceptionCode(), EX_UNSUPPORTED_OPERATION);
2526 } else {
2527 is_supported = true;
2528 if (result.inputConfig.has_value())
2529 DataPathConfigurations.push_back(result.inputConfig.value());
2530 if (result.inputConfig.has_value())
2531 DataPathConfigurations.push_back(result.inputConfig.value());
2532 }
2533 }
2534
2535 if (is_supported) {
2536 // Datapath Configurations should not be empty, as we searched for all
2537 // contexts
2538 ASSERT_FALSE(DataPathConfigurations.empty());
2539 }
2540}
2541
Bao Doc36897d2023-12-06 01:27:54 +00002542/**
2543 * Test whether each provider of type
2544 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002545 * stopped with Unicast hardware encoding config
2546 */
2547TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2548 StartAndEndLeAudioOutputSessionWithPossibleUnicastConfig) {
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 */, true /* 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 ASSERT_TRUE(aidl_retval.isOk());
2569 EXPECT_TRUE(audio_provider_->endSession().isOk());
2570 }
2571}
2572
2573/**
2574 * Test whether each provider of type
2575 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2576 * stopped with Unicast hardware encoding config
2577 *
2578 * Disabled since offload codec checking is not ready
2579 */
2580TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2581 DISABLED_StartAndEndLeAudioOutputSessionWithInvalidAudioConfiguration) {
2582 if (!IsOffloadOutputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002583 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08002584 }
2585
2586 auto lc3_codec_configs =
2587 GetUnicastLc3SupportedList(false /* decoding */, false /* supported */);
2588 LeAudioConfiguration le_audio_config = {
2589 .codecType = CodecType::LC3,
2590 .peerDelayUs = 0,
2591 };
2592
2593 for (auto& lc3_config : lc3_codec_configs) {
2594 le_audio_config.leAudioCodecConfig
2595 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2596 DataMQDesc mq_desc;
2597 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002598 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2599 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002600
2601 // AIDL call should fail on invalid codec
2602 ASSERT_FALSE(aidl_retval.isOk());
2603 EXPECT_TRUE(audio_provider_->endSession().isOk());
2604 }
2605}
2606
Sagar Verma62df9102022-12-07 17:56:04 +05302607static std::vector<uint8_t> vendorMetadata = {0x0B, // Length
2608 0xFF, // Type: Vendor-specific
2609 0x0A, 0x00, // Company_ID
2610 0x01, 0x02, 0x03, 0x04, // Data
2611 0x05, 0x06, 0x07, 0x08};
2612
2613/**
2614 * Test whether each provider of type
2615 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2616 * stopped with Unicast hardware encoding config
2617 */
2618TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2619 StartAndEndLeAudioOutputSessionWithAptxAdaptiveLeUnicastConfig) {
2620 if (!IsOffloadOutputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002621 GTEST_SKIP();
Sagar Verma62df9102022-12-07 17:56:04 +05302622 }
2623 for (auto codec_type :
2624 {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
2625 bool is_le_extended = (codec_type == CodecType::APTX_ADAPTIVE_LEX);
2626 auto aptx_adaptive_le_codec_configs =
2627 GetUnicastAptxAdaptiveLeSupportedList(false, true, is_le_extended);
2628 LeAudioConfiguration le_audio_config = {
2629 .codecType = codec_type,
2630 .peerDelayUs = 0,
2631 .vendorSpecificMetadata = vendorMetadata,
2632 };
2633
2634 for (auto& aptx_adaptive_le_config : aptx_adaptive_le_codec_configs) {
2635 le_audio_config.leAudioCodecConfig
2636 .set<LeAudioCodecConfiguration::aptxAdaptiveLeConfig>(
2637 aptx_adaptive_le_config);
2638 DataMQDesc mq_desc;
2639 auto aidl_retval = audio_provider_->startSession(
2640 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2641 &mq_desc);
2642
2643 ASSERT_TRUE(aidl_retval.isOk());
2644 EXPECT_TRUE(audio_provider_->endSession().isOk());
2645 }
2646 }
2647}
2648
2649/**
2650 * Test whether each provider of type
2651 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2652 * stopped with Unicast hardware encoding config
2653 */
2654TEST_P(
2655 BluetoothAudioProviderLeAudioOutputHardwareAidl,
2656 BluetoothAudioProviderLeAudioOutputHardwareAidl_StartAndEndLeAudioOutputSessionWithInvalidAptxAdaptiveLeAudioConfiguration) {
2657 if (!IsOffloadOutputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002658 GTEST_SKIP();
Sagar Verma62df9102022-12-07 17:56:04 +05302659 }
2660
2661 for (auto codec_type :
2662 {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
2663 bool is_le_extended = (codec_type == CodecType::APTX_ADAPTIVE_LEX);
2664 auto aptx_adaptive_le_codec_configs =
2665 GetUnicastAptxAdaptiveLeSupportedList(false, true, is_le_extended);
2666 LeAudioConfiguration le_audio_config = {
2667 .codecType = codec_type,
2668 .peerDelayUs = 0,
2669 .vendorSpecificMetadata = vendorMetadata,
2670 };
2671
2672 for (auto& aptx_adaptive_le_config : aptx_adaptive_le_codec_configs) {
2673 le_audio_config.leAudioCodecConfig
2674 .set<LeAudioCodecConfiguration::aptxAdaptiveLeConfig>(
2675 aptx_adaptive_le_config);
2676 DataMQDesc mq_desc;
2677 auto aidl_retval = audio_provider_->startSession(
2678 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2679 &mq_desc);
2680
2681 // AIDL call should fail on invalid codec
2682 ASSERT_FALSE(aidl_retval.isOk());
2683 EXPECT_TRUE(audio_provider_->endSession().isOk());
2684 }
2685 }
2686}
2687
Josh Wu049e2cd2022-01-12 05:42:58 -08002688/**
2689 * openProvider LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH
2690 */
2691class BluetoothAudioProviderLeAudioInputHardwareAidl
2692 : public BluetoothAudioProviderLeAudioOutputHardwareAidl {
2693 public:
2694 virtual void SetUp() override {
2695 BluetoothAudioProviderFactoryAidl::SetUp();
2696 GetProviderCapabilitiesHelper(
2697 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
Bao Doc36897d2023-12-06 01:27:54 +00002698 GetProviderInfoHelper(
2699 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
Josh Wu049e2cd2022-01-12 05:42:58 -08002700 OpenProviderHelper(
2701 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
2702 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
2703 audio_provider_ != nullptr);
2704 }
2705
2706 bool IsOffloadInputSupported() {
2707 for (auto& capability : temp_provider_capabilities_) {
2708 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2709 continue;
2710 }
2711 auto& le_audio_capability =
2712 capability.get<AudioCapabilities::leAudioCapabilities>();
2713 if (le_audio_capability.unicastDecodeCapability.codecType !=
2714 CodecType::UNKNOWN)
2715 return true;
2716 }
2717 return false;
2718 }
2719
2720 virtual void TearDown() override {
2721 audio_port_ = nullptr;
2722 audio_provider_ = nullptr;
2723 BluetoothAudioProviderFactoryAidl::TearDown();
2724 }
2725};
2726
2727/**
2728 * Test whether each provider of type
Bao Doc36897d2023-12-06 01:27:54 +00002729 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002730 * stopped
2731 */
2732TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
2733 OpenLeAudioInputHardwareProvider) {}
2734
2735/**
2736 * Test whether each provider of type
Bao Doc36897d2023-12-06 01:27:54 +00002737 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
2738 * stopped with Unicast hardware encoding config taken from provider info
2739 */
2740TEST_P(
2741 BluetoothAudioProviderLeAudioInputHardwareAidl,
2742 StartAndEndLeAudioInputSessionWithPossibleUnicastConfigFromProviderInfo) {
2743 if (!IsOffloadOutputProviderInfoSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002744 GTEST_SKIP();
Bao Doc36897d2023-12-06 01:27:54 +00002745 }
2746
2747 auto lc3_codec_configs = GetUnicastLc3SupportedListFromProviderInfo();
2748 LeAudioConfiguration le_audio_config = {
2749 .codecType = CodecType::LC3,
2750 .peerDelayUs = 0,
2751 };
2752
2753 for (auto& lc3_config : lc3_codec_configs) {
2754 le_audio_config.leAudioCodecConfig
2755 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2756 DataMQDesc mq_desc;
2757 auto aidl_retval = audio_provider_->startSession(
2758 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2759 &mq_desc);
2760
2761 ASSERT_TRUE(aidl_retval.isOk());
2762 EXPECT_TRUE(audio_provider_->endSession().isOk());
2763 }
2764}
2765
2766/**
2767 * Test whether each provider of type
2768 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002769 * stopped with Unicast hardware encoding config
2770 */
2771TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
2772 StartAndEndLeAudioInputSessionWithPossibleUnicastConfig) {
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 */, true /* 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 DataMQDesc mq_desc;
2788 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002789 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2790 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002791
2792 ASSERT_TRUE(aidl_retval.isOk());
2793 EXPECT_TRUE(audio_provider_->endSession().isOk());
2794 }
2795}
2796
2797/**
2798 * Test whether each provider of type
Bao Doc36897d2023-12-06 01:27:54 +00002799 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002800 * stopped with Unicast hardware encoding config
2801 *
2802 * Disabled since offload codec checking is not ready
2803 */
2804TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
2805 DISABLED_StartAndEndLeAudioInputSessionWithInvalidAudioConfiguration) {
2806 if (!IsOffloadInputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002807 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08002808 }
2809
2810 auto lc3_codec_configs =
2811 GetUnicastLc3SupportedList(true /* decoding */, false /* supported */);
2812 LeAudioConfiguration le_audio_config = {
2813 .codecType = CodecType::LC3,
2814 .peerDelayUs = 0,
2815 };
2816
2817 for (auto& lc3_config : lc3_codec_configs) {
2818 le_audio_config.leAudioCodecConfig
2819 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2820
2821 DataMQDesc mq_desc;
2822 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002823 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2824 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002825
2826 // AIDL call should fail on invalid codec
2827 ASSERT_FALSE(aidl_retval.isOk());
2828 EXPECT_TRUE(audio_provider_->endSession().isOk());
2829 }
2830}
2831
2832/**
2833 * openProvider LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH
2834 */
2835class BluetoothAudioProviderLeAudioBroadcastSoftwareAidl
2836 : public BluetoothAudioProviderFactoryAidl {
2837 public:
2838 virtual void SetUp() override {
2839 BluetoothAudioProviderFactoryAidl::SetUp();
2840 GetProviderCapabilitiesHelper(
2841 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
2842 OpenProviderHelper(
2843 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
2844 ASSERT_NE(audio_provider_, nullptr);
2845 }
2846
2847 virtual void TearDown() override {
2848 audio_port_ = nullptr;
2849 audio_provider_ = nullptr;
2850 BluetoothAudioProviderFactoryAidl::TearDown();
2851 }
2852
2853 static constexpr int32_t le_audio_output_sample_rates_[] = {
2854 0, 8000, 16000, 24000, 32000, 44100, 48000,
2855 };
2856 static constexpr int8_t le_audio_output_bits_per_samples_[] = {0, 16, 24};
2857 static constexpr ChannelMode le_audio_output_channel_modes_[] = {
2858 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
2859 static constexpr int32_t le_audio_output_data_interval_us_[] = {
2860 0 /* Invalid */, 10000 /* Valid 10ms */};
2861};
2862
2863/**
2864 * Test whether each provider of type
2865 * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started and
2866 * stopped
2867 */
2868TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
Josh Wu3202eab2022-02-17 18:09:05 -08002869 OpenLeAudioOutputSoftwareProvider) {}
Josh Wu049e2cd2022-01-12 05:42:58 -08002870
2871/**
2872 * Test whether each provider of type
2873 * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started and
2874 * stopped with different PCM config
2875 */
2876TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
Josh Wu3202eab2022-02-17 18:09:05 -08002877 StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
Josh Wu049e2cd2022-01-12 05:42:58 -08002878 for (auto sample_rate : le_audio_output_sample_rates_) {
2879 for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
2880 for (auto channel_mode : le_audio_output_channel_modes_) {
2881 for (auto data_interval_us : le_audio_output_data_interval_us_) {
2882 PcmConfiguration pcm_config{
2883 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08002884 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00002885 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08002886 .dataIntervalUs = data_interval_us,
2887 };
Josh Wu8a1be762022-02-15 09:37:29 -08002888 bool is_codec_config_valid =
2889 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
Josh Wu049e2cd2022-01-12 05:42:58 -08002890 DataMQDesc mq_desc;
2891 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002892 audio_port_, AudioConfiguration(pcm_config), latency_modes,
2893 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002894 DataMQ data_mq(mq_desc);
2895
2896 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
2897 if (is_codec_config_valid) {
2898 EXPECT_TRUE(data_mq.isValid());
2899 }
2900 EXPECT_TRUE(audio_provider_->endSession().isOk());
2901 }
2902 }
2903 }
2904 }
2905}
2906
Alice Kuo336d90c2022-02-16 09:09:59 +08002907/**
2908 * openProvider LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH
2909 */
2910class BluetoothAudioProviderLeAudioBroadcastHardwareAidl
2911 : public BluetoothAudioProviderFactoryAidl {
2912 public:
2913 virtual void SetUp() override {
2914 BluetoothAudioProviderFactoryAidl::SetUp();
2915 GetProviderCapabilitiesHelper(
2916 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
Bao Doc36897d2023-12-06 01:27:54 +00002917 GetProviderInfoHelper(
2918 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
Alice Kuo336d90c2022-02-16 09:09:59 +08002919 OpenProviderHelper(
2920 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
2921 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
2922 audio_provider_ != nullptr);
2923 }
2924
2925 virtual void TearDown() override {
2926 audio_port_ = nullptr;
2927 audio_provider_ = nullptr;
2928 BluetoothAudioProviderFactoryAidl::TearDown();
2929 }
2930
2931 bool IsBroadcastOffloadSupported() {
2932 for (auto& capability : temp_provider_capabilities_) {
2933 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2934 continue;
2935 }
2936 auto& le_audio_capability =
2937 capability.get<AudioCapabilities::leAudioCapabilities>();
2938 if (le_audio_capability.broadcastCapability.codecType !=
2939 CodecType::UNKNOWN)
2940 return true;
2941 }
2942 return false;
2943 }
2944
Bao Doc36897d2023-12-06 01:27:54 +00002945 bool IsBroadcastOffloadProviderInfoSupported() {
2946 if (!temp_provider_info_.has_value()) return false;
2947 if (temp_provider_info_.value().codecInfos.empty()) return false;
2948 // Check if all codec info is of LeAudio type
2949 for (auto& codec_info : temp_provider_info_.value().codecInfos) {
2950 if (codec_info.transport.getTag() != CodecInfo::Transport::leAudio)
2951 return false;
2952 }
2953 return true;
2954 }
2955
2956 std::vector<Lc3Configuration> GetBroadcastLc3SupportedListFromProviderInfo() {
2957 std::vector<Lc3Configuration> le_audio_codec_configs;
2958 for (auto& codec_info : temp_provider_info_.value().codecInfos) {
2959 // Only gets LC3 codec information
2960 if (codec_info.id != CodecId::Core::LC3) continue;
2961 // Combine those parameters into one list of Lc3Configuration
2962 auto& transport =
2963 codec_info.transport.get<CodecInfo::Transport::Tag::leAudio>();
2964 for (int32_t samplingFrequencyHz : transport.samplingFrequencyHz) {
2965 for (int32_t frameDurationUs : transport.frameDurationUs) {
2966 for (int32_t octetsPerFrame : transport.bitdepth) {
2967 Lc3Configuration lc3_config = {
2968 .samplingFrequencyHz = samplingFrequencyHz,
2969 .frameDurationUs = frameDurationUs,
2970 .octetsPerFrame = octetsPerFrame,
2971 };
2972 le_audio_codec_configs.push_back(lc3_config);
2973 }
2974 }
2975 }
2976 }
2977
2978 return le_audio_codec_configs;
2979 }
2980
Alice Kuo336d90c2022-02-16 09:09:59 +08002981 std::vector<Lc3Configuration> GetBroadcastLc3SupportedList(bool supported) {
2982 std::vector<Lc3Configuration> le_audio_codec_configs;
2983 if (!supported) {
shihchienc3ab9f5e2022-09-23 08:18:05 +00002984 Lc3Configuration lc3_config{.pcmBitDepth = 0, .samplingFrequencyHz = 0};
Alice Kuo336d90c2022-02-16 09:09:59 +08002985 le_audio_codec_configs.push_back(lc3_config);
2986 return le_audio_codec_configs;
2987 }
2988
2989 // There might be more than one LeAudioCodecCapabilitiesSetting
2990 std::vector<Lc3Capabilities> lc3_capabilities;
2991 for (auto& capability : temp_provider_capabilities_) {
2992 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2993 continue;
2994 }
2995 auto& le_audio_capability =
2996 capability.get<AudioCapabilities::leAudioCapabilities>();
2997 auto& broadcast_capability = le_audio_capability.broadcastCapability;
2998 if (broadcast_capability.codecType != CodecType::LC3) {
2999 continue;
3000 }
3001 auto& lc3_capability = broadcast_capability.leAudioCodecCapabilities.get<
3002 BroadcastCapability::LeAudioCodecCapabilities::lc3Capabilities>();
3003 for (int idx = 0; idx < lc3_capability->size(); idx++)
3004 lc3_capabilities.push_back(*lc3_capability->at(idx));
3005 }
3006
3007 // Combine those parameters into one list of LeAudioCodecConfiguration
3008 // This seems horrible, but usually each Lc3Capability only contains a
3009 // single Lc3Configuration, which means every array has a length of 1.
3010 for (auto& lc3_capability : lc3_capabilities) {
3011 for (int32_t samplingFrequencyHz : lc3_capability.samplingFrequencyHz) {
3012 for (int32_t frameDurationUs : lc3_capability.frameDurationUs) {
3013 for (int32_t octetsPerFrame : lc3_capability.octetsPerFrame) {
3014 Lc3Configuration lc3_config = {
3015 .samplingFrequencyHz = samplingFrequencyHz,
3016 .frameDurationUs = frameDurationUs,
3017 .octetsPerFrame = octetsPerFrame,
3018 };
3019 le_audio_codec_configs.push_back(lc3_config);
3020 }
3021 }
3022 }
3023 }
3024
3025 return le_audio_codec_configs;
3026 }
3027
3028 LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
3029};
3030
3031/**
3032 * Test whether each provider of type
3033 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
3034 * started and stopped
3035 */
3036TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3037 OpenLeAudioOutputHardwareProvider) {}
3038
3039/**
3040 * Test whether each provider of type
3041 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
Bao Doc36897d2023-12-06 01:27:54 +00003042 * started and stopped with broadcast hardware encoding config taken from
3043 * provider info
3044 */
3045TEST_P(
3046 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3047 StartAndEndLeAudioBroadcastSessionWithPossibleUnicastConfigFromProviderInfo) {
3048 if (!IsBroadcastOffloadProviderInfoSupported()) {
3049 return;
3050 }
3051
3052 auto lc3_codec_configs = GetBroadcastLc3SupportedListFromProviderInfo();
3053 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
3054 .codecType = CodecType::LC3,
3055 .streamMap = {},
3056 };
3057
3058 for (auto& lc3_config : lc3_codec_configs) {
3059 le_audio_broadcast_config.streamMap.resize(1);
3060 le_audio_broadcast_config.streamMap[0]
3061 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
3062 lc3_config);
3063 le_audio_broadcast_config.streamMap[0].streamHandle = 0x0;
3064 le_audio_broadcast_config.streamMap[0].pcmStreamId = 0x0;
3065 le_audio_broadcast_config.streamMap[0].audioChannelAllocation = 0x1 << 0;
3066
3067 DataMQDesc mq_desc;
3068 auto aidl_retval = audio_provider_->startSession(
3069 audio_port_, AudioConfiguration(le_audio_broadcast_config),
3070 latency_modes, &mq_desc);
3071
3072 ASSERT_TRUE(aidl_retval.isOk());
3073 EXPECT_TRUE(audio_provider_->endSession().isOk());
3074 }
3075}
3076
Bao Do5b2fdab2023-11-20 08:02:55 +00003077TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3078 GetEmptyBroadcastConfigurationEmptyCapability) {
3079 std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
3080 IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement
3081 empty_requirement;
3082
3083 IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting* configuration =
3084 new IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting();
3085
3086 // Check empty capability for source direction
3087 auto aidl_retval = audio_provider_->getLeAudioBroadcastConfiguration(
3088 empty_capability, empty_requirement, configuration);
3089
3090 ASSERT_TRUE(aidl_retval.isOk());
3091}
3092
Bao Doc36897d2023-12-06 01:27:54 +00003093/**
3094 * Test whether each provider of type
3095 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
Alice Kuo336d90c2022-02-16 09:09:59 +08003096 * started and stopped with broadcast hardware encoding config
3097 */
3098TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3099 StartAndEndLeAudioBroadcastSessionWithPossibleBroadcastConfig) {
3100 if (!IsBroadcastOffloadSupported()) {
3101 return;
3102 }
3103
3104 auto lc3_codec_configs = GetBroadcastLc3SupportedList(true /* supported */);
3105 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
3106 .codecType = CodecType::LC3,
3107 .streamMap = {},
3108 };
3109
3110 for (auto& lc3_config : lc3_codec_configs) {
Patty Huangac077ef2022-11-23 14:45:15 +08003111 le_audio_broadcast_config.streamMap.resize(1);
Alice Kuo336d90c2022-02-16 09:09:59 +08003112 le_audio_broadcast_config.streamMap[0]
3113 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
3114 lc3_config);
Rongxuan Liuc1aea322023-01-26 17:14:54 +00003115 le_audio_broadcast_config.streamMap[0].streamHandle = 0x0;
3116 le_audio_broadcast_config.streamMap[0].pcmStreamId = 0x0;
3117 le_audio_broadcast_config.streamMap[0].audioChannelAllocation = 0x1 << 0;
3118
Alice Kuo336d90c2022-02-16 09:09:59 +08003119 DataMQDesc mq_desc;
3120 auto aidl_retval = audio_provider_->startSession(
Chen Chen60d52e42022-02-16 12:19:12 -08003121 audio_port_, AudioConfiguration(le_audio_broadcast_config),
3122 latency_modes, &mq_desc);
Alice Kuo336d90c2022-02-16 09:09:59 +08003123
3124 ASSERT_TRUE(aidl_retval.isOk());
3125 EXPECT_TRUE(audio_provider_->endSession().isOk());
3126 }
3127}
3128
3129/**
3130 * Test whether each provider of type
3131 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
3132 * started and stopped with Broadcast hardware encoding config
3133 *
3134 * Disabled since offload codec checking is not ready
3135 */
3136TEST_P(
3137 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3138 DISABLED_StartAndEndLeAudioBroadcastSessionWithInvalidAudioConfiguration) {
3139 if (!IsBroadcastOffloadSupported()) {
3140 return;
3141 }
3142
3143 auto lc3_codec_configs = GetBroadcastLc3SupportedList(false /* supported */);
3144 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
3145 .codecType = CodecType::LC3,
3146 .streamMap = {},
3147 };
3148
3149 for (auto& lc3_config : lc3_codec_configs) {
3150 le_audio_broadcast_config.streamMap[0]
3151 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
3152 lc3_config);
3153 DataMQDesc mq_desc;
3154 auto aidl_retval = audio_provider_->startSession(
Chen Chen60d52e42022-02-16 12:19:12 -08003155 audio_port_, AudioConfiguration(le_audio_broadcast_config),
3156 latency_modes, &mq_desc);
Alice Kuo336d90c2022-02-16 09:09:59 +08003157
3158 // AIDL call should fail on invalid codec
3159 ASSERT_FALSE(aidl_retval.isOk());
3160 EXPECT_TRUE(audio_provider_->endSession().isOk());
3161 }
3162}
3163
Alice Kuoadcceec2022-03-28 13:28:43 +08003164/**
3165 * openProvider A2DP_SOFTWARE_DECODING_DATAPATH
3166 */
3167class BluetoothAudioProviderA2dpDecodingSoftwareAidl
3168 : public BluetoothAudioProviderFactoryAidl {
3169 public:
3170 virtual void SetUp() override {
3171 BluetoothAudioProviderFactoryAidl::SetUp();
3172 GetProviderCapabilitiesHelper(SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
3173 OpenProviderHelper(SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
3174 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
3175 audio_provider_ != nullptr);
3176 }
3177
3178 virtual void TearDown() override {
3179 audio_port_ = nullptr;
3180 audio_provider_ = nullptr;
3181 BluetoothAudioProviderFactoryAidl::TearDown();
3182 }
3183};
3184
3185/**
3186 * Test whether we can open a provider of type
3187 */
3188TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,
3189 OpenA2dpDecodingSoftwareProvider) {}
3190
3191/**
3192 * Test whether each provider of type
3193 * SessionType::A2DP_SOFTWARE_DECODING_DATAPATH can be started and stopped with
3194 * different PCM config
3195 */
3196TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,
3197 StartAndEndA2dpDecodingSoftwareSessionWithPossiblePcmConfig) {
3198 for (auto sample_rate : a2dp_sample_rates) {
3199 for (auto bits_per_sample : a2dp_bits_per_samples) {
3200 for (auto channel_mode : a2dp_channel_modes) {
3201 PcmConfiguration pcm_config{
3202 .sampleRateHz = sample_rate,
Alice Kuoadcceec2022-03-28 13:28:43 +08003203 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00003204 .bitsPerSample = bits_per_sample,
Alice Kuoadcceec2022-03-28 13:28:43 +08003205 };
3206 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
3207 DataMQDesc mq_desc;
3208 auto aidl_retval = audio_provider_->startSession(
3209 audio_port_, AudioConfiguration(pcm_config), latency_modes,
3210 &mq_desc);
3211 DataMQ data_mq(mq_desc);
3212
3213 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
3214 if (is_codec_config_valid) {
3215 EXPECT_TRUE(data_mq.isValid());
3216 }
3217 EXPECT_TRUE(audio_provider_->endSession().isOk());
3218 }
3219 }
3220 }
3221}
3222
3223/**
3224 * openProvider A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH
3225 */
3226class BluetoothAudioProviderA2dpDecodingHardwareAidl
3227 : public BluetoothAudioProviderFactoryAidl {
3228 public:
3229 virtual void SetUp() override {
3230 BluetoothAudioProviderFactoryAidl::SetUp();
3231 GetProviderCapabilitiesHelper(
3232 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
3233 OpenProviderHelper(SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
3234 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
3235 audio_provider_ != nullptr);
3236 }
3237
3238 virtual void TearDown() override {
3239 audio_port_ = nullptr;
3240 audio_provider_ = nullptr;
3241 BluetoothAudioProviderFactoryAidl::TearDown();
3242 }
3243
3244 bool IsOffloadSupported() { return (temp_provider_capabilities_.size() > 0); }
3245};
3246
3247/**
3248 * Test whether we can open a provider of type
3249 */
3250TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3251 OpenA2dpDecodingHardwareProvider) {}
3252
3253/**
3254 * Test whether each provider of type
3255 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
3256 * SBC hardware encoding config
3257 */
3258TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3259 StartAndEndA2dpSbcDecodingHardwareSession) {
3260 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003261 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08003262 }
3263
3264 CodecConfiguration codec_config = {
3265 .codecType = CodecType::SBC,
3266 .encodedAudioBitrate = 328000,
3267 .peerMtu = 1005,
3268 .isScmstEnabled = false,
3269 };
3270 auto sbc_codec_specifics = GetSbcCodecSpecificSupportedList(true);
3271
3272 for (auto& codec_specific : sbc_codec_specifics) {
3273 copy_codec_specific(codec_config.config, codec_specific);
3274 DataMQDesc mq_desc;
3275 auto aidl_retval = audio_provider_->startSession(
3276 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
3277
3278 ASSERT_TRUE(aidl_retval.isOk());
3279 EXPECT_TRUE(audio_provider_->endSession().isOk());
3280 }
3281}
3282
3283/**
3284 * Test whether each provider of type
3285 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
3286 * AAC hardware encoding config
3287 */
3288TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3289 StartAndEndA2dpAacDecodingHardwareSession) {
3290 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003291 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08003292 }
3293
3294 CodecConfiguration codec_config = {
3295 .codecType = CodecType::AAC,
3296 .encodedAudioBitrate = 320000,
3297 .peerMtu = 1005,
3298 .isScmstEnabled = false,
3299 };
3300 auto aac_codec_specifics = GetAacCodecSpecificSupportedList(true);
3301
3302 for (auto& codec_specific : aac_codec_specifics) {
3303 copy_codec_specific(codec_config.config, codec_specific);
3304 DataMQDesc mq_desc;
3305 auto aidl_retval = audio_provider_->startSession(
3306 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
3307
3308 ASSERT_TRUE(aidl_retval.isOk());
3309 EXPECT_TRUE(audio_provider_->endSession().isOk());
3310 }
3311}
3312
3313/**
3314 * Test whether each provider of type
3315 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
3316 * LDAC hardware encoding config
3317 */
3318TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3319 StartAndEndA2dpLdacDecodingHardwareSession) {
3320 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003321 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08003322 }
3323
3324 CodecConfiguration codec_config = {
3325 .codecType = CodecType::LDAC,
3326 .encodedAudioBitrate = 990000,
3327 .peerMtu = 1005,
3328 .isScmstEnabled = false,
3329 };
3330 auto ldac_codec_specifics = GetLdacCodecSpecificSupportedList(true);
3331
3332 for (auto& codec_specific : ldac_codec_specifics) {
3333 copy_codec_specific(codec_config.config, codec_specific);
3334 DataMQDesc mq_desc;
3335 auto aidl_retval = audio_provider_->startSession(
3336 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
3337
3338 ASSERT_TRUE(aidl_retval.isOk());
3339 EXPECT_TRUE(audio_provider_->endSession().isOk());
3340 }
3341}
3342
3343/**
3344 * Test whether each provider of type
3345 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
Omer Osmana2587da2022-05-01 03:54:11 +00003346 * Opus hardware encoding config
Alice Kuoadcceec2022-03-28 13:28:43 +08003347 */
3348TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
Omer Osmana2587da2022-05-01 03:54:11 +00003349 StartAndEndA2dpOpusDecodingHardwareSession) {
Alice Kuoadcceec2022-03-28 13:28:43 +08003350 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003351 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08003352 }
3353
3354 CodecConfiguration codec_config = {
Omer Osmana2587da2022-05-01 03:54:11 +00003355 .codecType = CodecType::OPUS,
Alice Kuoadcceec2022-03-28 13:28:43 +08003356 .encodedAudioBitrate = 990000,
3357 .peerMtu = 1005,
3358 .isScmstEnabled = false,
3359 };
Omer Osmana2587da2022-05-01 03:54:11 +00003360 auto opus_codec_specifics = GetOpusCodecSpecificSupportedList(true);
Alice Kuoadcceec2022-03-28 13:28:43 +08003361
Omer Osmana2587da2022-05-01 03:54:11 +00003362 for (auto& codec_specific : opus_codec_specifics) {
Alice Kuoadcceec2022-03-28 13:28:43 +08003363 copy_codec_specific(codec_config.config, codec_specific);
3364 DataMQDesc mq_desc;
3365 auto aidl_retval = audio_provider_->startSession(
3366 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
3367
3368 ASSERT_TRUE(aidl_retval.isOk());
3369 EXPECT_TRUE(audio_provider_->endSession().isOk());
3370 }
3371}
3372
3373/**
3374 * Test whether each provider of type
3375 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
3376 * AptX hardware encoding config
3377 */
3378TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3379 StartAndEndA2dpAptxDecodingHardwareSession) {
3380 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003381 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08003382 }
3383
3384 for (auto codec_type : {CodecType::APTX, CodecType::APTX_HD}) {
3385 CodecConfiguration codec_config = {
3386 .codecType = codec_type,
3387 .encodedAudioBitrate =
3388 (codec_type == CodecType::APTX ? 352000 : 576000),
3389 .peerMtu = 1005,
3390 .isScmstEnabled = false,
3391 };
3392
3393 auto aptx_codec_specifics = GetAptxCodecSpecificSupportedList(
3394 (codec_type == CodecType::APTX_HD ? true : false), true);
3395
3396 for (auto& codec_specific : aptx_codec_specifics) {
3397 copy_codec_specific(codec_config.config, codec_specific);
3398 DataMQDesc mq_desc;
3399 auto aidl_retval = audio_provider_->startSession(
3400 audio_port_, AudioConfiguration(codec_config), latency_modes,
3401 &mq_desc);
3402
3403 ASSERT_TRUE(aidl_retval.isOk());
3404 EXPECT_TRUE(audio_provider_->endSession().isOk());
3405 }
3406 }
3407}
3408
3409/**
3410 * Test whether each provider of type
3411 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
3412 * an invalid codec config
3413 */
3414TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3415 StartAndEndA2dpDecodingHardwareSessionInvalidCodecConfig) {
3416 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003417 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08003418 }
3419 ASSERT_NE(audio_provider_, nullptr);
3420
3421 std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
Sagar Verma62df9102022-12-07 17:56:04 +05303422 for (auto codec_type : ndk::enum_range<CodecType>()) {
Alice Kuoadcceec2022-03-28 13:28:43 +08003423 switch (codec_type) {
3424 case CodecType::SBC:
3425 codec_specifics = GetSbcCodecSpecificSupportedList(false);
3426 break;
3427 case CodecType::AAC:
3428 codec_specifics = GetAacCodecSpecificSupportedList(false);
3429 break;
3430 case CodecType::LDAC:
3431 codec_specifics = GetLdacCodecSpecificSupportedList(false);
3432 break;
3433 case CodecType::APTX:
3434 codec_specifics = GetAptxCodecSpecificSupportedList(false, false);
3435 break;
3436 case CodecType::APTX_HD:
3437 codec_specifics = GetAptxCodecSpecificSupportedList(true, false);
3438 break;
Omer Osmana2587da2022-05-01 03:54:11 +00003439 case CodecType::OPUS:
3440 codec_specifics = GetOpusCodecSpecificSupportedList(false);
Alice Kuoadcceec2022-03-28 13:28:43 +08003441 continue;
3442 case CodecType::APTX_ADAPTIVE:
Sagar Verma62df9102022-12-07 17:56:04 +05303443 case CodecType::APTX_ADAPTIVE_LE:
3444 case CodecType::APTX_ADAPTIVE_LEX:
Omer Osmana2587da2022-05-01 03:54:11 +00003445 case CodecType::LC3:
Alice Kuoadcceec2022-03-28 13:28:43 +08003446 case CodecType::VENDOR:
3447 case CodecType::UNKNOWN:
3448 codec_specifics.clear();
3449 break;
3450 }
3451 if (codec_specifics.empty()) {
3452 continue;
3453 }
3454
3455 CodecConfiguration codec_config = {
3456 .codecType = codec_type,
3457 .encodedAudioBitrate = 328000,
3458 .peerMtu = 1005,
3459 .isScmstEnabled = false,
3460 };
3461 for (auto codec_specific : codec_specifics) {
3462 copy_codec_specific(codec_config.config, codec_specific);
3463 DataMQDesc mq_desc;
3464 auto aidl_retval = audio_provider_->startSession(
3465 audio_port_, AudioConfiguration(codec_config), latency_modes,
3466 &mq_desc);
3467
3468 // AIDL call should fail on invalid codec
3469 ASSERT_FALSE(aidl_retval.isOk());
3470 EXPECT_TRUE(audio_provider_->endSession().isOk());
3471 }
3472 }
3473}
3474
Josh Wu049e2cd2022-01-12 05:42:58 -08003475GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3476 BluetoothAudioProviderFactoryAidl);
3477INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderFactoryAidl,
3478 testing::ValuesIn(android::getAidlHalInstanceNames(
3479 IBluetoothAudioProviderFactory::descriptor)),
3480 android::PrintInstanceNameToString);
3481
Antoine SOULIER33c4e5a2023-09-28 21:59:19 +00003482GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothAudioProviderAidl);
3483INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderAidl,
3484 testing::ValuesIn(android::getAidlHalInstanceNames(
3485 IBluetoothAudioProviderFactory::descriptor)),
3486 android::PrintInstanceNameToString);
3487
Josh Wu049e2cd2022-01-12 05:42:58 -08003488GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
Alice Kuoadcceec2022-03-28 13:28:43 +08003489 BluetoothAudioProviderA2dpEncodingSoftwareAidl);
3490INSTANTIATE_TEST_SUITE_P(PerInstance,
3491 BluetoothAudioProviderA2dpEncodingSoftwareAidl,
Josh Wu049e2cd2022-01-12 05:42:58 -08003492 testing::ValuesIn(android::getAidlHalInstanceNames(
3493 IBluetoothAudioProviderFactory::descriptor)),
3494 android::PrintInstanceNameToString);
3495
3496GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
Alice Kuoadcceec2022-03-28 13:28:43 +08003497 BluetoothAudioProviderA2dpEncodingHardwareAidl);
3498INSTANTIATE_TEST_SUITE_P(PerInstance,
3499 BluetoothAudioProviderA2dpEncodingHardwareAidl,
Josh Wu049e2cd2022-01-12 05:42:58 -08003500 testing::ValuesIn(android::getAidlHalInstanceNames(
3501 IBluetoothAudioProviderFactory::descriptor)),
3502 android::PrintInstanceNameToString);
3503
3504GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3505 BluetoothAudioProviderHearingAidSoftwareAidl);
3506INSTANTIATE_TEST_SUITE_P(PerInstance,
3507 BluetoothAudioProviderHearingAidSoftwareAidl,
3508 testing::ValuesIn(android::getAidlHalInstanceNames(
3509 IBluetoothAudioProviderFactory::descriptor)),
3510 android::PrintInstanceNameToString);
3511
3512GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3513 BluetoothAudioProviderLeAudioOutputSoftwareAidl);
3514INSTANTIATE_TEST_SUITE_P(PerInstance,
3515 BluetoothAudioProviderLeAudioOutputSoftwareAidl,
3516 testing::ValuesIn(android::getAidlHalInstanceNames(
3517 IBluetoothAudioProviderFactory::descriptor)),
3518 android::PrintInstanceNameToString);
3519
3520GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3521 BluetoothAudioProviderLeAudioInputSoftwareAidl);
3522INSTANTIATE_TEST_SUITE_P(PerInstance,
3523 BluetoothAudioProviderLeAudioInputSoftwareAidl,
3524 testing::ValuesIn(android::getAidlHalInstanceNames(
3525 IBluetoothAudioProviderFactory::descriptor)),
3526 android::PrintInstanceNameToString);
3527
3528GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3529 BluetoothAudioProviderLeAudioOutputHardwareAidl);
3530INSTANTIATE_TEST_SUITE_P(PerInstance,
3531 BluetoothAudioProviderLeAudioOutputHardwareAidl,
3532 testing::ValuesIn(android::getAidlHalInstanceNames(
3533 IBluetoothAudioProviderFactory::descriptor)),
3534 android::PrintInstanceNameToString);
3535
3536GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3537 BluetoothAudioProviderLeAudioInputHardwareAidl);
3538INSTANTIATE_TEST_SUITE_P(PerInstance,
3539 BluetoothAudioProviderLeAudioInputHardwareAidl,
3540 testing::ValuesIn(android::getAidlHalInstanceNames(
3541 IBluetoothAudioProviderFactory::descriptor)),
3542 android::PrintInstanceNameToString);
3543
3544GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3545 BluetoothAudioProviderLeAudioBroadcastSoftwareAidl);
3546INSTANTIATE_TEST_SUITE_P(PerInstance,
3547 BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
3548 testing::ValuesIn(android::getAidlHalInstanceNames(
3549 IBluetoothAudioProviderFactory::descriptor)),
3550 android::PrintInstanceNameToString);
3551
Alice Kuo336d90c2022-02-16 09:09:59 +08003552GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3553 BluetoothAudioProviderLeAudioBroadcastHardwareAidl);
3554INSTANTIATE_TEST_SUITE_P(PerInstance,
3555 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3556 testing::ValuesIn(android::getAidlHalInstanceNames(
3557 IBluetoothAudioProviderFactory::descriptor)),
3558 android::PrintInstanceNameToString);
Josh Wu049e2cd2022-01-12 05:42:58 -08003559
Alice Kuoadcceec2022-03-28 13:28:43 +08003560GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3561 BluetoothAudioProviderA2dpDecodingSoftwareAidl);
3562INSTANTIATE_TEST_SUITE_P(PerInstance,
3563 BluetoothAudioProviderA2dpDecodingSoftwareAidl,
3564 testing::ValuesIn(android::getAidlHalInstanceNames(
3565 IBluetoothAudioProviderFactory::descriptor)),
3566 android::PrintInstanceNameToString);
3567
3568GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3569 BluetoothAudioProviderA2dpDecodingHardwareAidl);
3570INSTANTIATE_TEST_SUITE_P(PerInstance,
3571 BluetoothAudioProviderA2dpDecodingHardwareAidl,
3572 testing::ValuesIn(android::getAidlHalInstanceNames(
3573 IBluetoothAudioProviderFactory::descriptor)),
3574 android::PrintInstanceNameToString);
3575
Bao Do72399432023-11-09 08:13:05 +00003576GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3577 BluetoothAudioProviderHfpHardwareAidl);
3578INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderHfpHardwareAidl,
3579 testing::ValuesIn(android::getAidlHalInstanceNames(
3580 IBluetoothAudioProviderFactory::descriptor)),
3581 android::PrintInstanceNameToString);
3582
3583GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3584 BluetoothAudioProviderHfpSoftwareDecodingAidl);
3585INSTANTIATE_TEST_SUITE_P(PerInstance,
3586 BluetoothAudioProviderHfpSoftwareDecodingAidl,
3587 testing::ValuesIn(android::getAidlHalInstanceNames(
3588 IBluetoothAudioProviderFactory::descriptor)),
3589 android::PrintInstanceNameToString);
3590
3591GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3592 BluetoothAudioProviderHfpSoftwareEncodingAidl);
3593INSTANTIATE_TEST_SUITE_P(PerInstance,
3594 BluetoothAudioProviderHfpSoftwareEncodingAidl,
3595 testing::ValuesIn(android::getAidlHalInstanceNames(
3596 IBluetoothAudioProviderFactory::descriptor)),
3597 android::PrintInstanceNameToString);
3598
Josh Wu049e2cd2022-01-12 05:42:58 -08003599int main(int argc, char** argv) {
3600 ::testing::InitGoogleTest(&argc, argv);
3601 ABinderProcess_setThreadPoolMaxThreadCount(1);
3602 ABinderProcess_startThreadPool();
3603 return RUN_ALL_TESTS();
3604}