blob: c313fb7d0c13e3af716681211e22ec2c9941f1bb [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
Bao Dob487a852023-12-25 10:12:09 +0800123enum class BluetoothAudioHalVersion : int32_t {
124 VERSION_UNAVAILABLE = 0,
125 VERSION_2_0,
126 VERSION_2_1,
127 VERSION_AIDL_V1,
128 VERSION_AIDL_V2,
129 VERSION_AIDL_V3,
130 VERSION_AIDL_V4,
131};
132
Bao Do72399432023-11-09 08:13:05 +0000133// Some valid configs for HFP PCM configuration (software sessions)
134static constexpr int32_t hfp_sample_rates_[] = {8000, 16000, 32000};
135static constexpr int8_t hfp_bits_per_samples_[] = {16};
136static constexpr ChannelMode hfp_channel_modes_[] = {ChannelMode::MONO};
137static constexpr int32_t hfp_data_interval_us_[] = {7500};
138
Josh Wu049e2cd2022-01-12 05:42:58 -0800139// Helpers
140
141template <typename T>
142struct identity {
143 typedef T type;
144};
145
146template <class T>
147bool contained_in_vector(const std::vector<T>& vector,
148 const typename identity<T>::type& target) {
149 return std::find(vector.begin(), vector.end(), target) != vector.end();
150}
151
152void copy_codec_specific(CodecConfiguration::CodecSpecific& dst,
153 const CodecConfiguration::CodecSpecific& src) {
154 switch (src.getTag()) {
155 case CodecConfiguration::CodecSpecific::sbcConfig:
156 dst.set<CodecConfiguration::CodecSpecific::sbcConfig>(
157 src.get<CodecConfiguration::CodecSpecific::sbcConfig>());
158 break;
159 case CodecConfiguration::CodecSpecific::aacConfig:
160 dst.set<CodecConfiguration::CodecSpecific::aacConfig>(
161 src.get<CodecConfiguration::CodecSpecific::aacConfig>());
162 break;
163 case CodecConfiguration::CodecSpecific::ldacConfig:
164 dst.set<CodecConfiguration::CodecSpecific::ldacConfig>(
165 src.get<CodecConfiguration::CodecSpecific::ldacConfig>());
166 break;
167 case CodecConfiguration::CodecSpecific::aptxConfig:
168 dst.set<CodecConfiguration::CodecSpecific::aptxConfig>(
169 src.get<CodecConfiguration::CodecSpecific::aptxConfig>());
170 break;
Omer Osmana2587da2022-05-01 03:54:11 +0000171 case CodecConfiguration::CodecSpecific::opusConfig:
172 dst.set<CodecConfiguration::CodecSpecific::opusConfig>(
173 src.get<CodecConfiguration::CodecSpecific::opusConfig>());
Josh Wu049e2cd2022-01-12 05:42:58 -0800174 break;
175 case CodecConfiguration::CodecSpecific::aptxAdaptiveConfig:
176 dst.set<CodecConfiguration::CodecSpecific::aptxAdaptiveConfig>(
177 src.get<CodecConfiguration::CodecSpecific::aptxAdaptiveConfig>());
178 break;
179 default:
180 break;
181 }
182}
183
184class BluetoothAudioPort : public BnBluetoothAudioPort {
185 public:
186 BluetoothAudioPort() {}
187
Chen Chen0a68a922022-02-15 18:43:26 -0800188 ndk::ScopedAStatus startStream(bool) { return ScopedAStatus::ok(); }
Josh Wu049e2cd2022-01-12 05:42:58 -0800189
190 ndk::ScopedAStatus suspendStream() { return ScopedAStatus::ok(); }
191
192 ndk::ScopedAStatus stopStream() { return ScopedAStatus::ok(); }
193
194 ndk::ScopedAStatus getPresentationPosition(PresentationPosition*) {
195 return ScopedAStatus::ok();
196 }
197
198 ndk::ScopedAStatus updateSourceMetadata(const SourceMetadata&) {
199 return ScopedAStatus::ok();
200 }
201
202 ndk::ScopedAStatus updateSinkMetadata(const SinkMetadata&) {
203 return ScopedAStatus::ok();
204 }
205
206 ndk::ScopedAStatus setLatencyMode(const LatencyMode) {
207 return ScopedAStatus::ok();
208 }
209
210 ndk::ScopedAStatus setCodecType(const CodecType) {
211 return ScopedAStatus::ok();
212 }
213
214 protected:
215 virtual ~BluetoothAudioPort() = default;
216};
217
218class BluetoothAudioProviderFactoryAidl
219 : public testing::TestWithParam<std::string> {
220 public:
221 virtual void SetUp() override {
222 provider_factory_ = IBluetoothAudioProviderFactory::fromBinder(
223 SpAIBinder(AServiceManager_getService(GetParam().c_str())));
224 audio_provider_ = nullptr;
225 ASSERT_NE(provider_factory_, nullptr);
226 }
227
228 virtual void TearDown() override { provider_factory_ = nullptr; }
229
Bao Doc36897d2023-12-06 01:27:54 +0000230 void GetProviderInfoHelper(const SessionType& session_type) {
231 temp_provider_info_ = std::nullopt;
232 auto aidl_reval =
233 provider_factory_->getProviderInfo(session_type, &temp_provider_info_);
Bao Doc36897d2023-12-06 01:27:54 +0000234 }
235
Josh Wu049e2cd2022-01-12 05:42:58 -0800236 void GetProviderCapabilitiesHelper(const SessionType& session_type) {
237 temp_provider_capabilities_.clear();
238 auto aidl_retval = provider_factory_->getProviderCapabilities(
239 session_type, &temp_provider_capabilities_);
240 // AIDL calls should not be failed and callback has to be executed
241 ASSERT_TRUE(aidl_retval.isOk());
242 switch (session_type) {
243 case SessionType::UNKNOWN: {
244 ASSERT_TRUE(temp_provider_capabilities_.empty());
245 } break;
246 case SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH:
247 case SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH:
248 case SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH:
249 case SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH:
Bao Do72399432023-11-09 08:13:05 +0000250 case SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH:
251 case SessionType::HFP_SOFTWARE_ENCODING_DATAPATH: {
Josh Wu049e2cd2022-01-12 05:42:58 -0800252 // All software paths are mandatory and must have exact 1
253 // "PcmParameters"
254 ASSERT_EQ(temp_provider_capabilities_.size(), 1);
255 ASSERT_EQ(temp_provider_capabilities_[0].getTag(),
256 AudioCapabilities::pcmCapabilities);
257 } break;
Alice Kuoadcceec2022-03-28 13:28:43 +0800258 case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
259 case SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH: {
Josh Wu049e2cd2022-01-12 05:42:58 -0800260 std::unordered_set<CodecType> codec_types;
261 // empty capability means offload is unsupported
262 for (auto& audio_capability : temp_provider_capabilities_) {
263 ASSERT_EQ(audio_capability.getTag(),
264 AudioCapabilities::a2dpCapabilities);
265 const auto& codec_capabilities =
266 audio_capability.get<AudioCapabilities::a2dpCapabilities>();
267 // Every codec can present once at most
268 ASSERT_EQ(codec_types.count(codec_capabilities.codecType), 0);
269 switch (codec_capabilities.codecType) {
270 case CodecType::SBC:
271 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
272 CodecCapabilities::Capabilities::sbcCapabilities);
273 break;
274 case CodecType::AAC:
275 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
276 CodecCapabilities::Capabilities::aacCapabilities);
277 break;
278 case CodecType::APTX:
279 case CodecType::APTX_HD:
280 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
281 CodecCapabilities::Capabilities::aptxCapabilities);
282 break;
283 case CodecType::LDAC:
284 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
285 CodecCapabilities::Capabilities::ldacCapabilities);
286 break;
Omer Osmana2587da2022-05-01 03:54:11 +0000287 case CodecType::OPUS:
Josh Wu049e2cd2022-01-12 05:42:58 -0800288 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
Omer Osmana2587da2022-05-01 03:54:11 +0000289 CodecCapabilities::Capabilities::opusCapabilities);
Josh Wu049e2cd2022-01-12 05:42:58 -0800290 break;
291 case CodecType::APTX_ADAPTIVE:
Sagar Verma62df9102022-12-07 17:56:04 +0530292 case CodecType::APTX_ADAPTIVE_LE:
293 case CodecType::APTX_ADAPTIVE_LEX:
Omer Osmana2587da2022-05-01 03:54:11 +0000294 case CodecType::LC3:
Josh Wu049e2cd2022-01-12 05:42:58 -0800295 case CodecType::VENDOR:
296 case CodecType::UNKNOWN:
297 break;
298 }
299 codec_types.insert(codec_capabilities.codecType);
300 }
301 } break;
302 case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
303 case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
304 case SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH: {
shihchienc3ab9f5e2022-09-23 08:18:05 +0000305 // empty capability means offload is unsupported since capabilities are
306 // not hardcoded
Josh Wu049e2cd2022-01-12 05:42:58 -0800307 for (auto audio_capability : temp_provider_capabilities_) {
308 ASSERT_EQ(audio_capability.getTag(),
309 AudioCapabilities::leAudioCapabilities);
310 }
311 } break;
Bao Do72399432023-11-09 08:13:05 +0000312 case SessionType::A2DP_SOFTWARE_DECODING_DATAPATH:
313 case SessionType::HFP_SOFTWARE_DECODING_DATAPATH: {
Alice Kuoadcceec2022-03-28 13:28:43 +0800314 if (!temp_provider_capabilities_.empty()) {
315 ASSERT_EQ(temp_provider_capabilities_.size(), 1);
316 ASSERT_EQ(temp_provider_capabilities_[0].getTag(),
317 AudioCapabilities::pcmCapabilities);
318 }
319 } break;
320 default: {
321 ASSERT_TRUE(temp_provider_capabilities_.empty());
322 }
Josh Wu049e2cd2022-01-12 05:42:58 -0800323 }
324 }
325
326 /***
327 * This helps to open the specified provider and check the openProvider()
328 * has corruct return values. BUT, to keep it simple, it does not consider
329 * the capability, and please do so at the SetUp of each session's test.
330 ***/
331 void OpenProviderHelper(const SessionType& session_type) {
332 auto aidl_retval =
333 provider_factory_->openProvider(session_type, &audio_provider_);
334 if (aidl_retval.isOk()) {
335 ASSERT_NE(session_type, SessionType::UNKNOWN);
336 ASSERT_NE(audio_provider_, nullptr);
337 audio_port_ = ndk::SharedRefBase::make<BluetoothAudioPort>();
338 } else {
Alice Kuoadcceec2022-03-28 13:28:43 +0800339 // optional session type
Josh Wu049e2cd2022-01-12 05:42:58 -0800340 ASSERT_TRUE(
341 session_type == SessionType::UNKNOWN ||
342 session_type ==
343 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
344 session_type ==
345 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
346 session_type ==
347 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
348 session_type ==
349 SessionType::
Alice Kuoadcceec2022-03-28 13:28:43 +0800350 LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
351 session_type ==
352 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
Bao Do72399432023-11-09 08:13:05 +0000353 session_type == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH ||
354 session_type == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH ||
355 session_type == SessionType::HFP_SOFTWARE_DECODING_DATAPATH ||
356 session_type == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH);
Josh Wu049e2cd2022-01-12 05:42:58 -0800357 ASSERT_EQ(audio_provider_, nullptr);
358 }
359 }
360
Josh Wu049e2cd2022-01-12 05:42:58 -0800361 void GetA2dpOffloadCapabilityHelper(const CodecType& codec_type) {
362 temp_codec_capabilities_ = nullptr;
Josh Wu4d2938f2022-02-15 09:21:10 -0800363 for (auto& codec_capability : temp_provider_capabilities_) {
Josh Wu049e2cd2022-01-12 05:42:58 -0800364 auto& a2dp_capabilities =
365 codec_capability.get<AudioCapabilities::a2dpCapabilities>();
366 if (a2dp_capabilities.codecType != codec_type) {
367 continue;
368 }
369 temp_codec_capabilities_ = &a2dp_capabilities;
370 }
371 }
372
373 std::vector<CodecConfiguration::CodecSpecific>
374 GetSbcCodecSpecificSupportedList(bool supported) {
375 std::vector<CodecConfiguration::CodecSpecific> sbc_codec_specifics;
376 if (!supported) {
377 SbcConfiguration sbc_config{.sampleRateHz = 0, .bitsPerSample = 0};
378 sbc_codec_specifics.push_back(
379 CodecConfiguration::CodecSpecific(sbc_config));
380 return sbc_codec_specifics;
381 }
382 GetA2dpOffloadCapabilityHelper(CodecType::SBC);
383 if (temp_codec_capabilities_ == nullptr ||
384 temp_codec_capabilities_->codecType != CodecType::SBC) {
385 return sbc_codec_specifics;
386 }
387 // parse the capability
388 auto& sbc_capability =
389 temp_codec_capabilities_->capabilities
390 .get<CodecCapabilities::Capabilities::sbcCapabilities>();
391 if (sbc_capability.minBitpool > sbc_capability.maxBitpool) {
392 return sbc_codec_specifics;
393 }
394
395 // combine those parameters into one list of
396 // CodecConfiguration::CodecSpecific
397 for (int32_t sample_rate : sbc_capability.sampleRateHz) {
398 for (int8_t block_length : sbc_capability.blockLength) {
399 for (int8_t num_subbands : sbc_capability.numSubbands) {
400 for (int8_t bits_per_sample : sbc_capability.bitsPerSample) {
401 for (auto channel_mode : sbc_capability.channelMode) {
402 for (auto alloc_method : sbc_capability.allocMethod) {
403 SbcConfiguration sbc_data = {
404 .sampleRateHz = sample_rate,
405 .channelMode = channel_mode,
406 .blockLength = block_length,
407 .numSubbands = num_subbands,
408 .allocMethod = alloc_method,
409 .bitsPerSample = bits_per_sample,
410 .minBitpool = sbc_capability.minBitpool,
411 .maxBitpool = sbc_capability.maxBitpool};
412 sbc_codec_specifics.push_back(
413 CodecConfiguration::CodecSpecific(sbc_data));
414 }
415 }
416 }
417 }
418 }
419 }
420 return sbc_codec_specifics;
421 }
422
423 std::vector<CodecConfiguration::CodecSpecific>
424 GetAacCodecSpecificSupportedList(bool supported) {
425 std::vector<CodecConfiguration::CodecSpecific> aac_codec_specifics;
426 if (!supported) {
427 AacConfiguration aac_config{.sampleRateHz = 0, .bitsPerSample = 0};
428 aac_codec_specifics.push_back(
429 CodecConfiguration::CodecSpecific(aac_config));
430 return aac_codec_specifics;
431 }
432 GetA2dpOffloadCapabilityHelper(CodecType::AAC);
433 if (temp_codec_capabilities_ == nullptr ||
434 temp_codec_capabilities_->codecType != CodecType::AAC) {
435 return aac_codec_specifics;
436 }
437 // parse the capability
438 auto& aac_capability =
439 temp_codec_capabilities_->capabilities
440 .get<CodecCapabilities::Capabilities::aacCapabilities>();
441
442 std::vector<bool> variable_bit_rate_enableds = {false};
443 if (aac_capability.variableBitRateSupported) {
444 variable_bit_rate_enableds.push_back(true);
445 }
446
Sagar Verma62df9102022-12-07 17:56:04 +0530447 std::vector<bool> adaptive_bit_rate_supporteds = {false};
448 if (aac_capability.adaptiveBitRateSupported) {
449 adaptive_bit_rate_supporteds.push_back(true);
450 }
451
Josh Wu049e2cd2022-01-12 05:42:58 -0800452 // combine those parameters into one list of
453 // CodecConfiguration::CodecSpecific
454 for (auto object_type : aac_capability.objectType) {
455 for (int32_t sample_rate : aac_capability.sampleRateHz) {
456 for (auto channel_mode : aac_capability.channelMode) {
457 for (int8_t bits_per_sample : aac_capability.bitsPerSample) {
458 for (auto variable_bit_rate_enabled : variable_bit_rate_enableds) {
Sagar Verma62df9102022-12-07 17:56:04 +0530459 for (auto adaptive_bit_rate_supported :
460 adaptive_bit_rate_supporteds) {
461 AacConfiguration aac_data{
462 .objectType = object_type,
463 .sampleRateHz = sample_rate,
464 .channelMode = channel_mode,
465 .variableBitRateEnabled = variable_bit_rate_enabled,
466 .bitsPerSample = bits_per_sample,
467 .adaptiveBitRateSupported = adaptive_bit_rate_supported};
468 aac_codec_specifics.push_back(
469 CodecConfiguration::CodecSpecific(aac_data));
470 }
Josh Wu049e2cd2022-01-12 05:42:58 -0800471 }
472 }
473 }
474 }
475 }
476 return aac_codec_specifics;
477 }
478
479 std::vector<CodecConfiguration::CodecSpecific>
480 GetLdacCodecSpecificSupportedList(bool supported) {
481 std::vector<CodecConfiguration::CodecSpecific> ldac_codec_specifics;
482 if (!supported) {
483 LdacConfiguration ldac_config{.sampleRateHz = 0, .bitsPerSample = 0};
484 ldac_codec_specifics.push_back(
485 CodecConfiguration::CodecSpecific(ldac_config));
486 return ldac_codec_specifics;
487 }
488 GetA2dpOffloadCapabilityHelper(CodecType::LDAC);
489 if (temp_codec_capabilities_ == nullptr ||
490 temp_codec_capabilities_->codecType != CodecType::LDAC) {
491 return ldac_codec_specifics;
492 }
493 // parse the capability
494 auto& ldac_capability =
495 temp_codec_capabilities_->capabilities
496 .get<CodecCapabilities::Capabilities::ldacCapabilities>();
497
498 // combine those parameters into one list of
499 // CodecConfiguration::CodecSpecific
500 for (int32_t sample_rate : ldac_capability.sampleRateHz) {
501 for (int8_t bits_per_sample : ldac_capability.bitsPerSample) {
502 for (auto channel_mode : ldac_capability.channelMode) {
503 for (auto quality_index : ldac_capability.qualityIndex) {
504 LdacConfiguration ldac_data{.sampleRateHz = sample_rate,
505 .channelMode = channel_mode,
506 .qualityIndex = quality_index,
507 .bitsPerSample = bits_per_sample};
508 ldac_codec_specifics.push_back(
509 CodecConfiguration::CodecSpecific(ldac_data));
510 }
511 }
512 }
513 }
514 return ldac_codec_specifics;
515 }
516
517 std::vector<CodecConfiguration::CodecSpecific>
518 GetAptxCodecSpecificSupportedList(bool is_hd, bool supported) {
519 std::vector<CodecConfiguration::CodecSpecific> aptx_codec_specifics;
520 if (!supported) {
521 AptxConfiguration aptx_config{.sampleRateHz = 0, .bitsPerSample = 0};
522 aptx_codec_specifics.push_back(
523 CodecConfiguration::CodecSpecific(aptx_config));
524 return aptx_codec_specifics;
525 }
526 GetA2dpOffloadCapabilityHelper(
527 (is_hd ? CodecType::APTX_HD : CodecType::APTX));
528 if (temp_codec_capabilities_ == nullptr) {
529 return aptx_codec_specifics;
530 }
531 if ((is_hd && temp_codec_capabilities_->codecType != CodecType::APTX_HD) ||
532 (!is_hd && temp_codec_capabilities_->codecType != CodecType::APTX)) {
533 return aptx_codec_specifics;
534 }
535
536 // parse the capability
537 auto& aptx_capability =
538 temp_codec_capabilities_->capabilities
539 .get<CodecCapabilities::Capabilities::aptxCapabilities>();
540
541 // combine those parameters into one list of
542 // CodecConfiguration::CodecSpecific
543 for (int8_t bits_per_sample : aptx_capability.bitsPerSample) {
544 for (int32_t sample_rate : aptx_capability.sampleRateHz) {
545 for (auto channel_mode : aptx_capability.channelMode) {
546 AptxConfiguration aptx_data{.sampleRateHz = sample_rate,
547 .channelMode = channel_mode,
548 .bitsPerSample = bits_per_sample};
549 aptx_codec_specifics.push_back(
550 CodecConfiguration::CodecSpecific(aptx_data));
551 }
552 }
553 }
554 return aptx_codec_specifics;
555 }
556
557 std::vector<CodecConfiguration::CodecSpecific>
Omer Osmana2587da2022-05-01 03:54:11 +0000558 GetOpusCodecSpecificSupportedList(bool supported) {
559 std::vector<CodecConfiguration::CodecSpecific> opus_codec_specifics;
Josh Wu049e2cd2022-01-12 05:42:58 -0800560 if (!supported) {
Omer Osmana2587da2022-05-01 03:54:11 +0000561 OpusConfiguration opus_config{.samplingFrequencyHz = 0,
562 .frameDurationUs = 0};
563 opus_codec_specifics.push_back(
564 CodecConfiguration::CodecSpecific(opus_config));
565 return opus_codec_specifics;
Josh Wu049e2cd2022-01-12 05:42:58 -0800566 }
Omer Osmana2587da2022-05-01 03:54:11 +0000567 GetA2dpOffloadCapabilityHelper(CodecType::OPUS);
Josh Wu049e2cd2022-01-12 05:42:58 -0800568 if (temp_codec_capabilities_ == nullptr ||
Omer Osmana2587da2022-05-01 03:54:11 +0000569 temp_codec_capabilities_->codecType != CodecType::OPUS) {
570 return opus_codec_specifics;
Josh Wu049e2cd2022-01-12 05:42:58 -0800571 }
572 // parse the capability
Omer Osmana2587da2022-05-01 03:54:11 +0000573 auto& opus_capability =
Josh Wu049e2cd2022-01-12 05:42:58 -0800574 temp_codec_capabilities_->capabilities
Omer Osmana2587da2022-05-01 03:54:11 +0000575 .get<CodecCapabilities::Capabilities::opusCapabilities>();
Josh Wu049e2cd2022-01-12 05:42:58 -0800576
577 // combine those parameters into one list of
578 // CodecConfiguration::CodecSpecific
Omer Osmana2587da2022-05-01 03:54:11 +0000579 for (int32_t samplingFrequencyHz : opus_capability->samplingFrequencyHz) {
580 for (int32_t frameDurationUs : opus_capability->frameDurationUs) {
581 for (auto channel_mode : opus_capability->channelMode) {
582 OpusConfiguration opus_data{
583 .samplingFrequencyHz = samplingFrequencyHz,
shihchienc3ab9f5e2022-09-23 08:18:05 +0000584 .frameDurationUs = frameDurationUs,
Omer Osmana2587da2022-05-01 03:54:11 +0000585 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +0000586 };
Omer Osmana2587da2022-05-01 03:54:11 +0000587 opus_codec_specifics.push_back(
588 CodecConfiguration::CodecSpecific(opus_data));
Josh Wu049e2cd2022-01-12 05:42:58 -0800589 }
590 }
591 }
Omer Osmana2587da2022-05-01 03:54:11 +0000592 return opus_codec_specifics;
Josh Wu049e2cd2022-01-12 05:42:58 -0800593 }
594
Alice Kuoadcceec2022-03-28 13:28:43 +0800595 bool IsPcmConfigSupported(const PcmConfiguration& pcm_config) {
596 if (temp_provider_capabilities_.size() != 1 ||
597 temp_provider_capabilities_[0].getTag() !=
598 AudioCapabilities::pcmCapabilities) {
599 return false;
600 }
601 auto pcm_capability = temp_provider_capabilities_[0]
602 .get<AudioCapabilities::pcmCapabilities>();
603 return (contained_in_vector(pcm_capability.channelMode,
604 pcm_config.channelMode) &&
605 contained_in_vector(pcm_capability.sampleRateHz,
606 pcm_config.sampleRateHz) &&
607 contained_in_vector(pcm_capability.bitsPerSample,
608 pcm_config.bitsPerSample));
609 }
610
611 std::shared_ptr<IBluetoothAudioProviderFactory> provider_factory_;
612 std::shared_ptr<IBluetoothAudioProvider> audio_provider_;
613 std::shared_ptr<IBluetoothAudioPort> audio_port_;
614 std::vector<AudioCapabilities> temp_provider_capabilities_;
Bao Doc36897d2023-12-06 01:27:54 +0000615 std::optional<IBluetoothAudioProviderFactory::ProviderInfo>
616 temp_provider_info_;
Alice Kuoadcceec2022-03-28 13:28:43 +0800617
Josh Wu049e2cd2022-01-12 05:42:58 -0800618 // temp storage saves the specified codec capability by
619 // GetOffloadCodecCapabilityHelper()
620 CodecCapabilities* temp_codec_capabilities_;
Alice Kuoadcceec2022-03-28 13:28:43 +0800621
622 static constexpr SessionType kSessionTypes[] = {
623 SessionType::UNKNOWN,
624 SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
625 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
626 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
627 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
628 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
629 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
630 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
631 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
632 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
633 SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
634 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
Bao Dob487a852023-12-25 10:12:09 +0800635 };
636
637 static constexpr SessionType kAndroidVSessionType[] = {
Bao Do72399432023-11-09 08:13:05 +0000638 SessionType::HFP_SOFTWARE_ENCODING_DATAPATH,
639 SessionType::HFP_SOFTWARE_DECODING_DATAPATH,
Alice Kuoadcceec2022-03-28 13:28:43 +0800640 };
Bao Dob487a852023-12-25 10:12:09 +0800641
642 BluetoothAudioHalVersion GetProviderFactoryInterfaceVersion() {
643 int32_t aidl_version = 0;
644 if (provider_factory_ == nullptr) {
645 return BluetoothAudioHalVersion::VERSION_UNAVAILABLE;
646 }
647
648 auto aidl_retval = provider_factory_->getInterfaceVersion(&aidl_version);
649 if (!aidl_retval.isOk()) {
650 return BluetoothAudioHalVersion::VERSION_UNAVAILABLE;
651 }
652 switch (aidl_version) {
653 case 1:
654 return BluetoothAudioHalVersion::VERSION_AIDL_V1;
655 case 2:
656 return BluetoothAudioHalVersion::VERSION_AIDL_V2;
657 case 3:
658 return BluetoothAudioHalVersion::VERSION_AIDL_V3;
659 case 4:
660 return BluetoothAudioHalVersion::VERSION_AIDL_V4;
661 default:
662 return BluetoothAudioHalVersion::VERSION_UNAVAILABLE;
663 }
664
665 return BluetoothAudioHalVersion::VERSION_UNAVAILABLE;
666 }
Alice Kuoadcceec2022-03-28 13:28:43 +0800667};
668
669/**
670 * Test whether we can get the FactoryService from HIDL
671 */
672TEST_P(BluetoothAudioProviderFactoryAidl, GetProviderFactoryService) {}
673
674/**
675 * Test whether we can open a provider for each provider returned by
676 * getProviderCapabilities() with non-empty capabalities
677 */
678TEST_P(BluetoothAudioProviderFactoryAidl,
679 OpenProviderAndCheckCapabilitiesBySession) {
680 for (auto session_type : kSessionTypes) {
681 GetProviderCapabilitiesHelper(session_type);
682 OpenProviderHelper(session_type);
683 // We must be able to open a provider if its getProviderCapabilities()
684 // returns non-empty list.
685 EXPECT_TRUE(temp_provider_capabilities_.empty() ||
686 audio_provider_ != nullptr);
687 }
Bao Dob487a852023-12-25 10:12:09 +0800688 if (GetProviderFactoryInterfaceVersion() >=
689 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
690 for (auto session_type : kAndroidVSessionType) {
691 GetProviderCapabilitiesHelper(session_type);
692 OpenProviderHelper(session_type);
693 EXPECT_TRUE(temp_provider_capabilities_.empty() ||
694 audio_provider_ != nullptr);
695 }
696 }
Alice Kuoadcceec2022-03-28 13:28:43 +0800697}
698
699/**
Antoine SOULIER8c90f1f2023-09-26 18:55:17 +0000700 * Test that getProviderInfo, when implemented,
701 * returns empty information for session types for
702 * software data paths.
703 */
704TEST_P(BluetoothAudioProviderFactoryAidl, getProviderInfo_invalidSessionTypes) {
705 static constexpr SessionType kInvalidSessionTypes[]{
706 SessionType::UNKNOWN,
707 SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
708 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
709 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
710 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
711 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
712 SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
713 };
714
715 for (auto session_type : kInvalidSessionTypes) {
716 std::optional<IBluetoothAudioProviderFactory::ProviderInfo> provider_info =
717 std::nullopt;
718 auto aidl_retval =
719 provider_factory_->getProviderInfo(session_type, &provider_info);
720 if (!aidl_retval.isOk()) {
721 continue;
722 }
723
724 // If getProviderInfo is supported, the provider info
725 // must be empty for software session types.
726 ASSERT_FALSE(provider_info.has_value());
727 }
728}
729
730/**
731 * Test that getProviderInfo, when implemented,
732 * returns valid information for session types for
733 * a2dp hardware data paths.
734 */
735TEST_P(BluetoothAudioProviderFactoryAidl, getProviderInfo_a2dpSessionTypes) {
736 static constexpr SessionType kA2dpSessionTypes[]{
737 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
738 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
739 };
740
741 for (auto session_type : kA2dpSessionTypes) {
742 std::optional<IBluetoothAudioProviderFactory::ProviderInfo> provider_info =
743 std::nullopt;
744 auto aidl_retval =
745 provider_factory_->getProviderInfo(session_type, &provider_info);
746 if (!aidl_retval.isOk() || !provider_info.has_value()) {
747 continue;
748 }
749
750 for (auto const& codec_info : provider_info->codecInfos) {
751 // The codec id must not be core.
752 ASSERT_NE(codec_info.id.getTag(), CodecId::core);
753 // The codec info must contain the information
754 // for a2dp transport.
755 ASSERT_EQ(codec_info.transport.getTag(), CodecInfo::Transport::a2dp);
756 }
757 }
758}
759
760/**
761 * Test that getProviderInfo, when implemented,
762 * returns valid information for session types for
763 * le audio hardware data paths.
764 */
765TEST_P(BluetoothAudioProviderFactoryAidl, getProviderInfo_leAudioSessionTypes) {
766 static constexpr SessionType kLeAudioSessionTypes[]{
767 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
768 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
769 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
770 };
771
772 for (auto session_type : kLeAudioSessionTypes) {
773 std::optional<IBluetoothAudioProviderFactory::ProviderInfo> provider_info =
774 std::nullopt;
775 auto aidl_retval =
776 provider_factory_->getProviderInfo(session_type, &provider_info);
777 if (!aidl_retval.isOk() || !provider_info.has_value()) {
778 continue;
779 }
780
781 for (auto const& codec_info : provider_info->codecInfos) {
782 // The codec id must not be a2dp.
783 ASSERT_NE(codec_info.id.getTag(), CodecId::a2dp);
784 // The codec info must contain the information
785 // for le audio transport.
Jakub Tyszkowski06781c02024-01-08 13:16:42 +0000786 ASSERT_EQ(codec_info.transport.getTag(), CodecInfo::Transport::leAudio);
Antoine SOULIER8c90f1f2023-09-26 18:55:17 +0000787 }
788 }
789}
790
Antoine SOULIER33c4e5a2023-09-28 21:59:19 +0000791class BluetoothAudioProviderAidl : public BluetoothAudioProviderFactoryAidl {
792 protected:
793 std::optional<IBluetoothAudioProviderFactory::ProviderInfo>
794 a2dp_encoding_provider_info_{};
795 std::optional<IBluetoothAudioProviderFactory::ProviderInfo>
796 a2dp_decoding_provider_info_{};
797 std::shared_ptr<IBluetoothAudioProvider> a2dp_encoding_provider_{nullptr};
798 std::shared_ptr<IBluetoothAudioProvider> a2dp_decoding_provider_{nullptr};
799
800 public:
801 void SetUp() override {
802 BluetoothAudioProviderFactoryAidl::SetUp();
803 audio_port_ = ndk::SharedRefBase::make<BluetoothAudioPort>();
804
805 (void)provider_factory_->getProviderInfo(
806 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
807 &a2dp_encoding_provider_info_);
808
809 (void)provider_factory_->getProviderInfo(
810 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
811 &a2dp_decoding_provider_info_);
812
813 (void)provider_factory_->openProvider(
814 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
815 &a2dp_encoding_provider_);
816
817 (void)provider_factory_->openProvider(
818 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
819 &a2dp_decoding_provider_);
820 }
821};
822
823/**
824 * Calling parseA2dpConfiguration on a session of a different type than
825 * A2DP_HARDWARE_OFFLOAD_(ENCODING|DECODING)_DATAPATH must fail.
826 */
827TEST_P(BluetoothAudioProviderAidl, parseA2dpConfiguration_invalidSessionType) {
828 static constexpr SessionType kInvalidSessionTypes[] = {
829 SessionType::UNKNOWN,
830 SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
831 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
832 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
833 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
834 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
835 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
836 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
837 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
838 SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
839 };
840
841 for (auto session_type : kInvalidSessionTypes) {
842 // Open a BluetoothAudioProvider instance of the selected session type.
843 // Skip validation if the provider cannot be opened.
844 std::shared_ptr<IBluetoothAudioProvider> provider{nullptr};
845 (void)provider_factory_->openProvider(session_type, &provider);
846 if (provider == nullptr) {
847 continue;
848 }
849
850 // parseA2dpConfiguration must fail without returning an A2dpStatus.
851 CodecId codec_id(CodecId::A2dp::SBC);
852 CodecParameters codec_parameters;
853 A2dpStatus a2dp_status = A2dpStatus::OK;
854 auto aidl_retval = provider->parseA2dpConfiguration(
855 codec_id, std::vector<uint8_t>{}, &codec_parameters, &a2dp_status);
856 EXPECT_FALSE(aidl_retval.isOk());
857 }
858}
859
860/**
861 * Calling parseA2dpConfiguration with an unknown codec must fail
862 * with the A2dpStatus code INVALID_CODEC_TYPE or NOT_SUPPORTED_CODEC_TYPE.
863 */
864TEST_P(BluetoothAudioProviderAidl,
865 parseA2dpConfiguration_unsupportedCodecType) {
866 CodecId unsupported_core_id(CodecId::Core::CVSD);
867 CodecId unsupported_vendor_id(
868 CodecId::Vendor(0xFCB1, 0x42)); // Google Codec #42
869
870 for (auto& provider : {a2dp_encoding_provider_, a2dp_decoding_provider_}) {
871 if (provider == nullptr) {
872 continue;
873 }
874
875 CodecParameters codec_parameters;
876 A2dpStatus a2dp_status = A2dpStatus::OK;
877 ::ndk::ScopedAStatus aidl_retval;
878
879 // Test with two invalid codec identifiers: vendor or core.
880 aidl_retval = provider->parseA2dpConfiguration(
881 unsupported_core_id, std::vector<uint8_t>{}, &codec_parameters,
882 &a2dp_status);
883 EXPECT_TRUE(!aidl_retval.isOk() ||
884 a2dp_status == A2dpStatus::NOT_SUPPORTED_CODEC_TYPE);
885
886 aidl_retval = provider->parseA2dpConfiguration(
887 unsupported_vendor_id, std::vector<uint8_t>{}, &codec_parameters,
888 &a2dp_status);
889 EXPECT_TRUE(!aidl_retval.isOk() ||
890 a2dp_status == A2dpStatus::NOT_SUPPORTED_CODEC_TYPE);
891 }
892}
893
894/**
895 * Calling parseA2dpConfiguration with a known codec and invalid configuration
896 * must fail with an A2dpStatus code different from INVALID_CODEC_TYPE or
897 * NOT_SUPPORTED_CODEC_TYPE.
898 */
899TEST_P(BluetoothAudioProviderAidl,
900 parseA2dpConfiguration_invalidConfiguration) {
901 for (auto& [provider, provider_info] :
902 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
903 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
904 if (provider == nullptr || !provider_info.has_value() ||
905 provider_info->codecInfos.empty()) {
906 continue;
907 }
908
909 CodecParameters codec_parameters;
910 A2dpStatus a2dp_status = A2dpStatus::OK;
911 ::ndk::ScopedAStatus aidl_retval;
912
913 // Test with the first available codec in the provider info for testing.
914 // The test runs with an empty parameters array, anything more specific
915 // would need understanding the codec.
916 aidl_retval = provider->parseA2dpConfiguration(
917 provider_info->codecInfos[0].id, std::vector<uint8_t>{},
918 &codec_parameters, &a2dp_status);
919 ASSERT_TRUE(aidl_retval.isOk());
920 EXPECT_TRUE(a2dp_status != A2dpStatus::OK &&
921 a2dp_status != A2dpStatus::NOT_SUPPORTED_CODEC_TYPE &&
922 a2dp_status != A2dpStatus::INVALID_CODEC_TYPE);
923 }
924}
925
926/**
927 * Calling parseA2dpConfiguration with a known codec and valid parameters
928 * must return with A2dpStatus OK.
929 */
930TEST_P(BluetoothAudioProviderAidl, parseA2dpConfiguration_valid) {
931 for (auto& [provider, provider_info] :
932 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
933 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
934 if (provider == nullptr || !provider_info.has_value() ||
935 provider_info->codecInfos.empty()) {
936 continue;
937 }
938
939 CodecParameters codec_parameters;
940 A2dpStatus a2dp_status = A2dpStatus::OK;
941 ::ndk::ScopedAStatus aidl_retval;
942
943 // Test with the first available codec in the provider info for testing.
944 // To get a valid configuration (the capabilities array in the provider
945 // info is not a selection), getA2dpConfiguration is used with the
946 // selected codec parameters as input.
947 auto const& codec_info = provider_info->codecInfos[0];
948 auto transport = codec_info.transport.get<CodecInfo::Transport::a2dp>();
949 A2dpRemoteCapabilities remote_capabilities(/*seid*/ 0, codec_info.id,
950 transport.capabilities);
951 std::optional<A2dpConfiguration> configuration;
952 aidl_retval = provider->getA2dpConfiguration(
953 std::vector<A2dpRemoteCapabilities>{remote_capabilities},
954 A2dpConfigurationHint(), &configuration);
955 ASSERT_TRUE(aidl_retval.isOk());
956 ASSERT_TRUE(configuration.has_value());
957
958 aidl_retval = provider->parseA2dpConfiguration(
959 configuration->id, configuration->configuration, &codec_parameters,
960 &a2dp_status);
961 ASSERT_TRUE(aidl_retval.isOk());
962 EXPECT_TRUE(a2dp_status == A2dpStatus::OK);
963 EXPECT_EQ(codec_parameters, configuration->parameters);
964 }
965}
966
967/**
968 * Calling getA2dpConfiguration on a session of a different type than
969 * A2DP_HARDWARE_OFFLOAD_(ENCODING|DECODING)_DATAPATH must fail.
970 */
971TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_invalidSessionType) {
972 static constexpr SessionType kInvalidSessionTypes[] = {
973 SessionType::UNKNOWN,
974 SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
975 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
976 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
977 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
978 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
979 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
980 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
981 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
982 SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
983 };
984
985 for (auto session_type : kInvalidSessionTypes) {
986 // Open a BluetoothAudioProvider instance of the selected session type.
987 // Skip validation if the provider cannot be opened.
988 std::shared_ptr<IBluetoothAudioProvider> provider{nullptr};
989 auto aidl_retval = provider_factory_->openProvider(session_type, &provider);
990 if (provider == nullptr) {
991 continue;
992 }
993
994 // getA2dpConfiguration must fail without returning a configuration.
995 std::optional<A2dpConfiguration> configuration;
996 aidl_retval =
997 provider->getA2dpConfiguration(std::vector<A2dpRemoteCapabilities>{},
998 A2dpConfigurationHint(), &configuration);
999 EXPECT_FALSE(aidl_retval.isOk());
1000 }
1001}
1002
1003/**
1004 * Calling getA2dpConfiguration with empty or unknown remote capabilities
1005 * must return an empty configuration.
1006 */
1007TEST_P(BluetoothAudioProviderAidl,
1008 getA2dpConfiguration_unknownRemoteCapabilities) {
1009 for (auto& [provider, provider_info] :
1010 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1011 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1012 if (provider == nullptr || !provider_info.has_value() ||
1013 provider_info->codecInfos.empty()) {
1014 continue;
1015 }
1016
1017 std::optional<A2dpConfiguration> configuration;
1018 ::ndk::ScopedAStatus aidl_retval;
1019
1020 // Test with empty remote capabilities.
1021 aidl_retval =
1022 provider->getA2dpConfiguration(std::vector<A2dpRemoteCapabilities>{},
1023 A2dpConfigurationHint(), &configuration);
1024 ASSERT_TRUE(aidl_retval.isOk());
1025 EXPECT_FALSE(configuration.has_value());
1026
1027 // Test with unknown remote capabilities.
1028 A2dpRemoteCapabilities unknown_core_remote_capabilities(
1029 /*seid*/ 0, CodecId::Core::CVSD, std::vector<uint8_t>{1, 2, 3});
1030 A2dpRemoteCapabilities unknown_vendor_remote_capabilities(
1031 /*seid*/ 1,
1032 /* Google Codec #42 */ CodecId::Vendor(0xFCB1, 0x42),
1033 std::vector<uint8_t>{1, 2, 3});
1034 aidl_retval = provider->getA2dpConfiguration(
1035 std::vector<A2dpRemoteCapabilities>{
1036 unknown_core_remote_capabilities,
1037 unknown_vendor_remote_capabilities,
1038 },
1039 A2dpConfigurationHint(), &configuration);
1040 ASSERT_TRUE(aidl_retval.isOk());
1041 EXPECT_FALSE(configuration.has_value());
1042 }
1043}
1044
1045/**
1046 * Calling getA2dpConfiguration with invalid remote capabilities
1047 * must return an empty configuration.
1048 */
1049TEST_P(BluetoothAudioProviderAidl,
1050 getA2dpConfiguration_invalidRemoteCapabilities) {
1051 for (auto& [provider, provider_info] :
1052 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1053 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1054 if (provider == nullptr || !provider_info.has_value() ||
1055 provider_info->codecInfos.empty()) {
1056 continue;
1057 }
1058
1059 std::optional<A2dpConfiguration> configuration;
1060 ::ndk::ScopedAStatus aidl_retval;
1061
1062 // Use the first available codec in the provider info for testing.
1063 // The capabilities are modified to make them invalid.
1064 auto const& codec_info = provider_info->codecInfos[0];
1065 auto transport = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1066 std::vector<uint8_t> invalid_capabilities = transport.capabilities;
1067 invalid_capabilities.push_back(0x42); // adding bytes should be invalid.
1068 aidl_retval = provider->getA2dpConfiguration(
1069 std::vector<A2dpRemoteCapabilities>{
1070 A2dpRemoteCapabilities(/*seid*/ 0, codec_info.id,
1071 std::vector<uint8_t>()),
1072 A2dpRemoteCapabilities(/*seid*/ 1, codec_info.id,
1073 invalid_capabilities),
1074 },
1075 A2dpConfigurationHint(), &configuration);
1076 ASSERT_TRUE(aidl_retval.isOk());
1077 EXPECT_FALSE(configuration.has_value());
1078 }
1079}
1080
1081/**
1082 * Calling getA2dpConfiguration with valid remote capabilities
1083 * must return a valid configuration. The selected parameters must
1084 * be contained in the original capabilities. The returned configuration
1085 * must match the returned parameters. The returned SEID must match the
1086 * input SEID.
1087 */
1088TEST_P(BluetoothAudioProviderAidl,
1089 getA2dpConfiguration_validRemoteCapabilities) {
1090 for (auto& [provider, provider_info] :
1091 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1092 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1093 if (provider == nullptr || !provider_info.has_value() ||
1094 provider_info->codecInfos.empty()) {
1095 continue;
1096 }
1097
1098 // Test with all available codecs in the provider info.
1099 for (auto const& codec_info : provider_info->codecInfos) {
1100 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1101 std::optional<A2dpConfiguration> configuration{};
1102 ::ndk::ScopedAStatus aidl_retval;
1103
1104 aidl_retval = provider->getA2dpConfiguration(
1105 std::vector<A2dpRemoteCapabilities>{
1106 A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
1107 a2dp_info.capabilities),
1108 },
1109 A2dpConfigurationHint(), &configuration);
1110
1111 ASSERT_TRUE(aidl_retval.isOk());
1112 ASSERT_TRUE(configuration.has_value());
1113
1114 // Returned configuration must have the same codec id
1115 // as the remote capability.
1116 EXPECT_EQ(configuration->id, codec_info.id);
1117
1118 // Returned configuration must have the same SEID
1119 // as the remote capability.
1120 EXPECT_EQ(configuration->remoteSeid, 42);
1121
1122 // Returned codec parameters must be in the range of input
1123 // parameters.
1124 EXPECT_NE(
1125 std::find(a2dp_info.channelMode.begin(), a2dp_info.channelMode.end(),
1126 configuration->parameters.channelMode),
1127 a2dp_info.channelMode.end());
1128 EXPECT_NE(std::find(a2dp_info.samplingFrequencyHz.begin(),
1129 a2dp_info.samplingFrequencyHz.end(),
1130 configuration->parameters.samplingFrequencyHz),
1131 a2dp_info.samplingFrequencyHz.end());
1132 EXPECT_NE(std::find(a2dp_info.bitdepth.begin(), a2dp_info.bitdepth.end(),
1133 configuration->parameters.bitdepth),
1134 a2dp_info.bitdepth.end());
1135 EXPECT_EQ(a2dp_info.lossless, configuration->parameters.lossless);
1136 EXPECT_TRUE(configuration->parameters.minBitrate <=
1137 configuration->parameters.maxBitrate);
1138
1139 // Returned configuration must be parsable by parseA2dpParameters
1140 // and match the codec parameters.
1141 CodecParameters codec_parameters;
1142 A2dpStatus a2dp_status = A2dpStatus::OK;
1143 aidl_retval = provider->parseA2dpConfiguration(
1144 configuration->id, configuration->configuration, &codec_parameters,
1145 &a2dp_status);
1146 ASSERT_TRUE(aidl_retval.isOk());
1147 EXPECT_TRUE(a2dp_status == A2dpStatus::OK);
1148 EXPECT_EQ(codec_parameters, configuration->parameters);
1149 }
1150 }
1151}
1152
1153/**
1154 * Calling getA2dpConfiguration with valid remote capabilities
1155 * with various hinted codec ids.
1156 */
1157TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_hintCodecId) {
1158 for (auto& [provider, provider_info] :
1159 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1160 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1161 if (provider == nullptr || !provider_info.has_value() ||
1162 provider_info->codecInfos.empty()) {
1163 continue;
1164 }
1165
1166 // Build the remote capabilities with all supported codecs.
1167 std::vector<A2dpRemoteCapabilities> remote_capabilities;
1168 for (size_t n = 0; n < provider_info->codecInfos.size(); n++) {
1169 auto const& codec_info = provider_info->codecInfos[n];
1170 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1171 remote_capabilities.push_back(A2dpRemoteCapabilities(
1172 /*seid*/ n, codec_info.id, a2dp_info.capabilities));
1173 }
1174
1175 // Test with all supported codec identifiers,
1176 for (auto const& codec_info : provider_info->codecInfos) {
1177 std::optional<A2dpConfiguration> configuration{};
1178 ::ndk::ScopedAStatus aidl_retval;
1179
1180 A2dpConfigurationHint hint;
1181 hint.codecId = codec_info.id;
1182
1183 aidl_retval = provider->getA2dpConfiguration(remote_capabilities, hint,
1184 &configuration);
1185
1186 ASSERT_TRUE(aidl_retval.isOk());
1187 ASSERT_TRUE(configuration.has_value());
1188 EXPECT_EQ(configuration->id, codec_info.id);
1189 }
1190
1191 // Test with unknown codec identifiers: either core or vendor.
1192 for (auto& codec_id :
1193 {CodecId(CodecId::Core::CVSD),
1194 CodecId(CodecId::Vendor(0xFCB1, 0x42)) /*Google Codec #42*/}) {
1195 std::optional<A2dpConfiguration> configuration{};
1196 ::ndk::ScopedAStatus aidl_retval;
1197
1198 A2dpConfigurationHint hint;
1199 hint.codecId = codec_id;
1200
1201 aidl_retval = provider->getA2dpConfiguration(remote_capabilities, hint,
1202 &configuration);
1203
1204 ASSERT_TRUE(aidl_retval.isOk());
1205 ASSERT_TRUE(configuration.has_value());
1206 EXPECT_NE(configuration->id, codec_id);
1207 }
1208 }
1209}
1210
1211/**
1212 * Calling getA2dpConfiguration with valid remote capabilities
1213 * with various hinted channel modes.
1214 */
1215TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_hintChannelMode) {
1216 for (auto& [provider, provider_info] :
1217 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1218 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1219 if (provider == nullptr || !provider_info.has_value() ||
1220 provider_info->codecInfos.empty()) {
1221 continue;
1222 }
1223
1224 // Test with all available codecs in the provider info.
1225 for (auto const& codec_info : provider_info->codecInfos) {
1226 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1227 std::optional<A2dpConfiguration> configuration{};
1228 ::ndk::ScopedAStatus aidl_retval;
1229
1230 for (auto& channel_mode :
1231 {ChannelMode::STEREO, ChannelMode::MONO, ChannelMode::DUALMONO}) {
1232 // Add the hint for the channel mode.
1233 A2dpConfigurationHint hint;
1234 auto& codec_parameters = hint.codecParameters.emplace();
1235 codec_parameters.channelMode = channel_mode;
1236
1237 aidl_retval = provider->getA2dpConfiguration(
1238 std::vector<A2dpRemoteCapabilities>{
1239 A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
1240 a2dp_info.capabilities),
1241 },
1242 hint, &configuration);
1243
1244 ASSERT_TRUE(aidl_retval.isOk());
1245 ASSERT_TRUE(configuration.has_value());
1246
1247 // The hint must be ignored if the channel mode is not supported
1248 // by the codec, and applied otherwise.
1249 ASSERT_EQ(configuration->parameters.channelMode == channel_mode,
1250 std::find(a2dp_info.channelMode.begin(),
1251 a2dp_info.channelMode.end(),
1252 channel_mode) != a2dp_info.channelMode.end());
1253 }
1254 }
1255 }
1256}
1257
1258/**
1259 * Calling getA2dpConfiguration with valid remote capabilities
1260 * with various hinted sampling frequencies.
1261 */
1262TEST_P(BluetoothAudioProviderAidl,
1263 getA2dpConfiguration_hintSamplingFrequencyHz) {
1264 for (auto& [provider, provider_info] :
1265 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1266 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1267 if (provider == nullptr || !provider_info.has_value() ||
1268 provider_info->codecInfos.empty()) {
1269 continue;
1270 }
1271
1272 // Test with all available codecs in the provider info.
1273 for (auto const& codec_info : provider_info->codecInfos) {
1274 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1275 std::optional<A2dpConfiguration> configuration{};
1276 ::ndk::ScopedAStatus aidl_retval;
1277
1278 for (auto& sampling_frequency_hz : {
1279 0,
1280 1,
1281 8000,
1282 16000,
1283 24000,
1284 32000,
1285 44100,
1286 48000,
1287 88200,
1288 96000,
1289 176400,
1290 192000,
1291 }) {
1292 // Add the hint for the sampling frequency.
1293 A2dpConfigurationHint hint;
1294 auto& codec_parameters = hint.codecParameters.emplace();
1295 codec_parameters.samplingFrequencyHz = sampling_frequency_hz;
1296
1297 aidl_retval = provider->getA2dpConfiguration(
1298 std::vector<A2dpRemoteCapabilities>{
1299 A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
1300 a2dp_info.capabilities),
1301 },
1302 hint, &configuration);
1303
1304 ASSERT_TRUE(aidl_retval.isOk());
1305 ASSERT_TRUE(configuration.has_value());
1306
1307 // The hint must be ignored if the sampling frequency is not supported
1308 // by the codec, and applied otherwise.
1309 ASSERT_EQ(configuration->parameters.samplingFrequencyHz ==
1310 sampling_frequency_hz,
1311 std::find(a2dp_info.samplingFrequencyHz.begin(),
1312 a2dp_info.samplingFrequencyHz.end(),
1313 sampling_frequency_hz) !=
1314 a2dp_info.samplingFrequencyHz.end());
1315 }
1316 }
1317 }
1318}
1319
1320/**
1321 * Calling getA2dpConfiguration with valid remote capabilities
1322 * with various hinted sampling bit-depths.
1323 */
1324TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_hintBitdepth) {
1325 for (auto& [provider, provider_info] :
1326 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1327 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1328 if (provider == nullptr || !provider_info.has_value() ||
1329 provider_info->codecInfos.empty()) {
1330 continue;
1331 }
1332
1333 // Test with all available codecs in the provider info.
1334 for (auto const& codec_info : provider_info->codecInfos) {
1335 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1336 std::optional<A2dpConfiguration> configuration{};
1337 ::ndk::ScopedAStatus aidl_retval;
1338
1339 for (auto& bitdepth : {0, 1, 16, 24, 32}) {
1340 // Add the hint for the bit depth.
1341 A2dpConfigurationHint hint;
1342 auto& codec_parameters = hint.codecParameters.emplace();
1343 codec_parameters.bitdepth = bitdepth;
1344
1345 aidl_retval = provider->getA2dpConfiguration(
1346 std::vector<A2dpRemoteCapabilities>{
1347 A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
1348 a2dp_info.capabilities),
1349 },
1350 hint, &configuration);
1351
1352 ASSERT_TRUE(aidl_retval.isOk());
1353 ASSERT_TRUE(configuration.has_value());
1354
1355 // The hint must be ignored if the bitdepth is not supported
1356 // by the codec, and applied otherwise.
1357 ASSERT_EQ(
1358 configuration->parameters.bitdepth == bitdepth,
1359 std::find(a2dp_info.bitdepth.begin(), a2dp_info.bitdepth.end(),
1360 bitdepth) != a2dp_info.bitdepth.end());
1361 }
1362 }
1363 }
1364}
1365
1366/**
1367 * Calling startSession with an unknown codec id must fail.
1368 */
1369TEST_P(BluetoothAudioProviderAidl, startSession_unknownCodecId) {
1370 for (auto& [provider, provider_info] :
1371 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1372 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1373 if (provider == nullptr || !provider_info.has_value() ||
1374 provider_info->codecInfos.empty()) {
1375 continue;
1376 }
1377
1378 for (auto& codec_id :
1379 {CodecId(CodecId::Core::CVSD),
1380 CodecId(CodecId::Vendor(0xFCB1, 0x42) /*Google Codec #42*/)}) {
1381 A2dpStreamConfiguration a2dp_config;
1382 DataMQDesc data_mq_desc;
1383
1384 a2dp_config.codecId = codec_id;
1385 a2dp_config.configuration = std::vector<uint8_t>{1, 2, 3};
1386
1387 auto aidl_retval =
1388 provider->startSession(audio_port_, AudioConfiguration(a2dp_config),
1389 std::vector<LatencyMode>{}, &data_mq_desc);
1390
1391 EXPECT_FALSE(aidl_retval.isOk());
1392 }
1393 }
1394}
1395
1396/**
1397 * Calling startSession with a known codec and a valid configuration
1398 * must succeed.
1399 */
1400TEST_P(BluetoothAudioProviderAidl, startSession_valid) {
1401 for (auto& [provider, provider_info] :
1402 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1403 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1404 if (provider == nullptr || !provider_info.has_value() ||
1405 provider_info->codecInfos.empty()) {
1406 continue;
1407 }
1408
1409 // Use the first available codec in the provider info for testing.
1410 // To get a valid configuration (the capabilities array in the provider
1411 // info is not a selection), getA2dpConfiguration is used with the
1412 // selected codec parameters as input.
1413 auto const& codec_info = provider_info->codecInfos[0];
1414 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1415 ::ndk::ScopedAStatus aidl_retval;
1416 A2dpRemoteCapabilities remote_capabilities(/*seid*/ 0, codec_info.id,
1417 a2dp_info.capabilities);
1418 std::optional<A2dpConfiguration> configuration;
1419 aidl_retval = provider->getA2dpConfiguration(
1420 std::vector<A2dpRemoteCapabilities>{remote_capabilities},
1421 A2dpConfigurationHint(), &configuration);
1422 ASSERT_TRUE(aidl_retval.isOk());
1423 ASSERT_TRUE(configuration.has_value());
1424
1425 // Build the stream configuration.
1426 A2dpStreamConfiguration a2dp_config;
1427 DataMQDesc data_mq_desc;
1428
1429 a2dp_config.codecId = codec_info.id;
1430 a2dp_config.configuration = configuration->configuration;
1431
1432 aidl_retval =
1433 provider->startSession(audio_port_, AudioConfiguration(a2dp_config),
1434 std::vector<LatencyMode>{}, &data_mq_desc);
1435
1436 EXPECT_TRUE(aidl_retval.isOk());
1437 }
1438}
1439
1440/**
1441 * Calling startSession with a known codec but an invalid configuration
1442 * must fail.
1443 */
1444TEST_P(BluetoothAudioProviderAidl, startSession_invalidConfiguration) {
1445 for (auto& [provider, provider_info] :
1446 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1447 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1448 if (provider == nullptr || !provider_info.has_value() ||
1449 provider_info->codecInfos.empty()) {
1450 continue;
1451 }
1452
1453 // Use the first available codec in the provider info for testing.
1454 // To get a valid configuration (the capabilities array in the provider
1455 // info is not a selection), getA2dpConfiguration is used with the
1456 // selected codec parameters as input.
1457 ::ndk::ScopedAStatus aidl_retval;
1458 auto const& codec_info = provider_info->codecInfos[0];
1459 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1460 A2dpRemoteCapabilities remote_capabilities(/*seid*/ 0, codec_info.id,
1461 a2dp_info.capabilities);
1462 std::optional<A2dpConfiguration> configuration;
1463 aidl_retval = provider->getA2dpConfiguration(
1464 std::vector<A2dpRemoteCapabilities>{remote_capabilities},
1465 A2dpConfigurationHint(), &configuration);
1466 ASSERT_TRUE(aidl_retval.isOk());
1467 ASSERT_TRUE(configuration.has_value());
1468
1469 // Build the stream configuration but edit the configuration bytes
1470 // to make it invalid.
1471 A2dpStreamConfiguration a2dp_config;
1472 DataMQDesc data_mq_desc;
1473
1474 a2dp_config.codecId = codec_info.id;
1475 a2dp_config.configuration = configuration->configuration;
1476 a2dp_config.configuration.push_back(42);
1477
1478 aidl_retval =
1479 provider->startSession(audio_port_, AudioConfiguration(a2dp_config),
1480 std::vector<LatencyMode>{}, &data_mq_desc);
1481
1482 EXPECT_FALSE(aidl_retval.isOk());
1483 }
1484}
1485
Antoine SOULIER8c90f1f2023-09-26 18:55:17 +00001486/**
Alice Kuoadcceec2022-03-28 13:28:43 +08001487 * openProvider A2DP_SOFTWARE_ENCODING_DATAPATH
1488 */
1489class BluetoothAudioProviderA2dpEncodingSoftwareAidl
1490 : public BluetoothAudioProviderFactoryAidl {
1491 public:
1492 virtual void SetUp() override {
1493 BluetoothAudioProviderFactoryAidl::SetUp();
1494 GetProviderCapabilitiesHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
1495 OpenProviderHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
1496 ASSERT_NE(audio_provider_, nullptr);
1497 }
1498
1499 virtual void TearDown() override {
1500 audio_port_ = nullptr;
1501 audio_provider_ = nullptr;
1502 BluetoothAudioProviderFactoryAidl::TearDown();
1503 }
Josh Wu049e2cd2022-01-12 05:42:58 -08001504};
1505
1506/**
1507 * Test whether we can open a provider of type
1508 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001509TEST_P(BluetoothAudioProviderA2dpEncodingSoftwareAidl,
1510 OpenA2dpEncodingSoftwareProvider) {}
1511
1512/**
1513 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08001514 * SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH can be started and stopped
1515 * with different PCM config
Alice Kuoadcceec2022-03-28 13:28:43 +08001516 */
1517TEST_P(BluetoothAudioProviderA2dpEncodingSoftwareAidl,
1518 StartAndEndA2dpEncodingSoftwareSessionWithPossiblePcmConfig) {
1519 for (auto sample_rate : a2dp_sample_rates) {
1520 for (auto bits_per_sample : a2dp_bits_per_samples) {
1521 for (auto channel_mode : a2dp_channel_modes) {
1522 PcmConfiguration pcm_config{
1523 .sampleRateHz = sample_rate,
Alice Kuoadcceec2022-03-28 13:28:43 +08001524 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00001525 .bitsPerSample = bits_per_sample,
Alice Kuoadcceec2022-03-28 13:28:43 +08001526 };
1527 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
1528 DataMQDesc mq_desc;
1529 auto aidl_retval = audio_provider_->startSession(
1530 audio_port_, AudioConfiguration(pcm_config), latency_modes,
1531 &mq_desc);
1532 DataMQ data_mq(mq_desc);
1533
1534 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
1535 if (is_codec_config_valid) {
1536 EXPECT_TRUE(data_mq.isValid());
1537 }
1538 EXPECT_TRUE(audio_provider_->endSession().isOk());
1539 }
1540 }
1541 }
1542}
1543
1544/**
Bao Do72399432023-11-09 08:13:05 +00001545 * openProvider HFP_SOFTWARE_ENCODING_DATAPATH
1546 */
1547class BluetoothAudioProviderHfpSoftwareEncodingAidl
1548 : public BluetoothAudioProviderFactoryAidl {
1549 public:
1550 virtual void SetUp() override {
1551 BluetoothAudioProviderFactoryAidl::SetUp();
Bao Dob487a852023-12-25 10:12:09 +08001552 if (GetProviderFactoryInterfaceVersion() <
1553 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
1554 GTEST_SKIP();
1555 }
Bao Do72399432023-11-09 08:13:05 +00001556 GetProviderCapabilitiesHelper(SessionType::HFP_SOFTWARE_ENCODING_DATAPATH);
1557 OpenProviderHelper(SessionType::HFP_SOFTWARE_ENCODING_DATAPATH);
1558 ASSERT_NE(audio_provider_, nullptr);
1559 }
1560
1561 virtual void TearDown() override {
1562 audio_port_ = nullptr;
1563 audio_provider_ = nullptr;
1564 BluetoothAudioProviderFactoryAidl::TearDown();
1565 }
1566
1567 bool OpenSession(int32_t sample_rate, int8_t bits_per_sample,
Bao Do5b2fdab2023-11-20 08:02:55 +00001568 ChannelMode channel_mode, int32_t data_interval_us) {
Bao Do72399432023-11-09 08:13:05 +00001569 PcmConfiguration pcm_config{
1570 .sampleRateHz = sample_rate,
1571 .channelMode = channel_mode,
1572 .bitsPerSample = bits_per_sample,
1573 .dataIntervalUs = data_interval_us,
1574 };
1575 // Checking against provider capability from getProviderCapabilities
1576 // For HFP software, it's
1577 // BluetoothAudioCodecs::GetSoftwarePcmCapabilities();
1578 DataMQDesc mq_desc;
1579 auto aidl_retval = audio_provider_->startSession(
1580 audio_port_, AudioConfiguration(pcm_config), latency_modes, &mq_desc);
1581 DataMQ data_mq(mq_desc);
1582
1583 if (!aidl_retval.isOk()) return false;
1584 if (!data_mq.isValid()) return false;
1585 return true;
1586 }
1587};
1588
1589/**
1590 * Test whether we can open a provider of type
1591 */
1592TEST_P(BluetoothAudioProviderHfpSoftwareEncodingAidl,
1593 OpenHfpSoftwareEncodingProvider) {}
1594
1595/**
1596 * Test whether each provider of type
1597 * SessionType::HFP_SOFTWARE_ENCODING_DATAPATH can be started and stopped with
1598 * different PCM config
1599 */
1600TEST_P(BluetoothAudioProviderHfpSoftwareEncodingAidl,
1601 StartAndEndHfpEncodingSoftwareSessionWithPossiblePcmConfig) {
1602 for (auto sample_rate : hfp_sample_rates_) {
1603 for (auto bits_per_sample : hfp_bits_per_samples_) {
1604 for (auto channel_mode : hfp_channel_modes_) {
Bao Do5b2fdab2023-11-20 08:02:55 +00001605 for (auto data_interval_us : hfp_data_interval_us_) {
1606 EXPECT_TRUE(OpenSession(sample_rate, bits_per_sample, channel_mode,
1607 data_interval_us));
Bao Do72399432023-11-09 08:13:05 +00001608 EXPECT_TRUE(audio_provider_->endSession().isOk());
1609 }
1610 }
1611 }
1612 }
1613}
1614
1615/**
1616 * openProvider HFP_SOFTWARE_DECODING_DATAPATH
1617 */
1618class BluetoothAudioProviderHfpSoftwareDecodingAidl
1619 : public BluetoothAudioProviderFactoryAidl {
1620 public:
1621 virtual void SetUp() override {
1622 BluetoothAudioProviderFactoryAidl::SetUp();
Bao Dob487a852023-12-25 10:12:09 +08001623 if (GetProviderFactoryInterfaceVersion() <
1624 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
1625 GTEST_SKIP();
1626 }
Bao Do72399432023-11-09 08:13:05 +00001627 GetProviderCapabilitiesHelper(SessionType::HFP_SOFTWARE_DECODING_DATAPATH);
1628 OpenProviderHelper(SessionType::HFP_SOFTWARE_DECODING_DATAPATH);
1629 ASSERT_NE(audio_provider_, nullptr);
1630 }
1631
1632 virtual void TearDown() override {
1633 audio_port_ = nullptr;
1634 audio_provider_ = nullptr;
1635 BluetoothAudioProviderFactoryAidl::TearDown();
1636 }
1637
1638 bool OpenSession(int32_t sample_rate, int8_t bits_per_sample,
Bao Do5b2fdab2023-11-20 08:02:55 +00001639 ChannelMode channel_mode, int32_t data_interval_us) {
Bao Do72399432023-11-09 08:13:05 +00001640 PcmConfiguration pcm_config{
1641 .sampleRateHz = sample_rate,
1642 .channelMode = channel_mode,
1643 .bitsPerSample = bits_per_sample,
1644 .dataIntervalUs = data_interval_us,
1645 };
1646 DataMQDesc mq_desc;
1647 auto aidl_retval = audio_provider_->startSession(
1648 audio_port_, AudioConfiguration(pcm_config), latency_modes, &mq_desc);
1649 DataMQ data_mq(mq_desc);
1650
1651 if (!aidl_retval.isOk()) return false;
1652 if (!data_mq.isValid()) return false;
1653 return true;
1654 }
1655};
1656
1657/**
1658 * Test whether we can open a provider of type
1659 */
1660TEST_P(BluetoothAudioProviderHfpSoftwareDecodingAidl,
1661 OpenHfpSoftwareDecodingProvider) {}
1662
1663/**
1664 * Test whether each provider of type
1665 * SessionType::HFP_SOFTWARE_DECODING_DATAPATH can be started and stopped with
1666 * different PCM config
1667 */
1668TEST_P(BluetoothAudioProviderHfpSoftwareDecodingAidl,
1669 StartAndEndHfpDecodingSoftwareSessionWithPossiblePcmConfig) {
1670 for (auto sample_rate : hfp_sample_rates_) {
1671 for (auto bits_per_sample : hfp_bits_per_samples_) {
1672 for (auto channel_mode : hfp_channel_modes_) {
Bao Do5b2fdab2023-11-20 08:02:55 +00001673 for (auto data_interval_us : hfp_data_interval_us_) {
1674 EXPECT_TRUE(OpenSession(sample_rate, bits_per_sample, channel_mode,
1675 data_interval_us));
1676 EXPECT_TRUE(audio_provider_->endSession().isOk());
Bao Do72399432023-11-09 08:13:05 +00001677 }
1678 }
1679 }
1680 }
1681}
1682
1683/**
Alice Kuoadcceec2022-03-28 13:28:43 +08001684 * openProvider A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH
1685 */
1686class BluetoothAudioProviderA2dpEncodingHardwareAidl
1687 : public BluetoothAudioProviderFactoryAidl {
1688 public:
1689 virtual void SetUp() override {
1690 BluetoothAudioProviderFactoryAidl::SetUp();
1691 GetProviderCapabilitiesHelper(
1692 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
1693 OpenProviderHelper(SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
1694 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
1695 audio_provider_ != nullptr);
1696 }
1697
1698 virtual void TearDown() override {
1699 audio_port_ = nullptr;
1700 audio_provider_ = nullptr;
1701 BluetoothAudioProviderFactoryAidl::TearDown();
1702 }
1703
1704 bool IsOffloadSupported() { return (temp_provider_capabilities_.size() > 0); }
1705};
1706
1707/**
1708 * Test whether we can open a provider of type
1709 */
1710TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1711 OpenA2dpEncodingHardwareProvider) {}
Josh Wu049e2cd2022-01-12 05:42:58 -08001712
1713/**
1714 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08001715 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped
1716 * with SBC hardware encoding config
Josh Wu049e2cd2022-01-12 05:42:58 -08001717 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001718TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1719 StartAndEndA2dpSbcEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001720 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00001721 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08001722 }
1723
1724 CodecConfiguration codec_config = {
1725 .codecType = CodecType::SBC,
1726 .encodedAudioBitrate = 328000,
1727 .peerMtu = 1005,
1728 .isScmstEnabled = false,
1729 };
1730 auto sbc_codec_specifics = GetSbcCodecSpecificSupportedList(true);
1731
1732 for (auto& codec_specific : sbc_codec_specifics) {
1733 copy_codec_specific(codec_config.config, codec_specific);
1734 DataMQDesc mq_desc;
1735 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001736 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001737
1738 ASSERT_TRUE(aidl_retval.isOk());
1739 EXPECT_TRUE(audio_provider_->endSession().isOk());
1740 }
1741}
1742
1743/**
1744 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08001745 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped
1746 * with AAC hardware encoding config
Josh Wu049e2cd2022-01-12 05:42:58 -08001747 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001748TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1749 StartAndEndA2dpAacEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001750 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00001751 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08001752 }
1753
1754 CodecConfiguration codec_config = {
1755 .codecType = CodecType::AAC,
1756 .encodedAudioBitrate = 320000,
1757 .peerMtu = 1005,
1758 .isScmstEnabled = false,
1759 };
1760 auto aac_codec_specifics = GetAacCodecSpecificSupportedList(true);
1761
1762 for (auto& codec_specific : aac_codec_specifics) {
1763 copy_codec_specific(codec_config.config, codec_specific);
1764 DataMQDesc mq_desc;
1765 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001766 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001767
1768 ASSERT_TRUE(aidl_retval.isOk());
1769 EXPECT_TRUE(audio_provider_->endSession().isOk());
1770 }
1771}
1772
1773/**
1774 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08001775 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped
1776 * with LDAC hardware encoding config
Josh Wu049e2cd2022-01-12 05:42:58 -08001777 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001778TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1779 StartAndEndA2dpLdacEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001780 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00001781 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08001782 }
1783
1784 CodecConfiguration codec_config = {
1785 .codecType = CodecType::LDAC,
1786 .encodedAudioBitrate = 990000,
1787 .peerMtu = 1005,
1788 .isScmstEnabled = false,
1789 };
1790 auto ldac_codec_specifics = GetLdacCodecSpecificSupportedList(true);
1791
1792 for (auto& codec_specific : ldac_codec_specifics) {
1793 copy_codec_specific(codec_config.config, codec_specific);
1794 DataMQDesc mq_desc;
1795 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001796 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001797
1798 ASSERT_TRUE(aidl_retval.isOk());
1799 EXPECT_TRUE(audio_provider_->endSession().isOk());
1800 }
1801}
1802
1803/**
1804 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08001805 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped
1806 * with Opus hardware encoding config
Josh Wu049e2cd2022-01-12 05:42:58 -08001807 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001808TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
Omer Osmana2587da2022-05-01 03:54:11 +00001809 StartAndEndA2dpOpusEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001810 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00001811 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08001812 }
1813
1814 CodecConfiguration codec_config = {
Omer Osmana2587da2022-05-01 03:54:11 +00001815 .codecType = CodecType::OPUS,
Josh Wu049e2cd2022-01-12 05:42:58 -08001816 .encodedAudioBitrate = 990000,
1817 .peerMtu = 1005,
1818 .isScmstEnabled = false,
1819 };
Omer Osmana2587da2022-05-01 03:54:11 +00001820 auto opus_codec_specifics = GetOpusCodecSpecificSupportedList(true);
Josh Wu049e2cd2022-01-12 05:42:58 -08001821
Omer Osmana2587da2022-05-01 03:54:11 +00001822 for (auto& codec_specific : opus_codec_specifics) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001823 copy_codec_specific(codec_config.config, codec_specific);
1824 DataMQDesc mq_desc;
1825 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001826 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001827
1828 ASSERT_TRUE(aidl_retval.isOk());
1829 EXPECT_TRUE(audio_provider_->endSession().isOk());
1830 }
1831}
1832
1833/**
1834 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08001835 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped
1836 * with AptX hardware encoding config
Josh Wu049e2cd2022-01-12 05:42:58 -08001837 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001838TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1839 StartAndEndA2dpAptxEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001840 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00001841 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08001842 }
1843
1844 for (auto codec_type : {CodecType::APTX, CodecType::APTX_HD}) {
1845 CodecConfiguration codec_config = {
1846 .codecType = codec_type,
1847 .encodedAudioBitrate =
1848 (codec_type == CodecType::APTX ? 352000 : 576000),
1849 .peerMtu = 1005,
1850 .isScmstEnabled = false,
1851 };
1852
1853 auto aptx_codec_specifics = GetAptxCodecSpecificSupportedList(
1854 (codec_type == CodecType::APTX_HD ? true : false), true);
1855
1856 for (auto& codec_specific : aptx_codec_specifics) {
1857 copy_codec_specific(codec_config.config, codec_specific);
1858 DataMQDesc mq_desc;
1859 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001860 audio_port_, AudioConfiguration(codec_config), latency_modes,
1861 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001862
1863 ASSERT_TRUE(aidl_retval.isOk());
1864 EXPECT_TRUE(audio_provider_->endSession().isOk());
1865 }
1866 }
1867}
1868
1869/**
1870 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08001871 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped
1872 * with an invalid codec config
Josh Wu049e2cd2022-01-12 05:42:58 -08001873 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001874TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1875 StartAndEndA2dpEncodingHardwareSessionInvalidCodecConfig) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001876 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00001877 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08001878 }
1879 ASSERT_NE(audio_provider_, nullptr);
1880
1881 std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
Sagar Verma62df9102022-12-07 17:56:04 +05301882 for (auto codec_type : ndk::enum_range<CodecType>()) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001883 switch (codec_type) {
1884 case CodecType::SBC:
1885 codec_specifics = GetSbcCodecSpecificSupportedList(false);
1886 break;
1887 case CodecType::AAC:
1888 codec_specifics = GetAacCodecSpecificSupportedList(false);
1889 break;
1890 case CodecType::LDAC:
1891 codec_specifics = GetLdacCodecSpecificSupportedList(false);
1892 break;
1893 case CodecType::APTX:
1894 codec_specifics = GetAptxCodecSpecificSupportedList(false, false);
1895 break;
1896 case CodecType::APTX_HD:
1897 codec_specifics = GetAptxCodecSpecificSupportedList(true, false);
1898 break;
Omer Osmana2587da2022-05-01 03:54:11 +00001899 case CodecType::OPUS:
1900 codec_specifics = GetOpusCodecSpecificSupportedList(false);
Josh Wu049e2cd2022-01-12 05:42:58 -08001901 continue;
1902 case CodecType::APTX_ADAPTIVE:
Sagar Verma62df9102022-12-07 17:56:04 +05301903 case CodecType::APTX_ADAPTIVE_LE:
1904 case CodecType::APTX_ADAPTIVE_LEX:
Omer Osmana2587da2022-05-01 03:54:11 +00001905 case CodecType::LC3:
Josh Wu049e2cd2022-01-12 05:42:58 -08001906 case CodecType::VENDOR:
1907 case CodecType::UNKNOWN:
1908 codec_specifics.clear();
1909 break;
1910 }
1911 if (codec_specifics.empty()) {
1912 continue;
1913 }
1914
1915 CodecConfiguration codec_config = {
1916 .codecType = codec_type,
1917 .encodedAudioBitrate = 328000,
1918 .peerMtu = 1005,
1919 .isScmstEnabled = false,
1920 };
1921 for (auto codec_specific : codec_specifics) {
1922 copy_codec_specific(codec_config.config, codec_specific);
1923 DataMQDesc mq_desc;
1924 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001925 audio_port_, AudioConfiguration(codec_config), latency_modes,
1926 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001927
1928 // AIDL call should fail on invalid codec
1929 ASSERT_FALSE(aidl_retval.isOk());
1930 EXPECT_TRUE(audio_provider_->endSession().isOk());
1931 }
1932 }
1933}
1934
1935/**
Bao Do72399432023-11-09 08:13:05 +00001936 * openProvider HFP_HARDWARE_OFFLOAD_DATAPATH
1937 */
1938class BluetoothAudioProviderHfpHardwareAidl
1939 : public BluetoothAudioProviderFactoryAidl {
1940 public:
1941 virtual void SetUp() override {
1942 BluetoothAudioProviderFactoryAidl::SetUp();
Bao Dob487a852023-12-25 10:12:09 +08001943 if (GetProviderFactoryInterfaceVersion() <
1944 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
1945 GTEST_SKIP();
1946 }
Bao Do2fa1ab42024-01-29 17:50:34 +08001947 GetProviderInfoHelper(SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH);
Bao Do72399432023-11-09 08:13:05 +00001948 OpenProviderHelper(SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH);
1949 // Can open or empty capability
1950 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
1951 audio_provider_ != nullptr);
1952 }
1953
1954 virtual void TearDown() override {
1955 audio_port_ = nullptr;
1956 audio_provider_ = nullptr;
1957 BluetoothAudioProviderFactoryAidl::TearDown();
1958 }
1959
1960 bool OpenSession(CodecId codec_id, int connection_handle, bool nrec,
Bao Do5b2fdab2023-11-20 08:02:55 +00001961 bool controller_codec) {
Bao Do72399432023-11-09 08:13:05 +00001962 // Check if can open session with a Hfp configuration
1963 HfpConfiguration hfp_configuration{
1964 .codecId = codec_id,
1965 .connectionHandle = connection_handle,
1966 .nrec = nrec,
1967 .controllerCodec = controller_codec,
1968 };
1969 DataMQDesc mq_desc;
1970 auto aidl_retval = audio_provider_->startSession(
1971 audio_port_, AudioConfiguration(hfp_configuration), latency_modes,
1972 &mq_desc);
1973
1974 // Only check if aidl is ok to start session.
1975 return aidl_retval.isOk();
1976 }
1977};
1978
1979/**
1980 * Test whether we can open a provider of type
1981 */
1982TEST_P(BluetoothAudioProviderHfpHardwareAidl, OpenHfpHardwareProvider) {}
1983
1984/**
1985 * Test whether each provider of type
1986 * SessionType::HFP_SOFTWARE_DECODING_DATAPATH can be started and stopped with
1987 * different HFP config
1988 */
1989TEST_P(BluetoothAudioProviderHfpHardwareAidl,
1990 StartAndEndHfpHardwareSessionWithPossiblePcmConfig) {
1991 // Try to open with a sample configuration
1992 EXPECT_TRUE(OpenSession(CodecId::Core::CVSD, 6, false, true));
1993 EXPECT_TRUE(audio_provider_->endSession().isOk());
1994}
1995
1996/**
Josh Wu049e2cd2022-01-12 05:42:58 -08001997 * openProvider HEARING_AID_SOFTWARE_ENCODING_DATAPATH
1998 */
1999class BluetoothAudioProviderHearingAidSoftwareAidl
2000 : public BluetoothAudioProviderFactoryAidl {
2001 public:
2002 virtual void SetUp() override {
2003 BluetoothAudioProviderFactoryAidl::SetUp();
2004 GetProviderCapabilitiesHelper(
2005 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
2006 OpenProviderHelper(SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
2007 ASSERT_NE(audio_provider_, nullptr);
2008 }
2009
2010 virtual void TearDown() override {
2011 audio_port_ = nullptr;
2012 audio_provider_ = nullptr;
2013 BluetoothAudioProviderFactoryAidl::TearDown();
2014 }
2015
2016 static constexpr int32_t hearing_aid_sample_rates_[] = {0, 16000, 24000};
2017 static constexpr int8_t hearing_aid_bits_per_samples_[] = {0, 16, 24};
2018 static constexpr ChannelMode hearing_aid_channel_modes_[] = {
2019 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
2020};
2021
2022/**
2023 * Test whether we can open a provider of type
2024 */
2025TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl,
2026 OpenHearingAidSoftwareProvider) {}
2027
2028/**
2029 * Test whether each provider of type
2030 * SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH can be started and
2031 * stopped with different PCM config
2032 */
2033TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl,
2034 StartAndEndHearingAidSessionWithPossiblePcmConfig) {
2035 for (int32_t sample_rate : hearing_aid_sample_rates_) {
2036 for (int8_t bits_per_sample : hearing_aid_bits_per_samples_) {
2037 for (auto channel_mode : hearing_aid_channel_modes_) {
2038 PcmConfiguration pcm_config{
2039 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08002040 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00002041 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08002042 };
2043 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
2044 DataMQDesc mq_desc;
2045 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002046 audio_port_, AudioConfiguration(pcm_config), latency_modes,
2047 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002048 DataMQ data_mq(mq_desc);
2049
2050 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
2051 if (is_codec_config_valid) {
2052 EXPECT_TRUE(data_mq.isValid());
2053 }
2054 EXPECT_TRUE(audio_provider_->endSession().isOk());
2055 }
2056 }
2057 }
2058}
2059
2060/**
2061 * openProvider LE_AUDIO_SOFTWARE_ENCODING_DATAPATH
2062 */
2063class BluetoothAudioProviderLeAudioOutputSoftwareAidl
2064 : public BluetoothAudioProviderFactoryAidl {
2065 public:
2066 virtual void SetUp() override {
2067 BluetoothAudioProviderFactoryAidl::SetUp();
2068 GetProviderCapabilitiesHelper(
2069 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
2070 OpenProviderHelper(SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
2071 ASSERT_NE(audio_provider_, nullptr);
2072 }
2073
2074 virtual void TearDown() override {
2075 audio_port_ = nullptr;
2076 audio_provider_ = nullptr;
2077 BluetoothAudioProviderFactoryAidl::TearDown();
2078 }
2079
2080 static constexpr int32_t le_audio_output_sample_rates_[] = {
2081 0, 8000, 16000, 24000, 32000, 44100, 48000,
2082 };
2083 static constexpr int8_t le_audio_output_bits_per_samples_[] = {0, 16, 24};
2084 static constexpr ChannelMode le_audio_output_channel_modes_[] = {
2085 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
2086 static constexpr int32_t le_audio_output_data_interval_us_[] = {
2087 0 /* Invalid */, 10000 /* Valid 10ms */};
2088};
2089
2090/**
2091 * Test whether each provider of type
2092 * SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH can be started and
2093 * stopped
2094 */
2095TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl,
2096 OpenLeAudioOutputSoftwareProvider) {}
2097
2098/**
2099 * Test whether each provider of type
2100 * SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH can be started and
2101 * stopped with different PCM config
2102 */
2103TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl,
2104 StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
2105 for (auto sample_rate : le_audio_output_sample_rates_) {
2106 for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
2107 for (auto channel_mode : le_audio_output_channel_modes_) {
2108 for (auto data_interval_us : le_audio_output_data_interval_us_) {
2109 PcmConfiguration pcm_config{
2110 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08002111 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00002112 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08002113 .dataIntervalUs = data_interval_us,
2114 };
Josh Wu8a1be762022-02-15 09:37:29 -08002115 bool is_codec_config_valid =
2116 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
Josh Wu049e2cd2022-01-12 05:42:58 -08002117 DataMQDesc mq_desc;
2118 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002119 audio_port_, AudioConfiguration(pcm_config), latency_modes,
2120 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002121 DataMQ data_mq(mq_desc);
2122
2123 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
2124 if (is_codec_config_valid) {
2125 EXPECT_TRUE(data_mq.isValid());
2126 }
2127 EXPECT_TRUE(audio_provider_->endSession().isOk());
2128 }
2129 }
2130 }
2131 }
2132}
2133
2134/**
Alice Kuo04a399a2022-02-16 09:19:56 +08002135 * openProvider LE_AUDIO_SOFTWARE_DECODING_DATAPATH
Josh Wu049e2cd2022-01-12 05:42:58 -08002136 */
2137class BluetoothAudioProviderLeAudioInputSoftwareAidl
2138 : public BluetoothAudioProviderFactoryAidl {
2139 public:
2140 virtual void SetUp() override {
2141 BluetoothAudioProviderFactoryAidl::SetUp();
2142 GetProviderCapabilitiesHelper(
2143 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH);
2144 OpenProviderHelper(SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH);
2145 ASSERT_NE(audio_provider_, nullptr);
2146 }
2147
2148 virtual void TearDown() override {
2149 audio_port_ = nullptr;
2150 audio_provider_ = nullptr;
2151 BluetoothAudioProviderFactoryAidl::TearDown();
2152 }
2153
2154 static constexpr int32_t le_audio_input_sample_rates_[] = {
2155 0, 8000, 16000, 24000, 32000, 44100, 48000};
2156 static constexpr int8_t le_audio_input_bits_per_samples_[] = {0, 16, 24};
2157 static constexpr ChannelMode le_audio_input_channel_modes_[] = {
2158 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
2159 static constexpr int32_t le_audio_input_data_interval_us_[] = {
2160 0 /* Invalid */, 10000 /* Valid 10ms */};
2161};
2162
2163/**
2164 * Test whether each provider of type
Alice Kuo04a399a2022-02-16 09:19:56 +08002165 * SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002166 * stopped
2167 */
2168TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl,
2169 OpenLeAudioInputSoftwareProvider) {}
2170
2171/**
2172 * Test whether each provider of type
Alice Kuo04a399a2022-02-16 09:19:56 +08002173 * SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002174 * stopped with different PCM config
2175 */
2176TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl,
2177 StartAndEndLeAudioInputSessionWithPossiblePcmConfig) {
2178 for (auto sample_rate : le_audio_input_sample_rates_) {
2179 for (auto bits_per_sample : le_audio_input_bits_per_samples_) {
2180 for (auto channel_mode : le_audio_input_channel_modes_) {
2181 for (auto data_interval_us : le_audio_input_data_interval_us_) {
2182 PcmConfiguration pcm_config{
2183 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08002184 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00002185 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08002186 .dataIntervalUs = data_interval_us,
2187 };
Josh Wu8a1be762022-02-15 09:37:29 -08002188 bool is_codec_config_valid =
2189 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
Josh Wu049e2cd2022-01-12 05:42:58 -08002190 DataMQDesc mq_desc;
2191 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002192 audio_port_, AudioConfiguration(pcm_config), latency_modes,
2193 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002194 DataMQ data_mq(mq_desc);
2195
2196 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
2197 if (is_codec_config_valid) {
2198 EXPECT_TRUE(data_mq.isValid());
2199 }
2200 EXPECT_TRUE(audio_provider_->endSession().isOk());
2201 }
2202 }
2203 }
2204 }
2205}
2206
2207/**
Alice Kuo04a399a2022-02-16 09:19:56 +08002208 * openProvider LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH
Josh Wu049e2cd2022-01-12 05:42:58 -08002209 */
2210class BluetoothAudioProviderLeAudioOutputHardwareAidl
2211 : public BluetoothAudioProviderFactoryAidl {
2212 public:
2213 virtual void SetUp() override {
2214 BluetoothAudioProviderFactoryAidl::SetUp();
2215 GetProviderCapabilitiesHelper(
2216 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
Bao Doc36897d2023-12-06 01:27:54 +00002217 GetProviderInfoHelper(
2218 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
Josh Wu049e2cd2022-01-12 05:42:58 -08002219 OpenProviderHelper(
2220 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
2221 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
2222 audio_provider_ != nullptr);
2223 }
2224
2225 virtual void TearDown() override {
2226 audio_port_ = nullptr;
2227 audio_provider_ = nullptr;
2228 BluetoothAudioProviderFactoryAidl::TearDown();
2229 }
2230
2231 bool IsOffloadOutputSupported() {
2232 for (auto& capability : temp_provider_capabilities_) {
2233 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2234 continue;
2235 }
2236 auto& le_audio_capability =
2237 capability.get<AudioCapabilities::leAudioCapabilities>();
2238 if (le_audio_capability.unicastEncodeCapability.codecType !=
2239 CodecType::UNKNOWN)
2240 return true;
2241 }
2242 return false;
2243 }
2244
Bao Doc36897d2023-12-06 01:27:54 +00002245 bool IsOffloadOutputProviderInfoSupported() {
2246 if (!temp_provider_info_.has_value()) return false;
2247 if (temp_provider_info_.value().codecInfos.empty()) return false;
2248 // Check if all codec info is of LeAudio type
2249 for (auto& codec_info : temp_provider_info_.value().codecInfos) {
2250 if (codec_info.transport.getTag() != CodecInfo::Transport::leAudio)
2251 return false;
2252 }
2253 return true;
2254 }
2255
2256 std::vector<Lc3Configuration> GetUnicastLc3SupportedListFromProviderInfo() {
2257 std::vector<Lc3Configuration> le_audio_codec_configs;
2258 for (auto& codec_info : temp_provider_info_.value().codecInfos) {
2259 // Only gets LC3 codec information
2260 if (codec_info.id != CodecId::Core::LC3) continue;
2261 // Combine those parameters into one list of Lc3Configuration
2262 auto& transport =
2263 codec_info.transport.get<CodecInfo::Transport::Tag::leAudio>();
2264 for (int32_t samplingFrequencyHz : transport.samplingFrequencyHz) {
2265 for (int32_t frameDurationUs : transport.frameDurationUs) {
2266 for (int32_t octetsPerFrame : transport.bitdepth) {
2267 Lc3Configuration lc3_config = {
2268 .samplingFrequencyHz = samplingFrequencyHz,
2269 .frameDurationUs = frameDurationUs,
2270 .octetsPerFrame = octetsPerFrame,
2271 };
2272 le_audio_codec_configs.push_back(lc3_config);
2273 }
2274 }
2275 }
2276 }
2277
2278 return le_audio_codec_configs;
2279 }
2280
2281 AudioContext GetAudioContext(int32_t bitmask) {
2282 AudioContext media_audio_context;
2283 media_audio_context.bitmask = bitmask;
2284 return media_audio_context;
2285 }
2286
2287 LeAudioDeviceCapabilities GetDefaultRemoteCapability() {
2288 // Create a capability
2289 LeAudioDeviceCapabilities capability;
2290
2291 capability.codecId = CodecId::Core::LC3;
2292
2293 auto pref_context_metadata = MetadataLtv::PreferredAudioContexts();
2294 pref_context_metadata.values = GetAudioContext(AudioContext::MEDIA);
2295 capability.metadata = {pref_context_metadata};
2296
2297 auto sampling_rate =
2298 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies();
2299 sampling_rate.bitmask =
2300 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ8000;
2301 auto frame_duration =
2302 CodecSpecificCapabilitiesLtv::SupportedFrameDurations();
2303 frame_duration.bitmask =
2304 CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US7500;
2305 auto octets = CodecSpecificCapabilitiesLtv::SupportedOctetsPerCodecFrame();
Jakub Tyszkowski1d214222024-01-16 09:44:48 +00002306 octets.min = 0;
2307 octets.max = 60;
Bao Doc36897d2023-12-06 01:27:54 +00002308 auto frames = CodecSpecificCapabilitiesLtv::SupportedMaxCodecFramesPerSDU();
2309 frames.value = 2;
2310 capability.codecSpecificCapabilities = {sampling_rate, frame_duration,
2311 octets, frames};
2312 return capability;
2313 }
2314
2315 LeAudioConfigurationRequirement GetDefaultRequirement(
2316 bool is_source_requriement) {
2317 // Create a requirements
2318 LeAudioConfigurationRequirement requirement;
2319 requirement.audioContext = GetAudioContext(AudioContext::MEDIA);
2320
2321 auto direction_ase_requriement = AseDirectionRequirement();
2322 direction_ase_requriement.aseConfiguration.codecId = CodecId::Core::LC3;
2323 direction_ase_requriement.aseConfiguration.targetLatency =
2324 LeAudioAseConfiguration::TargetLatency::BALANCED_LATENCY_RELIABILITY;
2325
2326 // Mismatch sampling frequency
2327 direction_ase_requriement.aseConfiguration.codecConfiguration = {
2328 CodecSpecificConfigurationLtv::SamplingFrequency::HZ11025,
2329 CodecSpecificConfigurationLtv::FrameDuration::US7500,
2330 };
2331 if (is_source_requriement)
2332 requirement.sourceAseRequirement = {direction_ase_requriement};
2333 else
2334 requirement.sinkAseRequirement = {direction_ase_requriement};
2335 return requirement;
2336 }
2337
Josh Wu049e2cd2022-01-12 05:42:58 -08002338 std::vector<Lc3Configuration> GetUnicastLc3SupportedList(bool decoding,
2339 bool supported) {
2340 std::vector<Lc3Configuration> le_audio_codec_configs;
2341 if (!supported) {
shihchienc3ab9f5e2022-09-23 08:18:05 +00002342 Lc3Configuration lc3_config{.pcmBitDepth = 0, .samplingFrequencyHz = 0};
Josh Wu049e2cd2022-01-12 05:42:58 -08002343 le_audio_codec_configs.push_back(lc3_config);
2344 return le_audio_codec_configs;
2345 }
2346
2347 // There might be more than one LeAudioCodecCapabilitiesSetting
2348 std::vector<Lc3Capabilities> lc3_capabilities;
2349 for (auto& capability : temp_provider_capabilities_) {
2350 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2351 continue;
2352 }
2353 auto& le_audio_capability =
2354 capability.get<AudioCapabilities::leAudioCapabilities>();
2355 auto& unicast_capability =
2356 decoding ? le_audio_capability.unicastDecodeCapability
2357 : le_audio_capability.unicastEncodeCapability;
2358 if (unicast_capability.codecType != CodecType::LC3) {
2359 continue;
2360 }
2361 auto& lc3_capability = unicast_capability.leAudioCodecCapabilities.get<
2362 UnicastCapability::LeAudioCodecCapabilities::lc3Capabilities>();
2363 lc3_capabilities.push_back(lc3_capability);
2364 }
2365
2366 // Combine those parameters into one list of LeAudioCodecConfiguration
2367 // This seems horrible, but usually each Lc3Capability only contains a
2368 // single Lc3Configuration, which means every array has a length of 1.
2369 for (auto& lc3_capability : lc3_capabilities) {
2370 for (int32_t samplingFrequencyHz : lc3_capability.samplingFrequencyHz) {
2371 for (int32_t frameDurationUs : lc3_capability.frameDurationUs) {
2372 for (int32_t octetsPerFrame : lc3_capability.octetsPerFrame) {
2373 Lc3Configuration lc3_config = {
2374 .samplingFrequencyHz = samplingFrequencyHz,
2375 .frameDurationUs = frameDurationUs,
2376 .octetsPerFrame = octetsPerFrame,
2377 };
2378 le_audio_codec_configs.push_back(lc3_config);
2379 }
2380 }
2381 }
2382 }
2383
2384 return le_audio_codec_configs;
2385 }
2386
Sagar Verma62df9102022-12-07 17:56:04 +05302387 static constexpr int32_t apx_adaptive_le_config_codec_modes[] = {0, 1, 2, 3};
2388
2389 std::vector<AptxAdaptiveLeConfiguration>
2390 GetUnicastAptxAdaptiveLeSupportedList(bool decoding, bool supported,
2391 bool is_le_extended) {
2392 std::vector<AptxAdaptiveLeConfiguration> le_audio_codec_configs;
2393 if (!supported) {
2394 AptxAdaptiveLeConfiguration aptx_adaptive_le_config{
2395 .pcmBitDepth = 0, .samplingFrequencyHz = 0};
2396 le_audio_codec_configs.push_back(aptx_adaptive_le_config);
2397 return le_audio_codec_configs;
2398 }
2399
2400 // There might be more than one LeAudioCodecCapabilitiesSetting
2401 std::vector<AptxAdaptiveLeCapabilities> aptx_adaptive_le_capabilities;
2402 for (auto& capability : temp_provider_capabilities_) {
2403 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2404 continue;
2405 }
2406 auto& le_audio_capability =
2407 capability.get<AudioCapabilities::leAudioCapabilities>();
2408 auto& unicast_capability =
2409 decoding ? le_audio_capability.unicastDecodeCapability
2410 : le_audio_capability.unicastEncodeCapability;
2411 if ((!is_le_extended &&
2412 unicast_capability.codecType != CodecType::APTX_ADAPTIVE_LE) ||
2413 (is_le_extended &&
2414 unicast_capability.codecType != CodecType::APTX_ADAPTIVE_LEX)) {
2415 continue;
2416 }
2417
2418 auto& aptx_adaptive_le_capability =
2419 unicast_capability.leAudioCodecCapabilities
2420 .get<UnicastCapability::LeAudioCodecCapabilities::
2421 aptxAdaptiveLeCapabilities>();
2422
2423 aptx_adaptive_le_capabilities.push_back(aptx_adaptive_le_capability);
2424 }
2425
2426 for (auto& aptx_adaptive_le_capability : aptx_adaptive_le_capabilities) {
2427 for (int32_t samplingFrequencyHz :
2428 aptx_adaptive_le_capability.samplingFrequencyHz) {
2429 for (int32_t frameDurationUs :
2430 aptx_adaptive_le_capability.frameDurationUs) {
2431 for (int32_t octetsPerFrame :
2432 aptx_adaptive_le_capability.octetsPerFrame) {
2433 for (int8_t blocksPerSdu :
2434 aptx_adaptive_le_capability.blocksPerSdu) {
2435 for (int32_t codecMode : apx_adaptive_le_config_codec_modes) {
2436 AptxAdaptiveLeConfiguration aptx_adaptive_le_config = {
2437 .samplingFrequencyHz = samplingFrequencyHz,
2438 .frameDurationUs = frameDurationUs,
2439 .octetsPerFrame = octetsPerFrame,
2440 .blocksPerSdu = blocksPerSdu,
2441 .codecMode = codecMode,
2442 };
2443 le_audio_codec_configs.push_back(aptx_adaptive_le_config);
2444 }
2445 }
2446 }
2447 }
2448 }
2449 }
2450
2451 return le_audio_codec_configs;
2452 }
2453
Josh Wu049e2cd2022-01-12 05:42:58 -08002454 LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
Bao Doc36897d2023-12-06 01:27:54 +00002455 std::vector<int32_t> all_context_bitmasks = {
2456 AudioContext::UNSPECIFIED, AudioContext::CONVERSATIONAL,
2457 AudioContext::MEDIA, AudioContext::GAME,
2458 AudioContext::INSTRUCTIONAL, AudioContext::VOICE_ASSISTANTS,
2459 AudioContext::LIVE_AUDIO, AudioContext::SOUND_EFFECTS,
2460 AudioContext::NOTIFICATIONS, AudioContext::RINGTONE_ALERTS,
2461 AudioContext::ALERTS, AudioContext::EMERGENCY_ALARM,
2462 };
Josh Wu049e2cd2022-01-12 05:42:58 -08002463};
2464
2465/**
2466 * Test whether each provider of type
2467 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2468 * stopped
2469 */
2470TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2471 OpenLeAudioOutputHardwareProvider) {}
2472
2473/**
2474 * Test whether each provider of type
2475 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
Bao Doc36897d2023-12-06 01:27:54 +00002476 * stopped with Unicast hardware encoding config taken from provider info
2477 */
2478TEST_P(
2479 BluetoothAudioProviderLeAudioOutputHardwareAidl,
2480 StartAndEndLeAudioOutputSessionWithPossibleUnicastConfigFromProviderInfo) {
Bao Dob487a852023-12-25 10:12:09 +08002481 if (GetProviderFactoryInterfaceVersion() <
2482 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
2483 GTEST_SKIP();
2484 }
Bao Doc36897d2023-12-06 01:27:54 +00002485 if (!IsOffloadOutputProviderInfoSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002486 GTEST_SKIP();
Bao Doc36897d2023-12-06 01:27:54 +00002487 }
2488
2489 auto lc3_codec_configs = GetUnicastLc3SupportedListFromProviderInfo();
2490 LeAudioConfiguration le_audio_config = {
2491 .codecType = CodecType::LC3,
2492 .peerDelayUs = 0,
2493 };
2494
2495 for (auto& lc3_config : lc3_codec_configs) {
2496 le_audio_config.leAudioCodecConfig
2497 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2498 DataMQDesc mq_desc;
2499 auto aidl_retval = audio_provider_->startSession(
2500 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2501 &mq_desc);
2502
2503 ASSERT_TRUE(aidl_retval.isOk());
2504 EXPECT_TRUE(audio_provider_->endSession().isOk());
2505 }
2506}
2507
2508TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2509 GetEmptyAseConfigurationEmptyCapability) {
Bao Dob487a852023-12-25 10:12:09 +08002510 if (GetProviderFactoryInterfaceVersion() <
2511 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
2512 GTEST_SKIP();
2513 }
Bao Doc36897d2023-12-06 01:27:54 +00002514 std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
2515 std::vector<LeAudioConfigurationRequirement> empty_requirement;
2516 std::vector<LeAudioAseConfigurationSetting> configurations;
2517
2518 // Check empty capability for source direction
2519 auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
2520 std::nullopt, empty_capability, empty_requirement, &configurations);
2521
2522 ASSERT_TRUE(aidl_retval.isOk());
2523 ASSERT_TRUE(configurations.empty());
2524
2525 // Check empty capability for sink direction
2526 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
2527 empty_capability, std::nullopt, empty_requirement, &configurations);
2528
2529 ASSERT_TRUE(aidl_retval.isOk());
2530 ASSERT_TRUE(configurations.empty());
2531}
2532
2533TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2534 GetEmptyAseConfigurationMismatchedRequirement) {
Bao Dob487a852023-12-25 10:12:09 +08002535 if (GetProviderFactoryInterfaceVersion() <
2536 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
2537 GTEST_SKIP();
2538 }
Bao Doc36897d2023-12-06 01:27:54 +00002539 std::vector<std::optional<LeAudioDeviceCapabilities>> capabilities = {
2540 GetDefaultRemoteCapability()};
2541
2542 // Check empty capability for source direction
2543 std::vector<LeAudioAseConfigurationSetting> configurations;
2544 std::vector<LeAudioConfigurationRequirement> source_requirements = {
2545 GetDefaultRequirement(true)};
2546 auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
2547 std::nullopt, capabilities, source_requirements, &configurations);
2548
2549 ASSERT_TRUE(aidl_retval.isOk());
2550 ASSERT_TRUE(configurations.empty());
2551
2552 // Check empty capability for sink direction
2553 std::vector<LeAudioConfigurationRequirement> sink_requirements = {
2554 GetDefaultRequirement(false)};
2555 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
2556 capabilities, std::nullopt, source_requirements, &configurations);
2557
2558 ASSERT_TRUE(aidl_retval.isOk());
2559 ASSERT_TRUE(configurations.empty());
2560}
2561
2562TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl, GetQoSConfiguration) {
Bao Dob487a852023-12-25 10:12:09 +08002563 if (GetProviderFactoryInterfaceVersion() <
2564 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
2565 GTEST_SKIP();
2566 }
Bao Doc36897d2023-12-06 01:27:54 +00002567 IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement requirement;
2568 std::vector<IBluetoothAudioProvider::LeAudioAseQosConfiguration>
2569 QoSConfigurations;
2570 for (auto bitmask : all_context_bitmasks) {
Jakub Tyszkowski1d214222024-01-16 09:44:48 +00002571 requirement.audioContext = GetAudioContext(bitmask);
Bao Doc36897d2023-12-06 01:27:54 +00002572 IBluetoothAudioProvider::LeAudioAseQosConfigurationPair result;
2573 auto aidl_retval =
2574 audio_provider_->getLeAudioAseQosConfiguration(requirement, &result);
2575 ASSERT_TRUE(aidl_retval.isOk());
2576 if (result.sinkQosConfiguration.has_value())
2577 QoSConfigurations.push_back(result.sinkQosConfiguration.value());
2578 if (result.sourceQosConfiguration.has_value())
2579 QoSConfigurations.push_back(result.sourceQosConfiguration.value());
2580 }
2581 // QoS Configurations should not be empty, as we searched for all contexts
2582 ASSERT_FALSE(QoSConfigurations.empty());
2583}
Jakub Tyszkowskic8a62242024-01-05 15:25:49 +00002584
2585TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2586 GetDataPathConfiguration) {
Jakub Tyszkowskie77f8722024-01-29 13:21:21 +00002587 if (GetProviderFactoryInterfaceVersion() <
2588 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
2589 GTEST_SKIP();
2590 }
Jakub Tyszkowskic8a62242024-01-05 15:25:49 +00002591 IBluetoothAudioProvider::StreamConfig sink_requirement;
2592 IBluetoothAudioProvider::StreamConfig source_requirement;
2593 std::vector<IBluetoothAudioProvider::LeAudioDataPathConfiguration>
2594 DataPathConfigurations;
2595 bool is_supported = false;
2596
2597 for (auto bitmask : all_context_bitmasks) {
Jakub Tyszkowski1d214222024-01-16 09:44:48 +00002598 sink_requirement.audioContext = GetAudioContext(bitmask);
2599 source_requirement.audioContext = GetAudioContext(bitmask);
Jakub Tyszkowskic8a62242024-01-05 15:25:49 +00002600 IBluetoothAudioProvider::LeAudioDataPathConfigurationPair result;
2601 auto aidl_retval = audio_provider_->getLeAudioAseDatapathConfiguration(
2602 sink_requirement, source_requirement, &result);
2603 if (!aidl_retval.isOk()) {
2604 // If not OK, then it could be not supported, as it is an optional feature
2605 ASSERT_EQ(aidl_retval.getExceptionCode(), EX_UNSUPPORTED_OPERATION);
2606 } else {
2607 is_supported = true;
2608 if (result.inputConfig.has_value())
2609 DataPathConfigurations.push_back(result.inputConfig.value());
2610 if (result.inputConfig.has_value())
2611 DataPathConfigurations.push_back(result.inputConfig.value());
2612 }
2613 }
2614
2615 if (is_supported) {
2616 // Datapath Configurations should not be empty, as we searched for all
2617 // contexts
2618 ASSERT_FALSE(DataPathConfigurations.empty());
2619 }
2620}
2621
Bao Doc36897d2023-12-06 01:27:54 +00002622/**
2623 * Test whether each provider of type
2624 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002625 * stopped with Unicast hardware encoding config
2626 */
2627TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2628 StartAndEndLeAudioOutputSessionWithPossibleUnicastConfig) {
2629 if (!IsOffloadOutputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002630 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08002631 }
2632
2633 auto lc3_codec_configs =
2634 GetUnicastLc3SupportedList(false /* decoding */, true /* supported */);
2635 LeAudioConfiguration le_audio_config = {
2636 .codecType = CodecType::LC3,
2637 .peerDelayUs = 0,
2638 };
2639
2640 for (auto& lc3_config : lc3_codec_configs) {
2641 le_audio_config.leAudioCodecConfig
2642 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2643 DataMQDesc mq_desc;
2644 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002645 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2646 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002647
2648 ASSERT_TRUE(aidl_retval.isOk());
2649 EXPECT_TRUE(audio_provider_->endSession().isOk());
2650 }
2651}
2652
2653/**
2654 * Test whether each provider of type
2655 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2656 * stopped with Unicast hardware encoding config
2657 *
2658 * Disabled since offload codec checking is not ready
2659 */
2660TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2661 DISABLED_StartAndEndLeAudioOutputSessionWithInvalidAudioConfiguration) {
2662 if (!IsOffloadOutputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002663 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08002664 }
2665
2666 auto lc3_codec_configs =
2667 GetUnicastLc3SupportedList(false /* decoding */, false /* supported */);
2668 LeAudioConfiguration le_audio_config = {
2669 .codecType = CodecType::LC3,
2670 .peerDelayUs = 0,
2671 };
2672
2673 for (auto& lc3_config : lc3_codec_configs) {
2674 le_audio_config.leAudioCodecConfig
2675 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2676 DataMQDesc mq_desc;
2677 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002678 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2679 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002680
2681 // AIDL call should fail on invalid codec
2682 ASSERT_FALSE(aidl_retval.isOk());
2683 EXPECT_TRUE(audio_provider_->endSession().isOk());
2684 }
2685}
2686
Sagar Verma62df9102022-12-07 17:56:04 +05302687static std::vector<uint8_t> vendorMetadata = {0x0B, // Length
2688 0xFF, // Type: Vendor-specific
2689 0x0A, 0x00, // Company_ID
2690 0x01, 0x02, 0x03, 0x04, // Data
2691 0x05, 0x06, 0x07, 0x08};
2692
2693/**
2694 * Test whether each provider of type
2695 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2696 * stopped with Unicast hardware encoding config
2697 */
2698TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2699 StartAndEndLeAudioOutputSessionWithAptxAdaptiveLeUnicastConfig) {
2700 if (!IsOffloadOutputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002701 GTEST_SKIP();
Sagar Verma62df9102022-12-07 17:56:04 +05302702 }
2703 for (auto codec_type :
2704 {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
2705 bool is_le_extended = (codec_type == CodecType::APTX_ADAPTIVE_LEX);
2706 auto aptx_adaptive_le_codec_configs =
2707 GetUnicastAptxAdaptiveLeSupportedList(false, true, is_le_extended);
2708 LeAudioConfiguration le_audio_config = {
2709 .codecType = codec_type,
2710 .peerDelayUs = 0,
2711 .vendorSpecificMetadata = vendorMetadata,
2712 };
2713
2714 for (auto& aptx_adaptive_le_config : aptx_adaptive_le_codec_configs) {
2715 le_audio_config.leAudioCodecConfig
2716 .set<LeAudioCodecConfiguration::aptxAdaptiveLeConfig>(
2717 aptx_adaptive_le_config);
2718 DataMQDesc mq_desc;
2719 auto aidl_retval = audio_provider_->startSession(
2720 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2721 &mq_desc);
2722
2723 ASSERT_TRUE(aidl_retval.isOk());
2724 EXPECT_TRUE(audio_provider_->endSession().isOk());
2725 }
2726 }
2727}
2728
2729/**
2730 * Test whether each provider of type
2731 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2732 * stopped with Unicast hardware encoding config
2733 */
2734TEST_P(
2735 BluetoothAudioProviderLeAudioOutputHardwareAidl,
2736 BluetoothAudioProviderLeAudioOutputHardwareAidl_StartAndEndLeAudioOutputSessionWithInvalidAptxAdaptiveLeAudioConfiguration) {
2737 if (!IsOffloadOutputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002738 GTEST_SKIP();
Sagar Verma62df9102022-12-07 17:56:04 +05302739 }
2740
2741 for (auto codec_type :
2742 {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
2743 bool is_le_extended = (codec_type == CodecType::APTX_ADAPTIVE_LEX);
2744 auto aptx_adaptive_le_codec_configs =
2745 GetUnicastAptxAdaptiveLeSupportedList(false, true, is_le_extended);
2746 LeAudioConfiguration le_audio_config = {
2747 .codecType = codec_type,
2748 .peerDelayUs = 0,
2749 .vendorSpecificMetadata = vendorMetadata,
2750 };
2751
2752 for (auto& aptx_adaptive_le_config : aptx_adaptive_le_codec_configs) {
2753 le_audio_config.leAudioCodecConfig
2754 .set<LeAudioCodecConfiguration::aptxAdaptiveLeConfig>(
2755 aptx_adaptive_le_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 // AIDL call should fail on invalid codec
2762 ASSERT_FALSE(aidl_retval.isOk());
2763 EXPECT_TRUE(audio_provider_->endSession().isOk());
2764 }
2765 }
2766}
2767
Josh Wu049e2cd2022-01-12 05:42:58 -08002768/**
2769 * openProvider LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH
2770 */
2771class BluetoothAudioProviderLeAudioInputHardwareAidl
2772 : public BluetoothAudioProviderLeAudioOutputHardwareAidl {
2773 public:
2774 virtual void SetUp() override {
2775 BluetoothAudioProviderFactoryAidl::SetUp();
2776 GetProviderCapabilitiesHelper(
2777 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
Bao Doc36897d2023-12-06 01:27:54 +00002778 GetProviderInfoHelper(
2779 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
Josh Wu049e2cd2022-01-12 05:42:58 -08002780 OpenProviderHelper(
2781 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
2782 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
2783 audio_provider_ != nullptr);
2784 }
2785
2786 bool IsOffloadInputSupported() {
2787 for (auto& capability : temp_provider_capabilities_) {
2788 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2789 continue;
2790 }
2791 auto& le_audio_capability =
2792 capability.get<AudioCapabilities::leAudioCapabilities>();
2793 if (le_audio_capability.unicastDecodeCapability.codecType !=
2794 CodecType::UNKNOWN)
2795 return true;
2796 }
2797 return false;
2798 }
2799
2800 virtual void TearDown() override {
2801 audio_port_ = nullptr;
2802 audio_provider_ = nullptr;
2803 BluetoothAudioProviderFactoryAidl::TearDown();
2804 }
2805};
2806
2807/**
2808 * Test whether each provider of type
Bao Doc36897d2023-12-06 01:27:54 +00002809 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002810 * stopped
2811 */
2812TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
2813 OpenLeAudioInputHardwareProvider) {}
2814
2815/**
2816 * Test whether each provider of type
Bao Doc36897d2023-12-06 01:27:54 +00002817 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
2818 * stopped with Unicast hardware encoding config taken from provider info
2819 */
2820TEST_P(
2821 BluetoothAudioProviderLeAudioInputHardwareAidl,
2822 StartAndEndLeAudioInputSessionWithPossibleUnicastConfigFromProviderInfo) {
2823 if (!IsOffloadOutputProviderInfoSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002824 GTEST_SKIP();
Bao Doc36897d2023-12-06 01:27:54 +00002825 }
2826
2827 auto lc3_codec_configs = GetUnicastLc3SupportedListFromProviderInfo();
2828 LeAudioConfiguration le_audio_config = {
2829 .codecType = CodecType::LC3,
2830 .peerDelayUs = 0,
2831 };
2832
2833 for (auto& lc3_config : lc3_codec_configs) {
2834 le_audio_config.leAudioCodecConfig
2835 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2836 DataMQDesc mq_desc;
2837 auto aidl_retval = audio_provider_->startSession(
2838 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2839 &mq_desc);
2840
2841 ASSERT_TRUE(aidl_retval.isOk());
2842 EXPECT_TRUE(audio_provider_->endSession().isOk());
2843 }
2844}
2845
2846/**
2847 * Test whether each provider of type
2848 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002849 * stopped with Unicast hardware encoding config
2850 */
2851TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
2852 StartAndEndLeAudioInputSessionWithPossibleUnicastConfig) {
2853 if (!IsOffloadInputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002854 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08002855 }
2856
2857 auto lc3_codec_configs =
2858 GetUnicastLc3SupportedList(true /* decoding */, true /* supported */);
2859 LeAudioConfiguration le_audio_config = {
2860 .codecType = CodecType::LC3,
2861 .peerDelayUs = 0,
2862 };
2863
2864 for (auto& lc3_config : lc3_codec_configs) {
2865 le_audio_config.leAudioCodecConfig
2866 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2867 DataMQDesc mq_desc;
2868 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002869 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2870 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002871
2872 ASSERT_TRUE(aidl_retval.isOk());
2873 EXPECT_TRUE(audio_provider_->endSession().isOk());
2874 }
2875}
2876
2877/**
2878 * Test whether each provider of type
Bao Doc36897d2023-12-06 01:27:54 +00002879 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002880 * stopped with Unicast hardware encoding config
2881 *
2882 * Disabled since offload codec checking is not ready
2883 */
2884TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
2885 DISABLED_StartAndEndLeAudioInputSessionWithInvalidAudioConfiguration) {
2886 if (!IsOffloadInputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002887 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08002888 }
2889
2890 auto lc3_codec_configs =
2891 GetUnicastLc3SupportedList(true /* decoding */, false /* supported */);
2892 LeAudioConfiguration le_audio_config = {
2893 .codecType = CodecType::LC3,
2894 .peerDelayUs = 0,
2895 };
2896
2897 for (auto& lc3_config : lc3_codec_configs) {
2898 le_audio_config.leAudioCodecConfig
2899 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2900
2901 DataMQDesc mq_desc;
2902 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002903 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2904 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002905
2906 // AIDL call should fail on invalid codec
2907 ASSERT_FALSE(aidl_retval.isOk());
2908 EXPECT_TRUE(audio_provider_->endSession().isOk());
2909 }
2910}
2911
2912/**
2913 * openProvider LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH
2914 */
2915class BluetoothAudioProviderLeAudioBroadcastSoftwareAidl
2916 : public BluetoothAudioProviderFactoryAidl {
2917 public:
2918 virtual void SetUp() override {
2919 BluetoothAudioProviderFactoryAidl::SetUp();
2920 GetProviderCapabilitiesHelper(
2921 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
2922 OpenProviderHelper(
2923 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
2924 ASSERT_NE(audio_provider_, nullptr);
2925 }
2926
2927 virtual void TearDown() override {
2928 audio_port_ = nullptr;
2929 audio_provider_ = nullptr;
2930 BluetoothAudioProviderFactoryAidl::TearDown();
2931 }
2932
2933 static constexpr int32_t le_audio_output_sample_rates_[] = {
2934 0, 8000, 16000, 24000, 32000, 44100, 48000,
2935 };
2936 static constexpr int8_t le_audio_output_bits_per_samples_[] = {0, 16, 24};
2937 static constexpr ChannelMode le_audio_output_channel_modes_[] = {
2938 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
2939 static constexpr int32_t le_audio_output_data_interval_us_[] = {
2940 0 /* Invalid */, 10000 /* Valid 10ms */};
2941};
2942
2943/**
2944 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08002945 * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started
2946 * and stopped
Josh Wu049e2cd2022-01-12 05:42:58 -08002947 */
2948TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
Josh Wu3202eab2022-02-17 18:09:05 -08002949 OpenLeAudioOutputSoftwareProvider) {}
Josh Wu049e2cd2022-01-12 05:42:58 -08002950
2951/**
2952 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08002953 * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started
2954 * and stopped with different PCM config
Josh Wu049e2cd2022-01-12 05:42:58 -08002955 */
2956TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
Josh Wu3202eab2022-02-17 18:09:05 -08002957 StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
Josh Wu049e2cd2022-01-12 05:42:58 -08002958 for (auto sample_rate : le_audio_output_sample_rates_) {
2959 for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
2960 for (auto channel_mode : le_audio_output_channel_modes_) {
2961 for (auto data_interval_us : le_audio_output_data_interval_us_) {
2962 PcmConfiguration pcm_config{
2963 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08002964 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00002965 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08002966 .dataIntervalUs = data_interval_us,
2967 };
Josh Wu8a1be762022-02-15 09:37:29 -08002968 bool is_codec_config_valid =
2969 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
Josh Wu049e2cd2022-01-12 05:42:58 -08002970 DataMQDesc mq_desc;
2971 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002972 audio_port_, AudioConfiguration(pcm_config), latency_modes,
2973 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002974 DataMQ data_mq(mq_desc);
2975
2976 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
2977 if (is_codec_config_valid) {
2978 EXPECT_TRUE(data_mq.isValid());
2979 }
2980 EXPECT_TRUE(audio_provider_->endSession().isOk());
2981 }
2982 }
2983 }
2984 }
2985}
2986
Alice Kuo336d90c2022-02-16 09:09:59 +08002987/**
2988 * openProvider LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH
2989 */
2990class BluetoothAudioProviderLeAudioBroadcastHardwareAidl
2991 : public BluetoothAudioProviderFactoryAidl {
2992 public:
2993 virtual void SetUp() override {
2994 BluetoothAudioProviderFactoryAidl::SetUp();
2995 GetProviderCapabilitiesHelper(
2996 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
Bao Doc36897d2023-12-06 01:27:54 +00002997 GetProviderInfoHelper(
2998 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
Alice Kuo336d90c2022-02-16 09:09:59 +08002999 OpenProviderHelper(
3000 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
3001 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
3002 audio_provider_ != nullptr);
3003 }
3004
3005 virtual void TearDown() override {
3006 audio_port_ = nullptr;
3007 audio_provider_ = nullptr;
3008 BluetoothAudioProviderFactoryAidl::TearDown();
3009 }
3010
3011 bool IsBroadcastOffloadSupported() {
3012 for (auto& capability : temp_provider_capabilities_) {
3013 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
3014 continue;
3015 }
3016 auto& le_audio_capability =
3017 capability.get<AudioCapabilities::leAudioCapabilities>();
3018 if (le_audio_capability.broadcastCapability.codecType !=
3019 CodecType::UNKNOWN)
3020 return true;
3021 }
3022 return false;
3023 }
3024
Bao Doc36897d2023-12-06 01:27:54 +00003025 bool IsBroadcastOffloadProviderInfoSupported() {
3026 if (!temp_provider_info_.has_value()) return false;
3027 if (temp_provider_info_.value().codecInfos.empty()) return false;
3028 // Check if all codec info is of LeAudio type
3029 for (auto& codec_info : temp_provider_info_.value().codecInfos) {
3030 if (codec_info.transport.getTag() != CodecInfo::Transport::leAudio)
3031 return false;
3032 }
3033 return true;
3034 }
3035
3036 std::vector<Lc3Configuration> GetBroadcastLc3SupportedListFromProviderInfo() {
3037 std::vector<Lc3Configuration> le_audio_codec_configs;
3038 for (auto& codec_info : temp_provider_info_.value().codecInfos) {
3039 // Only gets LC3 codec information
3040 if (codec_info.id != CodecId::Core::LC3) continue;
3041 // Combine those parameters into one list of Lc3Configuration
3042 auto& transport =
3043 codec_info.transport.get<CodecInfo::Transport::Tag::leAudio>();
3044 for (int32_t samplingFrequencyHz : transport.samplingFrequencyHz) {
3045 for (int32_t frameDurationUs : transport.frameDurationUs) {
3046 for (int32_t octetsPerFrame : transport.bitdepth) {
3047 Lc3Configuration lc3_config = {
3048 .samplingFrequencyHz = samplingFrequencyHz,
3049 .frameDurationUs = frameDurationUs,
3050 .octetsPerFrame = octetsPerFrame,
3051 };
3052 le_audio_codec_configs.push_back(lc3_config);
3053 }
3054 }
3055 }
3056 }
3057
3058 return le_audio_codec_configs;
3059 }
3060
Alice Kuo336d90c2022-02-16 09:09:59 +08003061 std::vector<Lc3Configuration> GetBroadcastLc3SupportedList(bool supported) {
3062 std::vector<Lc3Configuration> le_audio_codec_configs;
3063 if (!supported) {
shihchienc3ab9f5e2022-09-23 08:18:05 +00003064 Lc3Configuration lc3_config{.pcmBitDepth = 0, .samplingFrequencyHz = 0};
Alice Kuo336d90c2022-02-16 09:09:59 +08003065 le_audio_codec_configs.push_back(lc3_config);
3066 return le_audio_codec_configs;
3067 }
3068
3069 // There might be more than one LeAudioCodecCapabilitiesSetting
3070 std::vector<Lc3Capabilities> lc3_capabilities;
3071 for (auto& capability : temp_provider_capabilities_) {
3072 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
3073 continue;
3074 }
3075 auto& le_audio_capability =
3076 capability.get<AudioCapabilities::leAudioCapabilities>();
3077 auto& broadcast_capability = le_audio_capability.broadcastCapability;
3078 if (broadcast_capability.codecType != CodecType::LC3) {
3079 continue;
3080 }
3081 auto& lc3_capability = broadcast_capability.leAudioCodecCapabilities.get<
3082 BroadcastCapability::LeAudioCodecCapabilities::lc3Capabilities>();
3083 for (int idx = 0; idx < lc3_capability->size(); idx++)
3084 lc3_capabilities.push_back(*lc3_capability->at(idx));
3085 }
3086
3087 // Combine those parameters into one list of LeAudioCodecConfiguration
3088 // This seems horrible, but usually each Lc3Capability only contains a
3089 // single Lc3Configuration, which means every array has a length of 1.
3090 for (auto& lc3_capability : lc3_capabilities) {
3091 for (int32_t samplingFrequencyHz : lc3_capability.samplingFrequencyHz) {
3092 for (int32_t frameDurationUs : lc3_capability.frameDurationUs) {
3093 for (int32_t octetsPerFrame : lc3_capability.octetsPerFrame) {
3094 Lc3Configuration lc3_config = {
3095 .samplingFrequencyHz = samplingFrequencyHz,
3096 .frameDurationUs = frameDurationUs,
3097 .octetsPerFrame = octetsPerFrame,
3098 };
3099 le_audio_codec_configs.push_back(lc3_config);
3100 }
3101 }
3102 }
3103 }
3104
3105 return le_audio_codec_configs;
3106 }
3107
3108 LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
3109};
3110
3111/**
3112 * Test whether each provider of type
3113 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
3114 * started and stopped
3115 */
3116TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3117 OpenLeAudioOutputHardwareProvider) {}
3118
3119/**
3120 * Test whether each provider of type
3121 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
Bao Doc36897d2023-12-06 01:27:54 +00003122 * started and stopped with broadcast hardware encoding config taken from
3123 * provider info
3124 */
3125TEST_P(
3126 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3127 StartAndEndLeAudioBroadcastSessionWithPossibleUnicastConfigFromProviderInfo) {
Bao Dob487a852023-12-25 10:12:09 +08003128 if (GetProviderFactoryInterfaceVersion() <
3129 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3130 GTEST_SKIP();
3131 }
Bao Doc36897d2023-12-06 01:27:54 +00003132 if (!IsBroadcastOffloadProviderInfoSupported()) {
3133 return;
3134 }
3135
3136 auto lc3_codec_configs = GetBroadcastLc3SupportedListFromProviderInfo();
3137 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
3138 .codecType = CodecType::LC3,
3139 .streamMap = {},
3140 };
3141
3142 for (auto& lc3_config : lc3_codec_configs) {
3143 le_audio_broadcast_config.streamMap.resize(1);
3144 le_audio_broadcast_config.streamMap[0]
3145 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
3146 lc3_config);
3147 le_audio_broadcast_config.streamMap[0].streamHandle = 0x0;
3148 le_audio_broadcast_config.streamMap[0].pcmStreamId = 0x0;
3149 le_audio_broadcast_config.streamMap[0].audioChannelAllocation = 0x1 << 0;
3150
3151 DataMQDesc mq_desc;
3152 auto aidl_retval = audio_provider_->startSession(
3153 audio_port_, AudioConfiguration(le_audio_broadcast_config),
3154 latency_modes, &mq_desc);
3155
3156 ASSERT_TRUE(aidl_retval.isOk());
3157 EXPECT_TRUE(audio_provider_->endSession().isOk());
3158 }
3159}
3160
Bao Do5b2fdab2023-11-20 08:02:55 +00003161TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3162 GetEmptyBroadcastConfigurationEmptyCapability) {
Bao Dob487a852023-12-25 10:12:09 +08003163 if (GetProviderFactoryInterfaceVersion() <
3164 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3165 GTEST_SKIP();
3166 }
Bao Do5b2fdab2023-11-20 08:02:55 +00003167 std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
3168 IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement
3169 empty_requirement;
3170
3171 IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting* configuration =
3172 new IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting();
3173
3174 // Check empty capability for source direction
3175 auto aidl_retval = audio_provider_->getLeAudioBroadcastConfiguration(
3176 empty_capability, empty_requirement, configuration);
3177
3178 ASSERT_TRUE(aidl_retval.isOk());
3179}
3180
Bao Doc36897d2023-12-06 01:27:54 +00003181/**
3182 * Test whether each provider of type
3183 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
Alice Kuo336d90c2022-02-16 09:09:59 +08003184 * started and stopped with broadcast hardware encoding config
3185 */
3186TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3187 StartAndEndLeAudioBroadcastSessionWithPossibleBroadcastConfig) {
3188 if (!IsBroadcastOffloadSupported()) {
3189 return;
3190 }
3191
3192 auto lc3_codec_configs = GetBroadcastLc3SupportedList(true /* supported */);
3193 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
3194 .codecType = CodecType::LC3,
3195 .streamMap = {},
3196 };
3197
3198 for (auto& lc3_config : lc3_codec_configs) {
Patty Huangac077ef2022-11-23 14:45:15 +08003199 le_audio_broadcast_config.streamMap.resize(1);
Alice Kuo336d90c2022-02-16 09:09:59 +08003200 le_audio_broadcast_config.streamMap[0]
3201 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
3202 lc3_config);
Rongxuan Liuc1aea322023-01-26 17:14:54 +00003203 le_audio_broadcast_config.streamMap[0].streamHandle = 0x0;
3204 le_audio_broadcast_config.streamMap[0].pcmStreamId = 0x0;
3205 le_audio_broadcast_config.streamMap[0].audioChannelAllocation = 0x1 << 0;
3206
Alice Kuo336d90c2022-02-16 09:09:59 +08003207 DataMQDesc mq_desc;
3208 auto aidl_retval = audio_provider_->startSession(
Chen Chen60d52e42022-02-16 12:19:12 -08003209 audio_port_, AudioConfiguration(le_audio_broadcast_config),
3210 latency_modes, &mq_desc);
Alice Kuo336d90c2022-02-16 09:09:59 +08003211
3212 ASSERT_TRUE(aidl_retval.isOk());
3213 EXPECT_TRUE(audio_provider_->endSession().isOk());
3214 }
3215}
3216
3217/**
3218 * Test whether each provider of type
3219 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
3220 * started and stopped with Broadcast hardware encoding config
3221 *
3222 * Disabled since offload codec checking is not ready
3223 */
3224TEST_P(
3225 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3226 DISABLED_StartAndEndLeAudioBroadcastSessionWithInvalidAudioConfiguration) {
3227 if (!IsBroadcastOffloadSupported()) {
3228 return;
3229 }
3230
3231 auto lc3_codec_configs = GetBroadcastLc3SupportedList(false /* supported */);
3232 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
3233 .codecType = CodecType::LC3,
3234 .streamMap = {},
3235 };
3236
3237 for (auto& lc3_config : lc3_codec_configs) {
3238 le_audio_broadcast_config.streamMap[0]
3239 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
3240 lc3_config);
3241 DataMQDesc mq_desc;
3242 auto aidl_retval = audio_provider_->startSession(
Chen Chen60d52e42022-02-16 12:19:12 -08003243 audio_port_, AudioConfiguration(le_audio_broadcast_config),
3244 latency_modes, &mq_desc);
Alice Kuo336d90c2022-02-16 09:09:59 +08003245
3246 // AIDL call should fail on invalid codec
3247 ASSERT_FALSE(aidl_retval.isOk());
3248 EXPECT_TRUE(audio_provider_->endSession().isOk());
3249 }
3250}
3251
Alice Kuoadcceec2022-03-28 13:28:43 +08003252/**
3253 * openProvider A2DP_SOFTWARE_DECODING_DATAPATH
3254 */
3255class BluetoothAudioProviderA2dpDecodingSoftwareAidl
3256 : public BluetoothAudioProviderFactoryAidl {
3257 public:
3258 virtual void SetUp() override {
3259 BluetoothAudioProviderFactoryAidl::SetUp();
3260 GetProviderCapabilitiesHelper(SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
3261 OpenProviderHelper(SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
3262 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
3263 audio_provider_ != nullptr);
3264 }
3265
3266 virtual void TearDown() override {
3267 audio_port_ = nullptr;
3268 audio_provider_ = nullptr;
3269 BluetoothAudioProviderFactoryAidl::TearDown();
3270 }
3271};
3272
3273/**
3274 * Test whether we can open a provider of type
3275 */
3276TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,
3277 OpenA2dpDecodingSoftwareProvider) {}
3278
3279/**
3280 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08003281 * SessionType::A2DP_SOFTWARE_DECODING_DATAPATH can be started and stopped
3282 * with different PCM config
Alice Kuoadcceec2022-03-28 13:28:43 +08003283 */
3284TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,
3285 StartAndEndA2dpDecodingSoftwareSessionWithPossiblePcmConfig) {
3286 for (auto sample_rate : a2dp_sample_rates) {
3287 for (auto bits_per_sample : a2dp_bits_per_samples) {
3288 for (auto channel_mode : a2dp_channel_modes) {
3289 PcmConfiguration pcm_config{
3290 .sampleRateHz = sample_rate,
Alice Kuoadcceec2022-03-28 13:28:43 +08003291 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00003292 .bitsPerSample = bits_per_sample,
Alice Kuoadcceec2022-03-28 13:28:43 +08003293 };
3294 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
3295 DataMQDesc mq_desc;
3296 auto aidl_retval = audio_provider_->startSession(
3297 audio_port_, AudioConfiguration(pcm_config), latency_modes,
3298 &mq_desc);
3299 DataMQ data_mq(mq_desc);
3300
3301 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
3302 if (is_codec_config_valid) {
3303 EXPECT_TRUE(data_mq.isValid());
3304 }
3305 EXPECT_TRUE(audio_provider_->endSession().isOk());
3306 }
3307 }
3308 }
3309}
3310
3311/**
3312 * openProvider A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH
3313 */
3314class BluetoothAudioProviderA2dpDecodingHardwareAidl
3315 : public BluetoothAudioProviderFactoryAidl {
3316 public:
3317 virtual void SetUp() override {
3318 BluetoothAudioProviderFactoryAidl::SetUp();
3319 GetProviderCapabilitiesHelper(
3320 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
3321 OpenProviderHelper(SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
3322 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
3323 audio_provider_ != nullptr);
3324 }
3325
3326 virtual void TearDown() override {
3327 audio_port_ = nullptr;
3328 audio_provider_ = nullptr;
3329 BluetoothAudioProviderFactoryAidl::TearDown();
3330 }
3331
3332 bool IsOffloadSupported() { return (temp_provider_capabilities_.size() > 0); }
3333};
3334
3335/**
3336 * Test whether we can open a provider of type
3337 */
3338TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3339 OpenA2dpDecodingHardwareProvider) {}
3340
3341/**
3342 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08003343 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
3344 * with SBC hardware encoding config
Alice Kuoadcceec2022-03-28 13:28:43 +08003345 */
3346TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3347 StartAndEndA2dpSbcDecodingHardwareSession) {
3348 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003349 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08003350 }
3351
3352 CodecConfiguration codec_config = {
3353 .codecType = CodecType::SBC,
3354 .encodedAudioBitrate = 328000,
3355 .peerMtu = 1005,
3356 .isScmstEnabled = false,
3357 };
3358 auto sbc_codec_specifics = GetSbcCodecSpecificSupportedList(true);
3359
3360 for (auto& codec_specific : sbc_codec_specifics) {
3361 copy_codec_specific(codec_config.config, codec_specific);
3362 DataMQDesc mq_desc;
3363 auto aidl_retval = audio_provider_->startSession(
3364 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
3365
3366 ASSERT_TRUE(aidl_retval.isOk());
3367 EXPECT_TRUE(audio_provider_->endSession().isOk());
3368 }
3369}
3370
3371/**
3372 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08003373 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
3374 * with AAC hardware encoding config
Alice Kuoadcceec2022-03-28 13:28:43 +08003375 */
3376TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3377 StartAndEndA2dpAacDecodingHardwareSession) {
3378 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003379 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08003380 }
3381
3382 CodecConfiguration codec_config = {
3383 .codecType = CodecType::AAC,
3384 .encodedAudioBitrate = 320000,
3385 .peerMtu = 1005,
3386 .isScmstEnabled = false,
3387 };
3388 auto aac_codec_specifics = GetAacCodecSpecificSupportedList(true);
3389
3390 for (auto& codec_specific : aac_codec_specifics) {
3391 copy_codec_specific(codec_config.config, codec_specific);
3392 DataMQDesc mq_desc;
3393 auto aidl_retval = audio_provider_->startSession(
3394 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
3395
3396 ASSERT_TRUE(aidl_retval.isOk());
3397 EXPECT_TRUE(audio_provider_->endSession().isOk());
3398 }
3399}
3400
3401/**
3402 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08003403 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
3404 * with LDAC hardware encoding config
Alice Kuoadcceec2022-03-28 13:28:43 +08003405 */
3406TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3407 StartAndEndA2dpLdacDecodingHardwareSession) {
3408 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003409 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08003410 }
3411
3412 CodecConfiguration codec_config = {
3413 .codecType = CodecType::LDAC,
3414 .encodedAudioBitrate = 990000,
3415 .peerMtu = 1005,
3416 .isScmstEnabled = false,
3417 };
3418 auto ldac_codec_specifics = GetLdacCodecSpecificSupportedList(true);
3419
3420 for (auto& codec_specific : ldac_codec_specifics) {
3421 copy_codec_specific(codec_config.config, codec_specific);
3422 DataMQDesc mq_desc;
3423 auto aidl_retval = audio_provider_->startSession(
3424 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
3425
3426 ASSERT_TRUE(aidl_retval.isOk());
3427 EXPECT_TRUE(audio_provider_->endSession().isOk());
3428 }
3429}
3430
3431/**
3432 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08003433 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
3434 * with Opus hardware encoding config
Alice Kuoadcceec2022-03-28 13:28:43 +08003435 */
3436TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
Omer Osmana2587da2022-05-01 03:54:11 +00003437 StartAndEndA2dpOpusDecodingHardwareSession) {
Alice Kuoadcceec2022-03-28 13:28:43 +08003438 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003439 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08003440 }
3441
3442 CodecConfiguration codec_config = {
Omer Osmana2587da2022-05-01 03:54:11 +00003443 .codecType = CodecType::OPUS,
Alice Kuoadcceec2022-03-28 13:28:43 +08003444 .encodedAudioBitrate = 990000,
3445 .peerMtu = 1005,
3446 .isScmstEnabled = false,
3447 };
Omer Osmana2587da2022-05-01 03:54:11 +00003448 auto opus_codec_specifics = GetOpusCodecSpecificSupportedList(true);
Alice Kuoadcceec2022-03-28 13:28:43 +08003449
Omer Osmana2587da2022-05-01 03:54:11 +00003450 for (auto& codec_specific : opus_codec_specifics) {
Alice Kuoadcceec2022-03-28 13:28:43 +08003451 copy_codec_specific(codec_config.config, codec_specific);
3452 DataMQDesc mq_desc;
3453 auto aidl_retval = audio_provider_->startSession(
3454 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
3455
3456 ASSERT_TRUE(aidl_retval.isOk());
3457 EXPECT_TRUE(audio_provider_->endSession().isOk());
3458 }
3459}
3460
3461/**
3462 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08003463 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
3464 * with AptX hardware encoding config
Alice Kuoadcceec2022-03-28 13:28:43 +08003465 */
3466TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3467 StartAndEndA2dpAptxDecodingHardwareSession) {
3468 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003469 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08003470 }
3471
3472 for (auto codec_type : {CodecType::APTX, CodecType::APTX_HD}) {
3473 CodecConfiguration codec_config = {
3474 .codecType = codec_type,
3475 .encodedAudioBitrate =
3476 (codec_type == CodecType::APTX ? 352000 : 576000),
3477 .peerMtu = 1005,
3478 .isScmstEnabled = false,
3479 };
3480
3481 auto aptx_codec_specifics = GetAptxCodecSpecificSupportedList(
3482 (codec_type == CodecType::APTX_HD ? true : false), true);
3483
3484 for (auto& codec_specific : aptx_codec_specifics) {
3485 copy_codec_specific(codec_config.config, codec_specific);
3486 DataMQDesc mq_desc;
3487 auto aidl_retval = audio_provider_->startSession(
3488 audio_port_, AudioConfiguration(codec_config), latency_modes,
3489 &mq_desc);
3490
3491 ASSERT_TRUE(aidl_retval.isOk());
3492 EXPECT_TRUE(audio_provider_->endSession().isOk());
3493 }
3494 }
3495}
3496
3497/**
3498 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08003499 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
3500 * with an invalid codec config
Alice Kuoadcceec2022-03-28 13:28:43 +08003501 */
3502TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3503 StartAndEndA2dpDecodingHardwareSessionInvalidCodecConfig) {
3504 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003505 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08003506 }
3507 ASSERT_NE(audio_provider_, nullptr);
3508
3509 std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
Sagar Verma62df9102022-12-07 17:56:04 +05303510 for (auto codec_type : ndk::enum_range<CodecType>()) {
Alice Kuoadcceec2022-03-28 13:28:43 +08003511 switch (codec_type) {
3512 case CodecType::SBC:
3513 codec_specifics = GetSbcCodecSpecificSupportedList(false);
3514 break;
3515 case CodecType::AAC:
3516 codec_specifics = GetAacCodecSpecificSupportedList(false);
3517 break;
3518 case CodecType::LDAC:
3519 codec_specifics = GetLdacCodecSpecificSupportedList(false);
3520 break;
3521 case CodecType::APTX:
3522 codec_specifics = GetAptxCodecSpecificSupportedList(false, false);
3523 break;
3524 case CodecType::APTX_HD:
3525 codec_specifics = GetAptxCodecSpecificSupportedList(true, false);
3526 break;
Omer Osmana2587da2022-05-01 03:54:11 +00003527 case CodecType::OPUS:
3528 codec_specifics = GetOpusCodecSpecificSupportedList(false);
Alice Kuoadcceec2022-03-28 13:28:43 +08003529 continue;
3530 case CodecType::APTX_ADAPTIVE:
Sagar Verma62df9102022-12-07 17:56:04 +05303531 case CodecType::APTX_ADAPTIVE_LE:
3532 case CodecType::APTX_ADAPTIVE_LEX:
Omer Osmana2587da2022-05-01 03:54:11 +00003533 case CodecType::LC3:
Alice Kuoadcceec2022-03-28 13:28:43 +08003534 case CodecType::VENDOR:
3535 case CodecType::UNKNOWN:
3536 codec_specifics.clear();
3537 break;
3538 }
3539 if (codec_specifics.empty()) {
3540 continue;
3541 }
3542
3543 CodecConfiguration codec_config = {
3544 .codecType = codec_type,
3545 .encodedAudioBitrate = 328000,
3546 .peerMtu = 1005,
3547 .isScmstEnabled = false,
3548 };
3549 for (auto codec_specific : codec_specifics) {
3550 copy_codec_specific(codec_config.config, codec_specific);
3551 DataMQDesc mq_desc;
3552 auto aidl_retval = audio_provider_->startSession(
3553 audio_port_, AudioConfiguration(codec_config), latency_modes,
3554 &mq_desc);
3555
3556 // AIDL call should fail on invalid codec
3557 ASSERT_FALSE(aidl_retval.isOk());
3558 EXPECT_TRUE(audio_provider_->endSession().isOk());
3559 }
3560 }
3561}
3562
Josh Wu049e2cd2022-01-12 05:42:58 -08003563GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3564 BluetoothAudioProviderFactoryAidl);
3565INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderFactoryAidl,
3566 testing::ValuesIn(android::getAidlHalInstanceNames(
3567 IBluetoothAudioProviderFactory::descriptor)),
3568 android::PrintInstanceNameToString);
3569
Antoine SOULIER33c4e5a2023-09-28 21:59:19 +00003570GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothAudioProviderAidl);
3571INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderAidl,
3572 testing::ValuesIn(android::getAidlHalInstanceNames(
3573 IBluetoothAudioProviderFactory::descriptor)),
3574 android::PrintInstanceNameToString);
3575
Josh Wu049e2cd2022-01-12 05:42:58 -08003576GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
Alice Kuoadcceec2022-03-28 13:28:43 +08003577 BluetoothAudioProviderA2dpEncodingSoftwareAidl);
3578INSTANTIATE_TEST_SUITE_P(PerInstance,
3579 BluetoothAudioProviderA2dpEncodingSoftwareAidl,
Josh Wu049e2cd2022-01-12 05:42:58 -08003580 testing::ValuesIn(android::getAidlHalInstanceNames(
3581 IBluetoothAudioProviderFactory::descriptor)),
3582 android::PrintInstanceNameToString);
3583
3584GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
Alice Kuoadcceec2022-03-28 13:28:43 +08003585 BluetoothAudioProviderA2dpEncodingHardwareAidl);
3586INSTANTIATE_TEST_SUITE_P(PerInstance,
3587 BluetoothAudioProviderA2dpEncodingHardwareAidl,
Josh Wu049e2cd2022-01-12 05:42:58 -08003588 testing::ValuesIn(android::getAidlHalInstanceNames(
3589 IBluetoothAudioProviderFactory::descriptor)),
3590 android::PrintInstanceNameToString);
3591
3592GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3593 BluetoothAudioProviderHearingAidSoftwareAidl);
3594INSTANTIATE_TEST_SUITE_P(PerInstance,
3595 BluetoothAudioProviderHearingAidSoftwareAidl,
3596 testing::ValuesIn(android::getAidlHalInstanceNames(
3597 IBluetoothAudioProviderFactory::descriptor)),
3598 android::PrintInstanceNameToString);
3599
3600GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3601 BluetoothAudioProviderLeAudioOutputSoftwareAidl);
3602INSTANTIATE_TEST_SUITE_P(PerInstance,
3603 BluetoothAudioProviderLeAudioOutputSoftwareAidl,
3604 testing::ValuesIn(android::getAidlHalInstanceNames(
3605 IBluetoothAudioProviderFactory::descriptor)),
3606 android::PrintInstanceNameToString);
3607
3608GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3609 BluetoothAudioProviderLeAudioInputSoftwareAidl);
3610INSTANTIATE_TEST_SUITE_P(PerInstance,
3611 BluetoothAudioProviderLeAudioInputSoftwareAidl,
3612 testing::ValuesIn(android::getAidlHalInstanceNames(
3613 IBluetoothAudioProviderFactory::descriptor)),
3614 android::PrintInstanceNameToString);
3615
3616GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3617 BluetoothAudioProviderLeAudioOutputHardwareAidl);
3618INSTANTIATE_TEST_SUITE_P(PerInstance,
3619 BluetoothAudioProviderLeAudioOutputHardwareAidl,
3620 testing::ValuesIn(android::getAidlHalInstanceNames(
3621 IBluetoothAudioProviderFactory::descriptor)),
3622 android::PrintInstanceNameToString);
3623
3624GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3625 BluetoothAudioProviderLeAudioInputHardwareAidl);
3626INSTANTIATE_TEST_SUITE_P(PerInstance,
3627 BluetoothAudioProviderLeAudioInputHardwareAidl,
3628 testing::ValuesIn(android::getAidlHalInstanceNames(
3629 IBluetoothAudioProviderFactory::descriptor)),
3630 android::PrintInstanceNameToString);
3631
3632GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3633 BluetoothAudioProviderLeAudioBroadcastSoftwareAidl);
3634INSTANTIATE_TEST_SUITE_P(PerInstance,
3635 BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
3636 testing::ValuesIn(android::getAidlHalInstanceNames(
3637 IBluetoothAudioProviderFactory::descriptor)),
3638 android::PrintInstanceNameToString);
3639
Alice Kuo336d90c2022-02-16 09:09:59 +08003640GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3641 BluetoothAudioProviderLeAudioBroadcastHardwareAidl);
3642INSTANTIATE_TEST_SUITE_P(PerInstance,
3643 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3644 testing::ValuesIn(android::getAidlHalInstanceNames(
3645 IBluetoothAudioProviderFactory::descriptor)),
3646 android::PrintInstanceNameToString);
Josh Wu049e2cd2022-01-12 05:42:58 -08003647
Alice Kuoadcceec2022-03-28 13:28:43 +08003648GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3649 BluetoothAudioProviderA2dpDecodingSoftwareAidl);
3650INSTANTIATE_TEST_SUITE_P(PerInstance,
3651 BluetoothAudioProviderA2dpDecodingSoftwareAidl,
3652 testing::ValuesIn(android::getAidlHalInstanceNames(
3653 IBluetoothAudioProviderFactory::descriptor)),
3654 android::PrintInstanceNameToString);
3655
3656GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3657 BluetoothAudioProviderA2dpDecodingHardwareAidl);
3658INSTANTIATE_TEST_SUITE_P(PerInstance,
3659 BluetoothAudioProviderA2dpDecodingHardwareAidl,
3660 testing::ValuesIn(android::getAidlHalInstanceNames(
3661 IBluetoothAudioProviderFactory::descriptor)),
3662 android::PrintInstanceNameToString);
3663
Bao Do72399432023-11-09 08:13:05 +00003664GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3665 BluetoothAudioProviderHfpHardwareAidl);
3666INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderHfpHardwareAidl,
3667 testing::ValuesIn(android::getAidlHalInstanceNames(
3668 IBluetoothAudioProviderFactory::descriptor)),
3669 android::PrintInstanceNameToString);
3670
3671GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3672 BluetoothAudioProviderHfpSoftwareDecodingAidl);
3673INSTANTIATE_TEST_SUITE_P(PerInstance,
3674 BluetoothAudioProviderHfpSoftwareDecodingAidl,
3675 testing::ValuesIn(android::getAidlHalInstanceNames(
3676 IBluetoothAudioProviderFactory::descriptor)),
3677 android::PrintInstanceNameToString);
3678
3679GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3680 BluetoothAudioProviderHfpSoftwareEncodingAidl);
3681INSTANTIATE_TEST_SUITE_P(PerInstance,
3682 BluetoothAudioProviderHfpSoftwareEncodingAidl,
3683 testing::ValuesIn(android::getAidlHalInstanceNames(
3684 IBluetoothAudioProviderFactory::descriptor)),
3685 android::PrintInstanceNameToString);
3686
Josh Wu049e2cd2022-01-12 05:42:58 -08003687int main(int argc, char** argv) {
3688 ::testing::InitGoogleTest(&argc, argv);
3689 ABinderProcess_setThreadPoolMaxThreadCount(1);
3690 ABinderProcess_startThreadPool();
3691 return RUN_ALL_TESTS();
3692}