blob: 789e8a126862f45ac288ece2a52c6c6427068dec [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 Do72399432023-11-09 08:13:05 +00001947 OpenProviderHelper(SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH);
1948 // Can open or empty capability
1949 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
1950 audio_provider_ != nullptr);
1951 }
1952
1953 virtual void TearDown() override {
1954 audio_port_ = nullptr;
1955 audio_provider_ = nullptr;
1956 BluetoothAudioProviderFactoryAidl::TearDown();
1957 }
1958
1959 bool OpenSession(CodecId codec_id, int connection_handle, bool nrec,
Bao Do5b2fdab2023-11-20 08:02:55 +00001960 bool controller_codec) {
Bao Do72399432023-11-09 08:13:05 +00001961 // Check if can open session with a Hfp configuration
1962 HfpConfiguration hfp_configuration{
1963 .codecId = codec_id,
1964 .connectionHandle = connection_handle,
1965 .nrec = nrec,
1966 .controllerCodec = controller_codec,
1967 };
1968 DataMQDesc mq_desc;
1969 auto aidl_retval = audio_provider_->startSession(
1970 audio_port_, AudioConfiguration(hfp_configuration), latency_modes,
1971 &mq_desc);
1972
1973 // Only check if aidl is ok to start session.
1974 return aidl_retval.isOk();
1975 }
1976};
1977
1978/**
1979 * Test whether we can open a provider of type
1980 */
1981TEST_P(BluetoothAudioProviderHfpHardwareAidl, OpenHfpHardwareProvider) {}
1982
1983/**
1984 * Test whether each provider of type
1985 * SessionType::HFP_SOFTWARE_DECODING_DATAPATH can be started and stopped with
1986 * different HFP config
1987 */
1988TEST_P(BluetoothAudioProviderHfpHardwareAidl,
1989 StartAndEndHfpHardwareSessionWithPossiblePcmConfig) {
1990 // Try to open with a sample configuration
1991 EXPECT_TRUE(OpenSession(CodecId::Core::CVSD, 6, false, true));
1992 EXPECT_TRUE(audio_provider_->endSession().isOk());
1993}
1994
1995/**
Josh Wu049e2cd2022-01-12 05:42:58 -08001996 * openProvider HEARING_AID_SOFTWARE_ENCODING_DATAPATH
1997 */
1998class BluetoothAudioProviderHearingAidSoftwareAidl
1999 : public BluetoothAudioProviderFactoryAidl {
2000 public:
2001 virtual void SetUp() override {
2002 BluetoothAudioProviderFactoryAidl::SetUp();
2003 GetProviderCapabilitiesHelper(
2004 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
2005 OpenProviderHelper(SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
2006 ASSERT_NE(audio_provider_, nullptr);
2007 }
2008
2009 virtual void TearDown() override {
2010 audio_port_ = nullptr;
2011 audio_provider_ = nullptr;
2012 BluetoothAudioProviderFactoryAidl::TearDown();
2013 }
2014
2015 static constexpr int32_t hearing_aid_sample_rates_[] = {0, 16000, 24000};
2016 static constexpr int8_t hearing_aid_bits_per_samples_[] = {0, 16, 24};
2017 static constexpr ChannelMode hearing_aid_channel_modes_[] = {
2018 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
2019};
2020
2021/**
2022 * Test whether we can open a provider of type
2023 */
2024TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl,
2025 OpenHearingAidSoftwareProvider) {}
2026
2027/**
2028 * Test whether each provider of type
2029 * SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH can be started and
2030 * stopped with different PCM config
2031 */
2032TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl,
2033 StartAndEndHearingAidSessionWithPossiblePcmConfig) {
2034 for (int32_t sample_rate : hearing_aid_sample_rates_) {
2035 for (int8_t bits_per_sample : hearing_aid_bits_per_samples_) {
2036 for (auto channel_mode : hearing_aid_channel_modes_) {
2037 PcmConfiguration pcm_config{
2038 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08002039 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00002040 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08002041 };
2042 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
2043 DataMQDesc mq_desc;
2044 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002045 audio_port_, AudioConfiguration(pcm_config), latency_modes,
2046 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002047 DataMQ data_mq(mq_desc);
2048
2049 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
2050 if (is_codec_config_valid) {
2051 EXPECT_TRUE(data_mq.isValid());
2052 }
2053 EXPECT_TRUE(audio_provider_->endSession().isOk());
2054 }
2055 }
2056 }
2057}
2058
2059/**
2060 * openProvider LE_AUDIO_SOFTWARE_ENCODING_DATAPATH
2061 */
2062class BluetoothAudioProviderLeAudioOutputSoftwareAidl
2063 : public BluetoothAudioProviderFactoryAidl {
2064 public:
2065 virtual void SetUp() override {
2066 BluetoothAudioProviderFactoryAidl::SetUp();
2067 GetProviderCapabilitiesHelper(
2068 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
2069 OpenProviderHelper(SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
2070 ASSERT_NE(audio_provider_, nullptr);
2071 }
2072
2073 virtual void TearDown() override {
2074 audio_port_ = nullptr;
2075 audio_provider_ = nullptr;
2076 BluetoothAudioProviderFactoryAidl::TearDown();
2077 }
2078
2079 static constexpr int32_t le_audio_output_sample_rates_[] = {
2080 0, 8000, 16000, 24000, 32000, 44100, 48000,
2081 };
2082 static constexpr int8_t le_audio_output_bits_per_samples_[] = {0, 16, 24};
2083 static constexpr ChannelMode le_audio_output_channel_modes_[] = {
2084 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
2085 static constexpr int32_t le_audio_output_data_interval_us_[] = {
2086 0 /* Invalid */, 10000 /* Valid 10ms */};
2087};
2088
2089/**
2090 * Test whether each provider of type
2091 * SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH can be started and
2092 * stopped
2093 */
2094TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl,
2095 OpenLeAudioOutputSoftwareProvider) {}
2096
2097/**
2098 * Test whether each provider of type
2099 * SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH can be started and
2100 * stopped with different PCM config
2101 */
2102TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl,
2103 StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
2104 for (auto sample_rate : le_audio_output_sample_rates_) {
2105 for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
2106 for (auto channel_mode : le_audio_output_channel_modes_) {
2107 for (auto data_interval_us : le_audio_output_data_interval_us_) {
2108 PcmConfiguration pcm_config{
2109 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08002110 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00002111 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08002112 .dataIntervalUs = data_interval_us,
2113 };
Josh Wu8a1be762022-02-15 09:37:29 -08002114 bool is_codec_config_valid =
2115 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
Josh Wu049e2cd2022-01-12 05:42:58 -08002116 DataMQDesc mq_desc;
2117 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002118 audio_port_, AudioConfiguration(pcm_config), latency_modes,
2119 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002120 DataMQ data_mq(mq_desc);
2121
2122 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
2123 if (is_codec_config_valid) {
2124 EXPECT_TRUE(data_mq.isValid());
2125 }
2126 EXPECT_TRUE(audio_provider_->endSession().isOk());
2127 }
2128 }
2129 }
2130 }
2131}
2132
2133/**
Alice Kuo04a399a2022-02-16 09:19:56 +08002134 * openProvider LE_AUDIO_SOFTWARE_DECODING_DATAPATH
Josh Wu049e2cd2022-01-12 05:42:58 -08002135 */
2136class BluetoothAudioProviderLeAudioInputSoftwareAidl
2137 : public BluetoothAudioProviderFactoryAidl {
2138 public:
2139 virtual void SetUp() override {
2140 BluetoothAudioProviderFactoryAidl::SetUp();
2141 GetProviderCapabilitiesHelper(
2142 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH);
2143 OpenProviderHelper(SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH);
2144 ASSERT_NE(audio_provider_, nullptr);
2145 }
2146
2147 virtual void TearDown() override {
2148 audio_port_ = nullptr;
2149 audio_provider_ = nullptr;
2150 BluetoothAudioProviderFactoryAidl::TearDown();
2151 }
2152
2153 static constexpr int32_t le_audio_input_sample_rates_[] = {
2154 0, 8000, 16000, 24000, 32000, 44100, 48000};
2155 static constexpr int8_t le_audio_input_bits_per_samples_[] = {0, 16, 24};
2156 static constexpr ChannelMode le_audio_input_channel_modes_[] = {
2157 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
2158 static constexpr int32_t le_audio_input_data_interval_us_[] = {
2159 0 /* Invalid */, 10000 /* Valid 10ms */};
2160};
2161
2162/**
2163 * Test whether each provider of type
Alice Kuo04a399a2022-02-16 09:19:56 +08002164 * SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002165 * stopped
2166 */
2167TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl,
2168 OpenLeAudioInputSoftwareProvider) {}
2169
2170/**
2171 * Test whether each provider of type
Alice Kuo04a399a2022-02-16 09:19:56 +08002172 * SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002173 * stopped with different PCM config
2174 */
2175TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl,
2176 StartAndEndLeAudioInputSessionWithPossiblePcmConfig) {
2177 for (auto sample_rate : le_audio_input_sample_rates_) {
2178 for (auto bits_per_sample : le_audio_input_bits_per_samples_) {
2179 for (auto channel_mode : le_audio_input_channel_modes_) {
2180 for (auto data_interval_us : le_audio_input_data_interval_us_) {
2181 PcmConfiguration pcm_config{
2182 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08002183 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00002184 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08002185 .dataIntervalUs = data_interval_us,
2186 };
Josh Wu8a1be762022-02-15 09:37:29 -08002187 bool is_codec_config_valid =
2188 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
Josh Wu049e2cd2022-01-12 05:42:58 -08002189 DataMQDesc mq_desc;
2190 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002191 audio_port_, AudioConfiguration(pcm_config), latency_modes,
2192 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002193 DataMQ data_mq(mq_desc);
2194
2195 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
2196 if (is_codec_config_valid) {
2197 EXPECT_TRUE(data_mq.isValid());
2198 }
2199 EXPECT_TRUE(audio_provider_->endSession().isOk());
2200 }
2201 }
2202 }
2203 }
2204}
2205
2206/**
Alice Kuo04a399a2022-02-16 09:19:56 +08002207 * openProvider LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH
Josh Wu049e2cd2022-01-12 05:42:58 -08002208 */
2209class BluetoothAudioProviderLeAudioOutputHardwareAidl
2210 : public BluetoothAudioProviderFactoryAidl {
2211 public:
2212 virtual void SetUp() override {
2213 BluetoothAudioProviderFactoryAidl::SetUp();
2214 GetProviderCapabilitiesHelper(
2215 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
Bao Doc36897d2023-12-06 01:27:54 +00002216 GetProviderInfoHelper(
2217 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
Josh Wu049e2cd2022-01-12 05:42:58 -08002218 OpenProviderHelper(
2219 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
2220 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
2221 audio_provider_ != nullptr);
2222 }
2223
2224 virtual void TearDown() override {
2225 audio_port_ = nullptr;
2226 audio_provider_ = nullptr;
2227 BluetoothAudioProviderFactoryAidl::TearDown();
2228 }
2229
2230 bool IsOffloadOutputSupported() {
2231 for (auto& capability : temp_provider_capabilities_) {
2232 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2233 continue;
2234 }
2235 auto& le_audio_capability =
2236 capability.get<AudioCapabilities::leAudioCapabilities>();
2237 if (le_audio_capability.unicastEncodeCapability.codecType !=
2238 CodecType::UNKNOWN)
2239 return true;
2240 }
2241 return false;
2242 }
2243
Bao Doc36897d2023-12-06 01:27:54 +00002244 bool IsOffloadOutputProviderInfoSupported() {
2245 if (!temp_provider_info_.has_value()) return false;
2246 if (temp_provider_info_.value().codecInfos.empty()) return false;
2247 // Check if all codec info is of LeAudio type
2248 for (auto& codec_info : temp_provider_info_.value().codecInfos) {
2249 if (codec_info.transport.getTag() != CodecInfo::Transport::leAudio)
2250 return false;
2251 }
2252 return true;
2253 }
2254
2255 std::vector<Lc3Configuration> GetUnicastLc3SupportedListFromProviderInfo() {
2256 std::vector<Lc3Configuration> le_audio_codec_configs;
2257 for (auto& codec_info : temp_provider_info_.value().codecInfos) {
2258 // Only gets LC3 codec information
2259 if (codec_info.id != CodecId::Core::LC3) continue;
2260 // Combine those parameters into one list of Lc3Configuration
2261 auto& transport =
2262 codec_info.transport.get<CodecInfo::Transport::Tag::leAudio>();
2263 for (int32_t samplingFrequencyHz : transport.samplingFrequencyHz) {
2264 for (int32_t frameDurationUs : transport.frameDurationUs) {
2265 for (int32_t octetsPerFrame : transport.bitdepth) {
2266 Lc3Configuration lc3_config = {
2267 .samplingFrequencyHz = samplingFrequencyHz,
2268 .frameDurationUs = frameDurationUs,
2269 .octetsPerFrame = octetsPerFrame,
2270 };
2271 le_audio_codec_configs.push_back(lc3_config);
2272 }
2273 }
2274 }
2275 }
2276
2277 return le_audio_codec_configs;
2278 }
2279
2280 AudioContext GetAudioContext(int32_t bitmask) {
2281 AudioContext media_audio_context;
2282 media_audio_context.bitmask = bitmask;
2283 return media_audio_context;
2284 }
2285
2286 LeAudioDeviceCapabilities GetDefaultRemoteCapability() {
2287 // Create a capability
2288 LeAudioDeviceCapabilities capability;
2289
2290 capability.codecId = CodecId::Core::LC3;
2291
2292 auto pref_context_metadata = MetadataLtv::PreferredAudioContexts();
2293 pref_context_metadata.values = GetAudioContext(AudioContext::MEDIA);
2294 capability.metadata = {pref_context_metadata};
2295
2296 auto sampling_rate =
2297 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies();
2298 sampling_rate.bitmask =
2299 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ8000;
2300 auto frame_duration =
2301 CodecSpecificCapabilitiesLtv::SupportedFrameDurations();
2302 frame_duration.bitmask =
2303 CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US7500;
2304 auto octets = CodecSpecificCapabilitiesLtv::SupportedOctetsPerCodecFrame();
Jakub Tyszkowski1d214222024-01-16 09:44:48 +00002305 octets.min = 0;
2306 octets.max = 60;
Bao Doc36897d2023-12-06 01:27:54 +00002307 auto frames = CodecSpecificCapabilitiesLtv::SupportedMaxCodecFramesPerSDU();
2308 frames.value = 2;
2309 capability.codecSpecificCapabilities = {sampling_rate, frame_duration,
2310 octets, frames};
2311 return capability;
2312 }
2313
2314 LeAudioConfigurationRequirement GetDefaultRequirement(
2315 bool is_source_requriement) {
2316 // Create a requirements
2317 LeAudioConfigurationRequirement requirement;
2318 requirement.audioContext = GetAudioContext(AudioContext::MEDIA);
2319
2320 auto direction_ase_requriement = AseDirectionRequirement();
2321 direction_ase_requriement.aseConfiguration.codecId = CodecId::Core::LC3;
2322 direction_ase_requriement.aseConfiguration.targetLatency =
2323 LeAudioAseConfiguration::TargetLatency::BALANCED_LATENCY_RELIABILITY;
2324
2325 // Mismatch sampling frequency
2326 direction_ase_requriement.aseConfiguration.codecConfiguration = {
2327 CodecSpecificConfigurationLtv::SamplingFrequency::HZ11025,
2328 CodecSpecificConfigurationLtv::FrameDuration::US7500,
2329 };
2330 if (is_source_requriement)
2331 requirement.sourceAseRequirement = {direction_ase_requriement};
2332 else
2333 requirement.sinkAseRequirement = {direction_ase_requriement};
2334 return requirement;
2335 }
2336
Josh Wu049e2cd2022-01-12 05:42:58 -08002337 std::vector<Lc3Configuration> GetUnicastLc3SupportedList(bool decoding,
2338 bool supported) {
2339 std::vector<Lc3Configuration> le_audio_codec_configs;
2340 if (!supported) {
shihchienc3ab9f5e2022-09-23 08:18:05 +00002341 Lc3Configuration lc3_config{.pcmBitDepth = 0, .samplingFrequencyHz = 0};
Josh Wu049e2cd2022-01-12 05:42:58 -08002342 le_audio_codec_configs.push_back(lc3_config);
2343 return le_audio_codec_configs;
2344 }
2345
2346 // There might be more than one LeAudioCodecCapabilitiesSetting
2347 std::vector<Lc3Capabilities> lc3_capabilities;
2348 for (auto& capability : temp_provider_capabilities_) {
2349 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2350 continue;
2351 }
2352 auto& le_audio_capability =
2353 capability.get<AudioCapabilities::leAudioCapabilities>();
2354 auto& unicast_capability =
2355 decoding ? le_audio_capability.unicastDecodeCapability
2356 : le_audio_capability.unicastEncodeCapability;
2357 if (unicast_capability.codecType != CodecType::LC3) {
2358 continue;
2359 }
2360 auto& lc3_capability = unicast_capability.leAudioCodecCapabilities.get<
2361 UnicastCapability::LeAudioCodecCapabilities::lc3Capabilities>();
2362 lc3_capabilities.push_back(lc3_capability);
2363 }
2364
2365 // Combine those parameters into one list of LeAudioCodecConfiguration
2366 // This seems horrible, but usually each Lc3Capability only contains a
2367 // single Lc3Configuration, which means every array has a length of 1.
2368 for (auto& lc3_capability : lc3_capabilities) {
2369 for (int32_t samplingFrequencyHz : lc3_capability.samplingFrequencyHz) {
2370 for (int32_t frameDurationUs : lc3_capability.frameDurationUs) {
2371 for (int32_t octetsPerFrame : lc3_capability.octetsPerFrame) {
2372 Lc3Configuration lc3_config = {
2373 .samplingFrequencyHz = samplingFrequencyHz,
2374 .frameDurationUs = frameDurationUs,
2375 .octetsPerFrame = octetsPerFrame,
2376 };
2377 le_audio_codec_configs.push_back(lc3_config);
2378 }
2379 }
2380 }
2381 }
2382
2383 return le_audio_codec_configs;
2384 }
2385
Sagar Verma62df9102022-12-07 17:56:04 +05302386 static constexpr int32_t apx_adaptive_le_config_codec_modes[] = {0, 1, 2, 3};
2387
2388 std::vector<AptxAdaptiveLeConfiguration>
2389 GetUnicastAptxAdaptiveLeSupportedList(bool decoding, bool supported,
2390 bool is_le_extended) {
2391 std::vector<AptxAdaptiveLeConfiguration> le_audio_codec_configs;
2392 if (!supported) {
2393 AptxAdaptiveLeConfiguration aptx_adaptive_le_config{
2394 .pcmBitDepth = 0, .samplingFrequencyHz = 0};
2395 le_audio_codec_configs.push_back(aptx_adaptive_le_config);
2396 return le_audio_codec_configs;
2397 }
2398
2399 // There might be more than one LeAudioCodecCapabilitiesSetting
2400 std::vector<AptxAdaptiveLeCapabilities> aptx_adaptive_le_capabilities;
2401 for (auto& capability : temp_provider_capabilities_) {
2402 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2403 continue;
2404 }
2405 auto& le_audio_capability =
2406 capability.get<AudioCapabilities::leAudioCapabilities>();
2407 auto& unicast_capability =
2408 decoding ? le_audio_capability.unicastDecodeCapability
2409 : le_audio_capability.unicastEncodeCapability;
2410 if ((!is_le_extended &&
2411 unicast_capability.codecType != CodecType::APTX_ADAPTIVE_LE) ||
2412 (is_le_extended &&
2413 unicast_capability.codecType != CodecType::APTX_ADAPTIVE_LEX)) {
2414 continue;
2415 }
2416
2417 auto& aptx_adaptive_le_capability =
2418 unicast_capability.leAudioCodecCapabilities
2419 .get<UnicastCapability::LeAudioCodecCapabilities::
2420 aptxAdaptiveLeCapabilities>();
2421
2422 aptx_adaptive_le_capabilities.push_back(aptx_adaptive_le_capability);
2423 }
2424
2425 for (auto& aptx_adaptive_le_capability : aptx_adaptive_le_capabilities) {
2426 for (int32_t samplingFrequencyHz :
2427 aptx_adaptive_le_capability.samplingFrequencyHz) {
2428 for (int32_t frameDurationUs :
2429 aptx_adaptive_le_capability.frameDurationUs) {
2430 for (int32_t octetsPerFrame :
2431 aptx_adaptive_le_capability.octetsPerFrame) {
2432 for (int8_t blocksPerSdu :
2433 aptx_adaptive_le_capability.blocksPerSdu) {
2434 for (int32_t codecMode : apx_adaptive_le_config_codec_modes) {
2435 AptxAdaptiveLeConfiguration aptx_adaptive_le_config = {
2436 .samplingFrequencyHz = samplingFrequencyHz,
2437 .frameDurationUs = frameDurationUs,
2438 .octetsPerFrame = octetsPerFrame,
2439 .blocksPerSdu = blocksPerSdu,
2440 .codecMode = codecMode,
2441 };
2442 le_audio_codec_configs.push_back(aptx_adaptive_le_config);
2443 }
2444 }
2445 }
2446 }
2447 }
2448 }
2449
2450 return le_audio_codec_configs;
2451 }
2452
Josh Wu049e2cd2022-01-12 05:42:58 -08002453 LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
Bao Doc36897d2023-12-06 01:27:54 +00002454 std::vector<int32_t> all_context_bitmasks = {
2455 AudioContext::UNSPECIFIED, AudioContext::CONVERSATIONAL,
2456 AudioContext::MEDIA, AudioContext::GAME,
2457 AudioContext::INSTRUCTIONAL, AudioContext::VOICE_ASSISTANTS,
2458 AudioContext::LIVE_AUDIO, AudioContext::SOUND_EFFECTS,
2459 AudioContext::NOTIFICATIONS, AudioContext::RINGTONE_ALERTS,
2460 AudioContext::ALERTS, AudioContext::EMERGENCY_ALARM,
2461 };
Josh Wu049e2cd2022-01-12 05:42:58 -08002462};
2463
2464/**
2465 * Test whether each provider of type
2466 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2467 * stopped
2468 */
2469TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2470 OpenLeAudioOutputHardwareProvider) {}
2471
2472/**
2473 * Test whether each provider of type
2474 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
Bao Doc36897d2023-12-06 01:27:54 +00002475 * stopped with Unicast hardware encoding config taken from provider info
2476 */
2477TEST_P(
2478 BluetoothAudioProviderLeAudioOutputHardwareAidl,
2479 StartAndEndLeAudioOutputSessionWithPossibleUnicastConfigFromProviderInfo) {
Bao Dob487a852023-12-25 10:12:09 +08002480 if (GetProviderFactoryInterfaceVersion() <
2481 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
2482 GTEST_SKIP();
2483 }
Bao Doc36897d2023-12-06 01:27:54 +00002484 if (!IsOffloadOutputProviderInfoSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002485 GTEST_SKIP();
Bao Doc36897d2023-12-06 01:27:54 +00002486 }
2487
2488 auto lc3_codec_configs = GetUnicastLc3SupportedListFromProviderInfo();
2489 LeAudioConfiguration le_audio_config = {
2490 .codecType = CodecType::LC3,
2491 .peerDelayUs = 0,
2492 };
2493
2494 for (auto& lc3_config : lc3_codec_configs) {
2495 le_audio_config.leAudioCodecConfig
2496 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2497 DataMQDesc mq_desc;
2498 auto aidl_retval = audio_provider_->startSession(
2499 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2500 &mq_desc);
2501
2502 ASSERT_TRUE(aidl_retval.isOk());
2503 EXPECT_TRUE(audio_provider_->endSession().isOk());
2504 }
2505}
2506
2507TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2508 GetEmptyAseConfigurationEmptyCapability) {
Bao Dob487a852023-12-25 10:12:09 +08002509 if (GetProviderFactoryInterfaceVersion() <
2510 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
2511 GTEST_SKIP();
2512 }
Bao Doc36897d2023-12-06 01:27:54 +00002513 std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
2514 std::vector<LeAudioConfigurationRequirement> empty_requirement;
2515 std::vector<LeAudioAseConfigurationSetting> configurations;
2516
2517 // Check empty capability for source direction
2518 auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
2519 std::nullopt, empty_capability, empty_requirement, &configurations);
2520
2521 ASSERT_TRUE(aidl_retval.isOk());
2522 ASSERT_TRUE(configurations.empty());
2523
2524 // Check empty capability for sink direction
2525 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
2526 empty_capability, std::nullopt, empty_requirement, &configurations);
2527
2528 ASSERT_TRUE(aidl_retval.isOk());
2529 ASSERT_TRUE(configurations.empty());
2530}
2531
2532TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2533 GetEmptyAseConfigurationMismatchedRequirement) {
Bao Dob487a852023-12-25 10:12:09 +08002534 if (GetProviderFactoryInterfaceVersion() <
2535 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
2536 GTEST_SKIP();
2537 }
Bao Doc36897d2023-12-06 01:27:54 +00002538 std::vector<std::optional<LeAudioDeviceCapabilities>> capabilities = {
2539 GetDefaultRemoteCapability()};
2540
2541 // Check empty capability for source direction
2542 std::vector<LeAudioAseConfigurationSetting> configurations;
2543 std::vector<LeAudioConfigurationRequirement> source_requirements = {
2544 GetDefaultRequirement(true)};
2545 auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
2546 std::nullopt, capabilities, source_requirements, &configurations);
2547
2548 ASSERT_TRUE(aidl_retval.isOk());
2549 ASSERT_TRUE(configurations.empty());
2550
2551 // Check empty capability for sink direction
2552 std::vector<LeAudioConfigurationRequirement> sink_requirements = {
2553 GetDefaultRequirement(false)};
2554 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
2555 capabilities, std::nullopt, source_requirements, &configurations);
2556
2557 ASSERT_TRUE(aidl_retval.isOk());
2558 ASSERT_TRUE(configurations.empty());
2559}
2560
2561TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl, GetQoSConfiguration) {
Bao Dob487a852023-12-25 10:12:09 +08002562 if (GetProviderFactoryInterfaceVersion() <
2563 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
2564 GTEST_SKIP();
2565 }
Bao Doc36897d2023-12-06 01:27:54 +00002566 IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement requirement;
2567 std::vector<IBluetoothAudioProvider::LeAudioAseQosConfiguration>
2568 QoSConfigurations;
2569 for (auto bitmask : all_context_bitmasks) {
Jakub Tyszkowski1d214222024-01-16 09:44:48 +00002570 requirement.audioContext = GetAudioContext(bitmask);
Bao Doc36897d2023-12-06 01:27:54 +00002571 IBluetoothAudioProvider::LeAudioAseQosConfigurationPair result;
2572 auto aidl_retval =
2573 audio_provider_->getLeAudioAseQosConfiguration(requirement, &result);
2574 ASSERT_TRUE(aidl_retval.isOk());
2575 if (result.sinkQosConfiguration.has_value())
2576 QoSConfigurations.push_back(result.sinkQosConfiguration.value());
2577 if (result.sourceQosConfiguration.has_value())
2578 QoSConfigurations.push_back(result.sourceQosConfiguration.value());
2579 }
2580 // QoS Configurations should not be empty, as we searched for all contexts
2581 ASSERT_FALSE(QoSConfigurations.empty());
2582}
Jakub Tyszkowskic8a62242024-01-05 15:25:49 +00002583
2584TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2585 GetDataPathConfiguration) {
Jakub Tyszkowskie77f8722024-01-29 13:21:21 +00002586 if (GetProviderFactoryInterfaceVersion() <
2587 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
2588 GTEST_SKIP();
2589 }
Jakub Tyszkowskic8a62242024-01-05 15:25:49 +00002590 IBluetoothAudioProvider::StreamConfig sink_requirement;
2591 IBluetoothAudioProvider::StreamConfig source_requirement;
2592 std::vector<IBluetoothAudioProvider::LeAudioDataPathConfiguration>
2593 DataPathConfigurations;
2594 bool is_supported = false;
2595
2596 for (auto bitmask : all_context_bitmasks) {
Jakub Tyszkowski1d214222024-01-16 09:44:48 +00002597 sink_requirement.audioContext = GetAudioContext(bitmask);
2598 source_requirement.audioContext = GetAudioContext(bitmask);
Jakub Tyszkowskic8a62242024-01-05 15:25:49 +00002599 IBluetoothAudioProvider::LeAudioDataPathConfigurationPair result;
2600 auto aidl_retval = audio_provider_->getLeAudioAseDatapathConfiguration(
2601 sink_requirement, source_requirement, &result);
2602 if (!aidl_retval.isOk()) {
2603 // If not OK, then it could be not supported, as it is an optional feature
2604 ASSERT_EQ(aidl_retval.getExceptionCode(), EX_UNSUPPORTED_OPERATION);
2605 } else {
2606 is_supported = true;
2607 if (result.inputConfig.has_value())
2608 DataPathConfigurations.push_back(result.inputConfig.value());
2609 if (result.inputConfig.has_value())
2610 DataPathConfigurations.push_back(result.inputConfig.value());
2611 }
2612 }
2613
2614 if (is_supported) {
2615 // Datapath Configurations should not be empty, as we searched for all
2616 // contexts
2617 ASSERT_FALSE(DataPathConfigurations.empty());
2618 }
2619}
2620
Bao Doc36897d2023-12-06 01:27:54 +00002621/**
2622 * Test whether each provider of type
2623 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002624 * stopped with Unicast hardware encoding config
2625 */
2626TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2627 StartAndEndLeAudioOutputSessionWithPossibleUnicastConfig) {
2628 if (!IsOffloadOutputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002629 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08002630 }
2631
2632 auto lc3_codec_configs =
2633 GetUnicastLc3SupportedList(false /* decoding */, true /* supported */);
2634 LeAudioConfiguration le_audio_config = {
2635 .codecType = CodecType::LC3,
2636 .peerDelayUs = 0,
2637 };
2638
2639 for (auto& lc3_config : lc3_codec_configs) {
2640 le_audio_config.leAudioCodecConfig
2641 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2642 DataMQDesc mq_desc;
2643 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002644 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2645 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002646
2647 ASSERT_TRUE(aidl_retval.isOk());
2648 EXPECT_TRUE(audio_provider_->endSession().isOk());
2649 }
2650}
2651
2652/**
2653 * Test whether each provider of type
2654 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2655 * stopped with Unicast hardware encoding config
2656 *
2657 * Disabled since offload codec checking is not ready
2658 */
2659TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2660 DISABLED_StartAndEndLeAudioOutputSessionWithInvalidAudioConfiguration) {
2661 if (!IsOffloadOutputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002662 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08002663 }
2664
2665 auto lc3_codec_configs =
2666 GetUnicastLc3SupportedList(false /* decoding */, false /* supported */);
2667 LeAudioConfiguration le_audio_config = {
2668 .codecType = CodecType::LC3,
2669 .peerDelayUs = 0,
2670 };
2671
2672 for (auto& lc3_config : lc3_codec_configs) {
2673 le_audio_config.leAudioCodecConfig
2674 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2675 DataMQDesc mq_desc;
2676 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002677 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2678 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002679
2680 // AIDL call should fail on invalid codec
2681 ASSERT_FALSE(aidl_retval.isOk());
2682 EXPECT_TRUE(audio_provider_->endSession().isOk());
2683 }
2684}
2685
Sagar Verma62df9102022-12-07 17:56:04 +05302686static std::vector<uint8_t> vendorMetadata = {0x0B, // Length
2687 0xFF, // Type: Vendor-specific
2688 0x0A, 0x00, // Company_ID
2689 0x01, 0x02, 0x03, 0x04, // Data
2690 0x05, 0x06, 0x07, 0x08};
2691
2692/**
2693 * Test whether each provider of type
2694 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2695 * stopped with Unicast hardware encoding config
2696 */
2697TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2698 StartAndEndLeAudioOutputSessionWithAptxAdaptiveLeUnicastConfig) {
2699 if (!IsOffloadOutputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002700 GTEST_SKIP();
Sagar Verma62df9102022-12-07 17:56:04 +05302701 }
2702 for (auto codec_type :
2703 {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
2704 bool is_le_extended = (codec_type == CodecType::APTX_ADAPTIVE_LEX);
2705 auto aptx_adaptive_le_codec_configs =
2706 GetUnicastAptxAdaptiveLeSupportedList(false, true, is_le_extended);
2707 LeAudioConfiguration le_audio_config = {
2708 .codecType = codec_type,
2709 .peerDelayUs = 0,
2710 .vendorSpecificMetadata = vendorMetadata,
2711 };
2712
2713 for (auto& aptx_adaptive_le_config : aptx_adaptive_le_codec_configs) {
2714 le_audio_config.leAudioCodecConfig
2715 .set<LeAudioCodecConfiguration::aptxAdaptiveLeConfig>(
2716 aptx_adaptive_le_config);
2717 DataMQDesc mq_desc;
2718 auto aidl_retval = audio_provider_->startSession(
2719 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2720 &mq_desc);
2721
2722 ASSERT_TRUE(aidl_retval.isOk());
2723 EXPECT_TRUE(audio_provider_->endSession().isOk());
2724 }
2725 }
2726}
2727
2728/**
2729 * Test whether each provider of type
2730 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2731 * stopped with Unicast hardware encoding config
2732 */
2733TEST_P(
2734 BluetoothAudioProviderLeAudioOutputHardwareAidl,
2735 BluetoothAudioProviderLeAudioOutputHardwareAidl_StartAndEndLeAudioOutputSessionWithInvalidAptxAdaptiveLeAudioConfiguration) {
2736 if (!IsOffloadOutputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002737 GTEST_SKIP();
Sagar Verma62df9102022-12-07 17:56:04 +05302738 }
2739
2740 for (auto codec_type :
2741 {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
2742 bool is_le_extended = (codec_type == CodecType::APTX_ADAPTIVE_LEX);
2743 auto aptx_adaptive_le_codec_configs =
2744 GetUnicastAptxAdaptiveLeSupportedList(false, true, is_le_extended);
2745 LeAudioConfiguration le_audio_config = {
2746 .codecType = codec_type,
2747 .peerDelayUs = 0,
2748 .vendorSpecificMetadata = vendorMetadata,
2749 };
2750
2751 for (auto& aptx_adaptive_le_config : aptx_adaptive_le_codec_configs) {
2752 le_audio_config.leAudioCodecConfig
2753 .set<LeAudioCodecConfiguration::aptxAdaptiveLeConfig>(
2754 aptx_adaptive_le_config);
2755 DataMQDesc mq_desc;
2756 auto aidl_retval = audio_provider_->startSession(
2757 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2758 &mq_desc);
2759
2760 // AIDL call should fail on invalid codec
2761 ASSERT_FALSE(aidl_retval.isOk());
2762 EXPECT_TRUE(audio_provider_->endSession().isOk());
2763 }
2764 }
2765}
2766
Josh Wu049e2cd2022-01-12 05:42:58 -08002767/**
2768 * openProvider LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH
2769 */
2770class BluetoothAudioProviderLeAudioInputHardwareAidl
2771 : public BluetoothAudioProviderLeAudioOutputHardwareAidl {
2772 public:
2773 virtual void SetUp() override {
2774 BluetoothAudioProviderFactoryAidl::SetUp();
2775 GetProviderCapabilitiesHelper(
2776 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
Bao Doc36897d2023-12-06 01:27:54 +00002777 GetProviderInfoHelper(
2778 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
Josh Wu049e2cd2022-01-12 05:42:58 -08002779 OpenProviderHelper(
2780 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
2781 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
2782 audio_provider_ != nullptr);
2783 }
2784
2785 bool IsOffloadInputSupported() {
2786 for (auto& capability : temp_provider_capabilities_) {
2787 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2788 continue;
2789 }
2790 auto& le_audio_capability =
2791 capability.get<AudioCapabilities::leAudioCapabilities>();
2792 if (le_audio_capability.unicastDecodeCapability.codecType !=
2793 CodecType::UNKNOWN)
2794 return true;
2795 }
2796 return false;
2797 }
2798
2799 virtual void TearDown() override {
2800 audio_port_ = nullptr;
2801 audio_provider_ = nullptr;
2802 BluetoothAudioProviderFactoryAidl::TearDown();
2803 }
2804};
2805
2806/**
2807 * Test whether each provider of type
Bao Doc36897d2023-12-06 01:27:54 +00002808 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002809 * stopped
2810 */
2811TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
2812 OpenLeAudioInputHardwareProvider) {}
2813
2814/**
2815 * Test whether each provider of type
Bao Doc36897d2023-12-06 01:27:54 +00002816 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
2817 * stopped with Unicast hardware encoding config taken from provider info
2818 */
2819TEST_P(
2820 BluetoothAudioProviderLeAudioInputHardwareAidl,
2821 StartAndEndLeAudioInputSessionWithPossibleUnicastConfigFromProviderInfo) {
2822 if (!IsOffloadOutputProviderInfoSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002823 GTEST_SKIP();
Bao Doc36897d2023-12-06 01:27:54 +00002824 }
2825
2826 auto lc3_codec_configs = GetUnicastLc3SupportedListFromProviderInfo();
2827 LeAudioConfiguration le_audio_config = {
2828 .codecType = CodecType::LC3,
2829 .peerDelayUs = 0,
2830 };
2831
2832 for (auto& lc3_config : lc3_codec_configs) {
2833 le_audio_config.leAudioCodecConfig
2834 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2835 DataMQDesc mq_desc;
2836 auto aidl_retval = audio_provider_->startSession(
2837 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2838 &mq_desc);
2839
2840 ASSERT_TRUE(aidl_retval.isOk());
2841 EXPECT_TRUE(audio_provider_->endSession().isOk());
2842 }
2843}
2844
2845/**
2846 * Test whether each provider of type
2847 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002848 * stopped with Unicast hardware encoding config
2849 */
2850TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
2851 StartAndEndLeAudioInputSessionWithPossibleUnicastConfig) {
2852 if (!IsOffloadInputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002853 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08002854 }
2855
2856 auto lc3_codec_configs =
2857 GetUnicastLc3SupportedList(true /* decoding */, true /* supported */);
2858 LeAudioConfiguration le_audio_config = {
2859 .codecType = CodecType::LC3,
2860 .peerDelayUs = 0,
2861 };
2862
2863 for (auto& lc3_config : lc3_codec_configs) {
2864 le_audio_config.leAudioCodecConfig
2865 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2866 DataMQDesc mq_desc;
2867 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002868 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2869 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002870
2871 ASSERT_TRUE(aidl_retval.isOk());
2872 EXPECT_TRUE(audio_provider_->endSession().isOk());
2873 }
2874}
2875
2876/**
2877 * Test whether each provider of type
Bao Doc36897d2023-12-06 01:27:54 +00002878 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002879 * stopped with Unicast hardware encoding config
2880 *
2881 * Disabled since offload codec checking is not ready
2882 */
2883TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
2884 DISABLED_StartAndEndLeAudioInputSessionWithInvalidAudioConfiguration) {
2885 if (!IsOffloadInputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002886 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08002887 }
2888
2889 auto lc3_codec_configs =
2890 GetUnicastLc3SupportedList(true /* decoding */, false /* supported */);
2891 LeAudioConfiguration le_audio_config = {
2892 .codecType = CodecType::LC3,
2893 .peerDelayUs = 0,
2894 };
2895
2896 for (auto& lc3_config : lc3_codec_configs) {
2897 le_audio_config.leAudioCodecConfig
2898 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2899
2900 DataMQDesc mq_desc;
2901 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002902 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2903 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002904
2905 // AIDL call should fail on invalid codec
2906 ASSERT_FALSE(aidl_retval.isOk());
2907 EXPECT_TRUE(audio_provider_->endSession().isOk());
2908 }
2909}
2910
2911/**
2912 * openProvider LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH
2913 */
2914class BluetoothAudioProviderLeAudioBroadcastSoftwareAidl
2915 : public BluetoothAudioProviderFactoryAidl {
2916 public:
2917 virtual void SetUp() override {
2918 BluetoothAudioProviderFactoryAidl::SetUp();
2919 GetProviderCapabilitiesHelper(
2920 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
2921 OpenProviderHelper(
2922 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
2923 ASSERT_NE(audio_provider_, nullptr);
2924 }
2925
2926 virtual void TearDown() override {
2927 audio_port_ = nullptr;
2928 audio_provider_ = nullptr;
2929 BluetoothAudioProviderFactoryAidl::TearDown();
2930 }
2931
2932 static constexpr int32_t le_audio_output_sample_rates_[] = {
2933 0, 8000, 16000, 24000, 32000, 44100, 48000,
2934 };
2935 static constexpr int8_t le_audio_output_bits_per_samples_[] = {0, 16, 24};
2936 static constexpr ChannelMode le_audio_output_channel_modes_[] = {
2937 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
2938 static constexpr int32_t le_audio_output_data_interval_us_[] = {
2939 0 /* Invalid */, 10000 /* Valid 10ms */};
2940};
2941
2942/**
2943 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08002944 * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started
2945 * and stopped
Josh Wu049e2cd2022-01-12 05:42:58 -08002946 */
2947TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
Josh Wu3202eab2022-02-17 18:09:05 -08002948 OpenLeAudioOutputSoftwareProvider) {}
Josh Wu049e2cd2022-01-12 05:42:58 -08002949
2950/**
2951 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08002952 * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started
2953 * and stopped with different PCM config
Josh Wu049e2cd2022-01-12 05:42:58 -08002954 */
2955TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
Josh Wu3202eab2022-02-17 18:09:05 -08002956 StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
Josh Wu049e2cd2022-01-12 05:42:58 -08002957 for (auto sample_rate : le_audio_output_sample_rates_) {
2958 for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
2959 for (auto channel_mode : le_audio_output_channel_modes_) {
2960 for (auto data_interval_us : le_audio_output_data_interval_us_) {
2961 PcmConfiguration pcm_config{
2962 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08002963 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00002964 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08002965 .dataIntervalUs = data_interval_us,
2966 };
Josh Wu8a1be762022-02-15 09:37:29 -08002967 bool is_codec_config_valid =
2968 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
Josh Wu049e2cd2022-01-12 05:42:58 -08002969 DataMQDesc mq_desc;
2970 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002971 audio_port_, AudioConfiguration(pcm_config), latency_modes,
2972 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002973 DataMQ data_mq(mq_desc);
2974
2975 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
2976 if (is_codec_config_valid) {
2977 EXPECT_TRUE(data_mq.isValid());
2978 }
2979 EXPECT_TRUE(audio_provider_->endSession().isOk());
2980 }
2981 }
2982 }
2983 }
2984}
2985
Alice Kuo336d90c2022-02-16 09:09:59 +08002986/**
2987 * openProvider LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH
2988 */
2989class BluetoothAudioProviderLeAudioBroadcastHardwareAidl
2990 : public BluetoothAudioProviderFactoryAidl {
2991 public:
2992 virtual void SetUp() override {
2993 BluetoothAudioProviderFactoryAidl::SetUp();
2994 GetProviderCapabilitiesHelper(
2995 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
Bao Doc36897d2023-12-06 01:27:54 +00002996 GetProviderInfoHelper(
2997 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
Alice Kuo336d90c2022-02-16 09:09:59 +08002998 OpenProviderHelper(
2999 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
3000 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
3001 audio_provider_ != nullptr);
3002 }
3003
3004 virtual void TearDown() override {
3005 audio_port_ = nullptr;
3006 audio_provider_ = nullptr;
3007 BluetoothAudioProviderFactoryAidl::TearDown();
3008 }
3009
3010 bool IsBroadcastOffloadSupported() {
3011 for (auto& capability : temp_provider_capabilities_) {
3012 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
3013 continue;
3014 }
3015 auto& le_audio_capability =
3016 capability.get<AudioCapabilities::leAudioCapabilities>();
3017 if (le_audio_capability.broadcastCapability.codecType !=
3018 CodecType::UNKNOWN)
3019 return true;
3020 }
3021 return false;
3022 }
3023
Bao Doc36897d2023-12-06 01:27:54 +00003024 bool IsBroadcastOffloadProviderInfoSupported() {
3025 if (!temp_provider_info_.has_value()) return false;
3026 if (temp_provider_info_.value().codecInfos.empty()) return false;
3027 // Check if all codec info is of LeAudio type
3028 for (auto& codec_info : temp_provider_info_.value().codecInfos) {
3029 if (codec_info.transport.getTag() != CodecInfo::Transport::leAudio)
3030 return false;
3031 }
3032 return true;
3033 }
3034
3035 std::vector<Lc3Configuration> GetBroadcastLc3SupportedListFromProviderInfo() {
3036 std::vector<Lc3Configuration> le_audio_codec_configs;
3037 for (auto& codec_info : temp_provider_info_.value().codecInfos) {
3038 // Only gets LC3 codec information
3039 if (codec_info.id != CodecId::Core::LC3) continue;
3040 // Combine those parameters into one list of Lc3Configuration
3041 auto& transport =
3042 codec_info.transport.get<CodecInfo::Transport::Tag::leAudio>();
3043 for (int32_t samplingFrequencyHz : transport.samplingFrequencyHz) {
3044 for (int32_t frameDurationUs : transport.frameDurationUs) {
3045 for (int32_t octetsPerFrame : transport.bitdepth) {
3046 Lc3Configuration lc3_config = {
3047 .samplingFrequencyHz = samplingFrequencyHz,
3048 .frameDurationUs = frameDurationUs,
3049 .octetsPerFrame = octetsPerFrame,
3050 };
3051 le_audio_codec_configs.push_back(lc3_config);
3052 }
3053 }
3054 }
3055 }
3056
3057 return le_audio_codec_configs;
3058 }
3059
Alice Kuo336d90c2022-02-16 09:09:59 +08003060 std::vector<Lc3Configuration> GetBroadcastLc3SupportedList(bool supported) {
3061 std::vector<Lc3Configuration> le_audio_codec_configs;
3062 if (!supported) {
shihchienc3ab9f5e2022-09-23 08:18:05 +00003063 Lc3Configuration lc3_config{.pcmBitDepth = 0, .samplingFrequencyHz = 0};
Alice Kuo336d90c2022-02-16 09:09:59 +08003064 le_audio_codec_configs.push_back(lc3_config);
3065 return le_audio_codec_configs;
3066 }
3067
3068 // There might be more than one LeAudioCodecCapabilitiesSetting
3069 std::vector<Lc3Capabilities> lc3_capabilities;
3070 for (auto& capability : temp_provider_capabilities_) {
3071 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
3072 continue;
3073 }
3074 auto& le_audio_capability =
3075 capability.get<AudioCapabilities::leAudioCapabilities>();
3076 auto& broadcast_capability = le_audio_capability.broadcastCapability;
3077 if (broadcast_capability.codecType != CodecType::LC3) {
3078 continue;
3079 }
3080 auto& lc3_capability = broadcast_capability.leAudioCodecCapabilities.get<
3081 BroadcastCapability::LeAudioCodecCapabilities::lc3Capabilities>();
3082 for (int idx = 0; idx < lc3_capability->size(); idx++)
3083 lc3_capabilities.push_back(*lc3_capability->at(idx));
3084 }
3085
3086 // Combine those parameters into one list of LeAudioCodecConfiguration
3087 // This seems horrible, but usually each Lc3Capability only contains a
3088 // single Lc3Configuration, which means every array has a length of 1.
3089 for (auto& lc3_capability : lc3_capabilities) {
3090 for (int32_t samplingFrequencyHz : lc3_capability.samplingFrequencyHz) {
3091 for (int32_t frameDurationUs : lc3_capability.frameDurationUs) {
3092 for (int32_t octetsPerFrame : lc3_capability.octetsPerFrame) {
3093 Lc3Configuration lc3_config = {
3094 .samplingFrequencyHz = samplingFrequencyHz,
3095 .frameDurationUs = frameDurationUs,
3096 .octetsPerFrame = octetsPerFrame,
3097 };
3098 le_audio_codec_configs.push_back(lc3_config);
3099 }
3100 }
3101 }
3102 }
3103
3104 return le_audio_codec_configs;
3105 }
3106
3107 LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
3108};
3109
3110/**
3111 * Test whether each provider of type
3112 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
3113 * started and stopped
3114 */
3115TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3116 OpenLeAudioOutputHardwareProvider) {}
3117
3118/**
3119 * Test whether each provider of type
3120 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
Bao Doc36897d2023-12-06 01:27:54 +00003121 * started and stopped with broadcast hardware encoding config taken from
3122 * provider info
3123 */
3124TEST_P(
3125 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3126 StartAndEndLeAudioBroadcastSessionWithPossibleUnicastConfigFromProviderInfo) {
Bao Dob487a852023-12-25 10:12:09 +08003127 if (GetProviderFactoryInterfaceVersion() <
3128 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3129 GTEST_SKIP();
3130 }
Bao Doc36897d2023-12-06 01:27:54 +00003131 if (!IsBroadcastOffloadProviderInfoSupported()) {
3132 return;
3133 }
3134
3135 auto lc3_codec_configs = GetBroadcastLc3SupportedListFromProviderInfo();
3136 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
3137 .codecType = CodecType::LC3,
3138 .streamMap = {},
3139 };
3140
3141 for (auto& lc3_config : lc3_codec_configs) {
3142 le_audio_broadcast_config.streamMap.resize(1);
3143 le_audio_broadcast_config.streamMap[0]
3144 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
3145 lc3_config);
3146 le_audio_broadcast_config.streamMap[0].streamHandle = 0x0;
3147 le_audio_broadcast_config.streamMap[0].pcmStreamId = 0x0;
3148 le_audio_broadcast_config.streamMap[0].audioChannelAllocation = 0x1 << 0;
3149
3150 DataMQDesc mq_desc;
3151 auto aidl_retval = audio_provider_->startSession(
3152 audio_port_, AudioConfiguration(le_audio_broadcast_config),
3153 latency_modes, &mq_desc);
3154
3155 ASSERT_TRUE(aidl_retval.isOk());
3156 EXPECT_TRUE(audio_provider_->endSession().isOk());
3157 }
3158}
3159
Bao Do5b2fdab2023-11-20 08:02:55 +00003160TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3161 GetEmptyBroadcastConfigurationEmptyCapability) {
Bao Dob487a852023-12-25 10:12:09 +08003162 if (GetProviderFactoryInterfaceVersion() <
3163 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3164 GTEST_SKIP();
3165 }
Bao Do5b2fdab2023-11-20 08:02:55 +00003166 std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
3167 IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement
3168 empty_requirement;
3169
3170 IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting* configuration =
3171 new IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting();
3172
3173 // Check empty capability for source direction
3174 auto aidl_retval = audio_provider_->getLeAudioBroadcastConfiguration(
3175 empty_capability, empty_requirement, configuration);
3176
3177 ASSERT_TRUE(aidl_retval.isOk());
3178}
3179
Bao Doc36897d2023-12-06 01:27:54 +00003180/**
3181 * Test whether each provider of type
3182 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
Alice Kuo336d90c2022-02-16 09:09:59 +08003183 * started and stopped with broadcast hardware encoding config
3184 */
3185TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3186 StartAndEndLeAudioBroadcastSessionWithPossibleBroadcastConfig) {
3187 if (!IsBroadcastOffloadSupported()) {
3188 return;
3189 }
3190
3191 auto lc3_codec_configs = GetBroadcastLc3SupportedList(true /* supported */);
3192 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
3193 .codecType = CodecType::LC3,
3194 .streamMap = {},
3195 };
3196
3197 for (auto& lc3_config : lc3_codec_configs) {
Patty Huangac077ef2022-11-23 14:45:15 +08003198 le_audio_broadcast_config.streamMap.resize(1);
Alice Kuo336d90c2022-02-16 09:09:59 +08003199 le_audio_broadcast_config.streamMap[0]
3200 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
3201 lc3_config);
Rongxuan Liuc1aea322023-01-26 17:14:54 +00003202 le_audio_broadcast_config.streamMap[0].streamHandle = 0x0;
3203 le_audio_broadcast_config.streamMap[0].pcmStreamId = 0x0;
3204 le_audio_broadcast_config.streamMap[0].audioChannelAllocation = 0x1 << 0;
3205
Alice Kuo336d90c2022-02-16 09:09:59 +08003206 DataMQDesc mq_desc;
3207 auto aidl_retval = audio_provider_->startSession(
Chen Chen60d52e42022-02-16 12:19:12 -08003208 audio_port_, AudioConfiguration(le_audio_broadcast_config),
3209 latency_modes, &mq_desc);
Alice Kuo336d90c2022-02-16 09:09:59 +08003210
3211 ASSERT_TRUE(aidl_retval.isOk());
3212 EXPECT_TRUE(audio_provider_->endSession().isOk());
3213 }
3214}
3215
3216/**
3217 * Test whether each provider of type
3218 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
3219 * started and stopped with Broadcast hardware encoding config
3220 *
3221 * Disabled since offload codec checking is not ready
3222 */
3223TEST_P(
3224 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3225 DISABLED_StartAndEndLeAudioBroadcastSessionWithInvalidAudioConfiguration) {
3226 if (!IsBroadcastOffloadSupported()) {
3227 return;
3228 }
3229
3230 auto lc3_codec_configs = GetBroadcastLc3SupportedList(false /* supported */);
3231 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
3232 .codecType = CodecType::LC3,
3233 .streamMap = {},
3234 };
3235
3236 for (auto& lc3_config : lc3_codec_configs) {
3237 le_audio_broadcast_config.streamMap[0]
3238 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
3239 lc3_config);
3240 DataMQDesc mq_desc;
3241 auto aidl_retval = audio_provider_->startSession(
Chen Chen60d52e42022-02-16 12:19:12 -08003242 audio_port_, AudioConfiguration(le_audio_broadcast_config),
3243 latency_modes, &mq_desc);
Alice Kuo336d90c2022-02-16 09:09:59 +08003244
3245 // AIDL call should fail on invalid codec
3246 ASSERT_FALSE(aidl_retval.isOk());
3247 EXPECT_TRUE(audio_provider_->endSession().isOk());
3248 }
3249}
3250
Alice Kuoadcceec2022-03-28 13:28:43 +08003251/**
3252 * openProvider A2DP_SOFTWARE_DECODING_DATAPATH
3253 */
3254class BluetoothAudioProviderA2dpDecodingSoftwareAidl
3255 : public BluetoothAudioProviderFactoryAidl {
3256 public:
3257 virtual void SetUp() override {
3258 BluetoothAudioProviderFactoryAidl::SetUp();
3259 GetProviderCapabilitiesHelper(SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
3260 OpenProviderHelper(SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
3261 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
3262 audio_provider_ != nullptr);
3263 }
3264
3265 virtual void TearDown() override {
3266 audio_port_ = nullptr;
3267 audio_provider_ = nullptr;
3268 BluetoothAudioProviderFactoryAidl::TearDown();
3269 }
3270};
3271
3272/**
3273 * Test whether we can open a provider of type
3274 */
3275TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,
3276 OpenA2dpDecodingSoftwareProvider) {}
3277
3278/**
3279 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08003280 * SessionType::A2DP_SOFTWARE_DECODING_DATAPATH can be started and stopped
3281 * with different PCM config
Alice Kuoadcceec2022-03-28 13:28:43 +08003282 */
3283TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,
3284 StartAndEndA2dpDecodingSoftwareSessionWithPossiblePcmConfig) {
3285 for (auto sample_rate : a2dp_sample_rates) {
3286 for (auto bits_per_sample : a2dp_bits_per_samples) {
3287 for (auto channel_mode : a2dp_channel_modes) {
3288 PcmConfiguration pcm_config{
3289 .sampleRateHz = sample_rate,
Alice Kuoadcceec2022-03-28 13:28:43 +08003290 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00003291 .bitsPerSample = bits_per_sample,
Alice Kuoadcceec2022-03-28 13:28:43 +08003292 };
3293 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
3294 DataMQDesc mq_desc;
3295 auto aidl_retval = audio_provider_->startSession(
3296 audio_port_, AudioConfiguration(pcm_config), latency_modes,
3297 &mq_desc);
3298 DataMQ data_mq(mq_desc);
3299
3300 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
3301 if (is_codec_config_valid) {
3302 EXPECT_TRUE(data_mq.isValid());
3303 }
3304 EXPECT_TRUE(audio_provider_->endSession().isOk());
3305 }
3306 }
3307 }
3308}
3309
3310/**
3311 * openProvider A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH
3312 */
3313class BluetoothAudioProviderA2dpDecodingHardwareAidl
3314 : public BluetoothAudioProviderFactoryAidl {
3315 public:
3316 virtual void SetUp() override {
3317 BluetoothAudioProviderFactoryAidl::SetUp();
3318 GetProviderCapabilitiesHelper(
3319 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
3320 OpenProviderHelper(SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
3321 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
3322 audio_provider_ != nullptr);
3323 }
3324
3325 virtual void TearDown() override {
3326 audio_port_ = nullptr;
3327 audio_provider_ = nullptr;
3328 BluetoothAudioProviderFactoryAidl::TearDown();
3329 }
3330
3331 bool IsOffloadSupported() { return (temp_provider_capabilities_.size() > 0); }
3332};
3333
3334/**
3335 * Test whether we can open a provider of type
3336 */
3337TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3338 OpenA2dpDecodingHardwareProvider) {}
3339
3340/**
3341 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08003342 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
3343 * with SBC hardware encoding config
Alice Kuoadcceec2022-03-28 13:28:43 +08003344 */
3345TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3346 StartAndEndA2dpSbcDecodingHardwareSession) {
3347 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003348 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08003349 }
3350
3351 CodecConfiguration codec_config = {
3352 .codecType = CodecType::SBC,
3353 .encodedAudioBitrate = 328000,
3354 .peerMtu = 1005,
3355 .isScmstEnabled = false,
3356 };
3357 auto sbc_codec_specifics = GetSbcCodecSpecificSupportedList(true);
3358
3359 for (auto& codec_specific : sbc_codec_specifics) {
3360 copy_codec_specific(codec_config.config, codec_specific);
3361 DataMQDesc mq_desc;
3362 auto aidl_retval = audio_provider_->startSession(
3363 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
3364
3365 ASSERT_TRUE(aidl_retval.isOk());
3366 EXPECT_TRUE(audio_provider_->endSession().isOk());
3367 }
3368}
3369
3370/**
3371 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08003372 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
3373 * with AAC hardware encoding config
Alice Kuoadcceec2022-03-28 13:28:43 +08003374 */
3375TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3376 StartAndEndA2dpAacDecodingHardwareSession) {
3377 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003378 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08003379 }
3380
3381 CodecConfiguration codec_config = {
3382 .codecType = CodecType::AAC,
3383 .encodedAudioBitrate = 320000,
3384 .peerMtu = 1005,
3385 .isScmstEnabled = false,
3386 };
3387 auto aac_codec_specifics = GetAacCodecSpecificSupportedList(true);
3388
3389 for (auto& codec_specific : aac_codec_specifics) {
3390 copy_codec_specific(codec_config.config, codec_specific);
3391 DataMQDesc mq_desc;
3392 auto aidl_retval = audio_provider_->startSession(
3393 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
3394
3395 ASSERT_TRUE(aidl_retval.isOk());
3396 EXPECT_TRUE(audio_provider_->endSession().isOk());
3397 }
3398}
3399
3400/**
3401 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08003402 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
3403 * with LDAC hardware encoding config
Alice Kuoadcceec2022-03-28 13:28:43 +08003404 */
3405TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3406 StartAndEndA2dpLdacDecodingHardwareSession) {
3407 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003408 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08003409 }
3410
3411 CodecConfiguration codec_config = {
3412 .codecType = CodecType::LDAC,
3413 .encodedAudioBitrate = 990000,
3414 .peerMtu = 1005,
3415 .isScmstEnabled = false,
3416 };
3417 auto ldac_codec_specifics = GetLdacCodecSpecificSupportedList(true);
3418
3419 for (auto& codec_specific : ldac_codec_specifics) {
3420 copy_codec_specific(codec_config.config, codec_specific);
3421 DataMQDesc mq_desc;
3422 auto aidl_retval = audio_provider_->startSession(
3423 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
3424
3425 ASSERT_TRUE(aidl_retval.isOk());
3426 EXPECT_TRUE(audio_provider_->endSession().isOk());
3427 }
3428}
3429
3430/**
3431 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08003432 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
3433 * with Opus hardware encoding config
Alice Kuoadcceec2022-03-28 13:28:43 +08003434 */
3435TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
Omer Osmana2587da2022-05-01 03:54:11 +00003436 StartAndEndA2dpOpusDecodingHardwareSession) {
Alice Kuoadcceec2022-03-28 13:28:43 +08003437 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003438 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08003439 }
3440
3441 CodecConfiguration codec_config = {
Omer Osmana2587da2022-05-01 03:54:11 +00003442 .codecType = CodecType::OPUS,
Alice Kuoadcceec2022-03-28 13:28:43 +08003443 .encodedAudioBitrate = 990000,
3444 .peerMtu = 1005,
3445 .isScmstEnabled = false,
3446 };
Omer Osmana2587da2022-05-01 03:54:11 +00003447 auto opus_codec_specifics = GetOpusCodecSpecificSupportedList(true);
Alice Kuoadcceec2022-03-28 13:28:43 +08003448
Omer Osmana2587da2022-05-01 03:54:11 +00003449 for (auto& codec_specific : opus_codec_specifics) {
Alice Kuoadcceec2022-03-28 13:28:43 +08003450 copy_codec_specific(codec_config.config, codec_specific);
3451 DataMQDesc mq_desc;
3452 auto aidl_retval = audio_provider_->startSession(
3453 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
3454
3455 ASSERT_TRUE(aidl_retval.isOk());
3456 EXPECT_TRUE(audio_provider_->endSession().isOk());
3457 }
3458}
3459
3460/**
3461 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08003462 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
3463 * with AptX hardware encoding config
Alice Kuoadcceec2022-03-28 13:28:43 +08003464 */
3465TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3466 StartAndEndA2dpAptxDecodingHardwareSession) {
3467 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003468 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08003469 }
3470
3471 for (auto codec_type : {CodecType::APTX, CodecType::APTX_HD}) {
3472 CodecConfiguration codec_config = {
3473 .codecType = codec_type,
3474 .encodedAudioBitrate =
3475 (codec_type == CodecType::APTX ? 352000 : 576000),
3476 .peerMtu = 1005,
3477 .isScmstEnabled = false,
3478 };
3479
3480 auto aptx_codec_specifics = GetAptxCodecSpecificSupportedList(
3481 (codec_type == CodecType::APTX_HD ? true : false), true);
3482
3483 for (auto& codec_specific : aptx_codec_specifics) {
3484 copy_codec_specific(codec_config.config, codec_specific);
3485 DataMQDesc mq_desc;
3486 auto aidl_retval = audio_provider_->startSession(
3487 audio_port_, AudioConfiguration(codec_config), latency_modes,
3488 &mq_desc);
3489
3490 ASSERT_TRUE(aidl_retval.isOk());
3491 EXPECT_TRUE(audio_provider_->endSession().isOk());
3492 }
3493 }
3494}
3495
3496/**
3497 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08003498 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
3499 * with an invalid codec config
Alice Kuoadcceec2022-03-28 13:28:43 +08003500 */
3501TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3502 StartAndEndA2dpDecodingHardwareSessionInvalidCodecConfig) {
3503 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003504 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08003505 }
3506 ASSERT_NE(audio_provider_, nullptr);
3507
3508 std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
Sagar Verma62df9102022-12-07 17:56:04 +05303509 for (auto codec_type : ndk::enum_range<CodecType>()) {
Alice Kuoadcceec2022-03-28 13:28:43 +08003510 switch (codec_type) {
3511 case CodecType::SBC:
3512 codec_specifics = GetSbcCodecSpecificSupportedList(false);
3513 break;
3514 case CodecType::AAC:
3515 codec_specifics = GetAacCodecSpecificSupportedList(false);
3516 break;
3517 case CodecType::LDAC:
3518 codec_specifics = GetLdacCodecSpecificSupportedList(false);
3519 break;
3520 case CodecType::APTX:
3521 codec_specifics = GetAptxCodecSpecificSupportedList(false, false);
3522 break;
3523 case CodecType::APTX_HD:
3524 codec_specifics = GetAptxCodecSpecificSupportedList(true, false);
3525 break;
Omer Osmana2587da2022-05-01 03:54:11 +00003526 case CodecType::OPUS:
3527 codec_specifics = GetOpusCodecSpecificSupportedList(false);
Alice Kuoadcceec2022-03-28 13:28:43 +08003528 continue;
3529 case CodecType::APTX_ADAPTIVE:
Sagar Verma62df9102022-12-07 17:56:04 +05303530 case CodecType::APTX_ADAPTIVE_LE:
3531 case CodecType::APTX_ADAPTIVE_LEX:
Omer Osmana2587da2022-05-01 03:54:11 +00003532 case CodecType::LC3:
Alice Kuoadcceec2022-03-28 13:28:43 +08003533 case CodecType::VENDOR:
3534 case CodecType::UNKNOWN:
3535 codec_specifics.clear();
3536 break;
3537 }
3538 if (codec_specifics.empty()) {
3539 continue;
3540 }
3541
3542 CodecConfiguration codec_config = {
3543 .codecType = codec_type,
3544 .encodedAudioBitrate = 328000,
3545 .peerMtu = 1005,
3546 .isScmstEnabled = false,
3547 };
3548 for (auto codec_specific : codec_specifics) {
3549 copy_codec_specific(codec_config.config, codec_specific);
3550 DataMQDesc mq_desc;
3551 auto aidl_retval = audio_provider_->startSession(
3552 audio_port_, AudioConfiguration(codec_config), latency_modes,
3553 &mq_desc);
3554
3555 // AIDL call should fail on invalid codec
3556 ASSERT_FALSE(aidl_retval.isOk());
3557 EXPECT_TRUE(audio_provider_->endSession().isOk());
3558 }
3559 }
3560}
3561
Josh Wu049e2cd2022-01-12 05:42:58 -08003562GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3563 BluetoothAudioProviderFactoryAidl);
3564INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderFactoryAidl,
3565 testing::ValuesIn(android::getAidlHalInstanceNames(
3566 IBluetoothAudioProviderFactory::descriptor)),
3567 android::PrintInstanceNameToString);
3568
Antoine SOULIER33c4e5a2023-09-28 21:59:19 +00003569GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothAudioProviderAidl);
3570INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderAidl,
3571 testing::ValuesIn(android::getAidlHalInstanceNames(
3572 IBluetoothAudioProviderFactory::descriptor)),
3573 android::PrintInstanceNameToString);
3574
Josh Wu049e2cd2022-01-12 05:42:58 -08003575GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
Alice Kuoadcceec2022-03-28 13:28:43 +08003576 BluetoothAudioProviderA2dpEncodingSoftwareAidl);
3577INSTANTIATE_TEST_SUITE_P(PerInstance,
3578 BluetoothAudioProviderA2dpEncodingSoftwareAidl,
Josh Wu049e2cd2022-01-12 05:42:58 -08003579 testing::ValuesIn(android::getAidlHalInstanceNames(
3580 IBluetoothAudioProviderFactory::descriptor)),
3581 android::PrintInstanceNameToString);
3582
3583GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
Alice Kuoadcceec2022-03-28 13:28:43 +08003584 BluetoothAudioProviderA2dpEncodingHardwareAidl);
3585INSTANTIATE_TEST_SUITE_P(PerInstance,
3586 BluetoothAudioProviderA2dpEncodingHardwareAidl,
Josh Wu049e2cd2022-01-12 05:42:58 -08003587 testing::ValuesIn(android::getAidlHalInstanceNames(
3588 IBluetoothAudioProviderFactory::descriptor)),
3589 android::PrintInstanceNameToString);
3590
3591GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3592 BluetoothAudioProviderHearingAidSoftwareAidl);
3593INSTANTIATE_TEST_SUITE_P(PerInstance,
3594 BluetoothAudioProviderHearingAidSoftwareAidl,
3595 testing::ValuesIn(android::getAidlHalInstanceNames(
3596 IBluetoothAudioProviderFactory::descriptor)),
3597 android::PrintInstanceNameToString);
3598
3599GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3600 BluetoothAudioProviderLeAudioOutputSoftwareAidl);
3601INSTANTIATE_TEST_SUITE_P(PerInstance,
3602 BluetoothAudioProviderLeAudioOutputSoftwareAidl,
3603 testing::ValuesIn(android::getAidlHalInstanceNames(
3604 IBluetoothAudioProviderFactory::descriptor)),
3605 android::PrintInstanceNameToString);
3606
3607GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3608 BluetoothAudioProviderLeAudioInputSoftwareAidl);
3609INSTANTIATE_TEST_SUITE_P(PerInstance,
3610 BluetoothAudioProviderLeAudioInputSoftwareAidl,
3611 testing::ValuesIn(android::getAidlHalInstanceNames(
3612 IBluetoothAudioProviderFactory::descriptor)),
3613 android::PrintInstanceNameToString);
3614
3615GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3616 BluetoothAudioProviderLeAudioOutputHardwareAidl);
3617INSTANTIATE_TEST_SUITE_P(PerInstance,
3618 BluetoothAudioProviderLeAudioOutputHardwareAidl,
3619 testing::ValuesIn(android::getAidlHalInstanceNames(
3620 IBluetoothAudioProviderFactory::descriptor)),
3621 android::PrintInstanceNameToString);
3622
3623GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3624 BluetoothAudioProviderLeAudioInputHardwareAidl);
3625INSTANTIATE_TEST_SUITE_P(PerInstance,
3626 BluetoothAudioProviderLeAudioInputHardwareAidl,
3627 testing::ValuesIn(android::getAidlHalInstanceNames(
3628 IBluetoothAudioProviderFactory::descriptor)),
3629 android::PrintInstanceNameToString);
3630
3631GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3632 BluetoothAudioProviderLeAudioBroadcastSoftwareAidl);
3633INSTANTIATE_TEST_SUITE_P(PerInstance,
3634 BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
3635 testing::ValuesIn(android::getAidlHalInstanceNames(
3636 IBluetoothAudioProviderFactory::descriptor)),
3637 android::PrintInstanceNameToString);
3638
Alice Kuo336d90c2022-02-16 09:09:59 +08003639GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3640 BluetoothAudioProviderLeAudioBroadcastHardwareAidl);
3641INSTANTIATE_TEST_SUITE_P(PerInstance,
3642 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3643 testing::ValuesIn(android::getAidlHalInstanceNames(
3644 IBluetoothAudioProviderFactory::descriptor)),
3645 android::PrintInstanceNameToString);
Josh Wu049e2cd2022-01-12 05:42:58 -08003646
Alice Kuoadcceec2022-03-28 13:28:43 +08003647GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3648 BluetoothAudioProviderA2dpDecodingSoftwareAidl);
3649INSTANTIATE_TEST_SUITE_P(PerInstance,
3650 BluetoothAudioProviderA2dpDecodingSoftwareAidl,
3651 testing::ValuesIn(android::getAidlHalInstanceNames(
3652 IBluetoothAudioProviderFactory::descriptor)),
3653 android::PrintInstanceNameToString);
3654
3655GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3656 BluetoothAudioProviderA2dpDecodingHardwareAidl);
3657INSTANTIATE_TEST_SUITE_P(PerInstance,
3658 BluetoothAudioProviderA2dpDecodingHardwareAidl,
3659 testing::ValuesIn(android::getAidlHalInstanceNames(
3660 IBluetoothAudioProviderFactory::descriptor)),
3661 android::PrintInstanceNameToString);
3662
Bao Do72399432023-11-09 08:13:05 +00003663GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3664 BluetoothAudioProviderHfpHardwareAidl);
3665INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderHfpHardwareAidl,
3666 testing::ValuesIn(android::getAidlHalInstanceNames(
3667 IBluetoothAudioProviderFactory::descriptor)),
3668 android::PrintInstanceNameToString);
3669
3670GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3671 BluetoothAudioProviderHfpSoftwareDecodingAidl);
3672INSTANTIATE_TEST_SUITE_P(PerInstance,
3673 BluetoothAudioProviderHfpSoftwareDecodingAidl,
3674 testing::ValuesIn(android::getAidlHalInstanceNames(
3675 IBluetoothAudioProviderFactory::descriptor)),
3676 android::PrintInstanceNameToString);
3677
3678GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3679 BluetoothAudioProviderHfpSoftwareEncodingAidl);
3680INSTANTIATE_TEST_SUITE_P(PerInstance,
3681 BluetoothAudioProviderHfpSoftwareEncodingAidl,
3682 testing::ValuesIn(android::getAidlHalInstanceNames(
3683 IBluetoothAudioProviderFactory::descriptor)),
3684 android::PrintInstanceNameToString);
3685
Josh Wu049e2cd2022-01-12 05:42:58 -08003686int main(int argc, char** argv) {
3687 ::testing::InitGoogleTest(&argc, argv);
3688 ABinderProcess_setThreadPoolMaxThreadCount(1);
3689 ABinderProcess_startThreadPool();
3690 return RUN_ALL_TESTS();
3691}