blob: 85bc48ad8d088df71368066d9ca93ac15092cd87 [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();
2305 octets.minimum = 0;
2306 octets.maximum = 60;
2307 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) {
2570 requirement.contextType = GetAudioContext(bitmask);
2571 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) {
2586 IBluetoothAudioProvider::StreamConfig sink_requirement;
2587 IBluetoothAudioProvider::StreamConfig source_requirement;
2588 std::vector<IBluetoothAudioProvider::LeAudioDataPathConfiguration>
2589 DataPathConfigurations;
2590 bool is_supported = false;
2591
2592 for (auto bitmask : all_context_bitmasks) {
2593 sink_requirement.context = GetAudioContext(bitmask);
2594 source_requirement.context = GetAudioContext(bitmask);
2595 IBluetoothAudioProvider::LeAudioDataPathConfigurationPair result;
2596 auto aidl_retval = audio_provider_->getLeAudioAseDatapathConfiguration(
2597 sink_requirement, source_requirement, &result);
2598 if (!aidl_retval.isOk()) {
2599 // If not OK, then it could be not supported, as it is an optional feature
2600 ASSERT_EQ(aidl_retval.getExceptionCode(), EX_UNSUPPORTED_OPERATION);
2601 } else {
2602 is_supported = true;
2603 if (result.inputConfig.has_value())
2604 DataPathConfigurations.push_back(result.inputConfig.value());
2605 if (result.inputConfig.has_value())
2606 DataPathConfigurations.push_back(result.inputConfig.value());
2607 }
2608 }
2609
2610 if (is_supported) {
2611 // Datapath Configurations should not be empty, as we searched for all
2612 // contexts
2613 ASSERT_FALSE(DataPathConfigurations.empty());
2614 }
2615}
2616
Bao Doc36897d2023-12-06 01:27:54 +00002617/**
2618 * Test whether each provider of type
2619 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002620 * stopped with Unicast hardware encoding config
2621 */
2622TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2623 StartAndEndLeAudioOutputSessionWithPossibleUnicastConfig) {
2624 if (!IsOffloadOutputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002625 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08002626 }
2627
2628 auto lc3_codec_configs =
2629 GetUnicastLc3SupportedList(false /* decoding */, true /* supported */);
2630 LeAudioConfiguration le_audio_config = {
2631 .codecType = CodecType::LC3,
2632 .peerDelayUs = 0,
2633 };
2634
2635 for (auto& lc3_config : lc3_codec_configs) {
2636 le_audio_config.leAudioCodecConfig
2637 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2638 DataMQDesc mq_desc;
2639 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002640 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2641 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002642
2643 ASSERT_TRUE(aidl_retval.isOk());
2644 EXPECT_TRUE(audio_provider_->endSession().isOk());
2645 }
2646}
2647
2648/**
2649 * Test whether each provider of type
2650 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2651 * stopped with Unicast hardware encoding config
2652 *
2653 * Disabled since offload codec checking is not ready
2654 */
2655TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2656 DISABLED_StartAndEndLeAudioOutputSessionWithInvalidAudioConfiguration) {
2657 if (!IsOffloadOutputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002658 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08002659 }
2660
2661 auto lc3_codec_configs =
2662 GetUnicastLc3SupportedList(false /* decoding */, false /* supported */);
2663 LeAudioConfiguration le_audio_config = {
2664 .codecType = CodecType::LC3,
2665 .peerDelayUs = 0,
2666 };
2667
2668 for (auto& lc3_config : lc3_codec_configs) {
2669 le_audio_config.leAudioCodecConfig
2670 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2671 DataMQDesc mq_desc;
2672 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002673 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2674 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002675
2676 // AIDL call should fail on invalid codec
2677 ASSERT_FALSE(aidl_retval.isOk());
2678 EXPECT_TRUE(audio_provider_->endSession().isOk());
2679 }
2680}
2681
Sagar Verma62df9102022-12-07 17:56:04 +05302682static std::vector<uint8_t> vendorMetadata = {0x0B, // Length
2683 0xFF, // Type: Vendor-specific
2684 0x0A, 0x00, // Company_ID
2685 0x01, 0x02, 0x03, 0x04, // Data
2686 0x05, 0x06, 0x07, 0x08};
2687
2688/**
2689 * Test whether each provider of type
2690 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2691 * stopped with Unicast hardware encoding config
2692 */
2693TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2694 StartAndEndLeAudioOutputSessionWithAptxAdaptiveLeUnicastConfig) {
2695 if (!IsOffloadOutputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002696 GTEST_SKIP();
Sagar Verma62df9102022-12-07 17:56:04 +05302697 }
2698 for (auto codec_type :
2699 {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
2700 bool is_le_extended = (codec_type == CodecType::APTX_ADAPTIVE_LEX);
2701 auto aptx_adaptive_le_codec_configs =
2702 GetUnicastAptxAdaptiveLeSupportedList(false, true, is_le_extended);
2703 LeAudioConfiguration le_audio_config = {
2704 .codecType = codec_type,
2705 .peerDelayUs = 0,
2706 .vendorSpecificMetadata = vendorMetadata,
2707 };
2708
2709 for (auto& aptx_adaptive_le_config : aptx_adaptive_le_codec_configs) {
2710 le_audio_config.leAudioCodecConfig
2711 .set<LeAudioCodecConfiguration::aptxAdaptiveLeConfig>(
2712 aptx_adaptive_le_config);
2713 DataMQDesc mq_desc;
2714 auto aidl_retval = audio_provider_->startSession(
2715 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2716 &mq_desc);
2717
2718 ASSERT_TRUE(aidl_retval.isOk());
2719 EXPECT_TRUE(audio_provider_->endSession().isOk());
2720 }
2721 }
2722}
2723
2724/**
2725 * Test whether each provider of type
2726 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2727 * stopped with Unicast hardware encoding config
2728 */
2729TEST_P(
2730 BluetoothAudioProviderLeAudioOutputHardwareAidl,
2731 BluetoothAudioProviderLeAudioOutputHardwareAidl_StartAndEndLeAudioOutputSessionWithInvalidAptxAdaptiveLeAudioConfiguration) {
2732 if (!IsOffloadOutputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002733 GTEST_SKIP();
Sagar Verma62df9102022-12-07 17:56:04 +05302734 }
2735
2736 for (auto codec_type :
2737 {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
2738 bool is_le_extended = (codec_type == CodecType::APTX_ADAPTIVE_LEX);
2739 auto aptx_adaptive_le_codec_configs =
2740 GetUnicastAptxAdaptiveLeSupportedList(false, true, is_le_extended);
2741 LeAudioConfiguration le_audio_config = {
2742 .codecType = codec_type,
2743 .peerDelayUs = 0,
2744 .vendorSpecificMetadata = vendorMetadata,
2745 };
2746
2747 for (auto& aptx_adaptive_le_config : aptx_adaptive_le_codec_configs) {
2748 le_audio_config.leAudioCodecConfig
2749 .set<LeAudioCodecConfiguration::aptxAdaptiveLeConfig>(
2750 aptx_adaptive_le_config);
2751 DataMQDesc mq_desc;
2752 auto aidl_retval = audio_provider_->startSession(
2753 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2754 &mq_desc);
2755
2756 // AIDL call should fail on invalid codec
2757 ASSERT_FALSE(aidl_retval.isOk());
2758 EXPECT_TRUE(audio_provider_->endSession().isOk());
2759 }
2760 }
2761}
2762
Josh Wu049e2cd2022-01-12 05:42:58 -08002763/**
2764 * openProvider LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH
2765 */
2766class BluetoothAudioProviderLeAudioInputHardwareAidl
2767 : public BluetoothAudioProviderLeAudioOutputHardwareAidl {
2768 public:
2769 virtual void SetUp() override {
2770 BluetoothAudioProviderFactoryAidl::SetUp();
2771 GetProviderCapabilitiesHelper(
2772 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
Bao Doc36897d2023-12-06 01:27:54 +00002773 GetProviderInfoHelper(
2774 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
Josh Wu049e2cd2022-01-12 05:42:58 -08002775 OpenProviderHelper(
2776 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
2777 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
2778 audio_provider_ != nullptr);
2779 }
2780
2781 bool IsOffloadInputSupported() {
2782 for (auto& capability : temp_provider_capabilities_) {
2783 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2784 continue;
2785 }
2786 auto& le_audio_capability =
2787 capability.get<AudioCapabilities::leAudioCapabilities>();
2788 if (le_audio_capability.unicastDecodeCapability.codecType !=
2789 CodecType::UNKNOWN)
2790 return true;
2791 }
2792 return false;
2793 }
2794
2795 virtual void TearDown() override {
2796 audio_port_ = nullptr;
2797 audio_provider_ = nullptr;
2798 BluetoothAudioProviderFactoryAidl::TearDown();
2799 }
2800};
2801
2802/**
2803 * Test whether each provider of type
Bao Doc36897d2023-12-06 01:27:54 +00002804 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002805 * stopped
2806 */
2807TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
2808 OpenLeAudioInputHardwareProvider) {}
2809
2810/**
2811 * Test whether each provider of type
Bao Doc36897d2023-12-06 01:27:54 +00002812 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
2813 * stopped with Unicast hardware encoding config taken from provider info
2814 */
2815TEST_P(
2816 BluetoothAudioProviderLeAudioInputHardwareAidl,
2817 StartAndEndLeAudioInputSessionWithPossibleUnicastConfigFromProviderInfo) {
2818 if (!IsOffloadOutputProviderInfoSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002819 GTEST_SKIP();
Bao Doc36897d2023-12-06 01:27:54 +00002820 }
2821
2822 auto lc3_codec_configs = GetUnicastLc3SupportedListFromProviderInfo();
2823 LeAudioConfiguration le_audio_config = {
2824 .codecType = CodecType::LC3,
2825 .peerDelayUs = 0,
2826 };
2827
2828 for (auto& lc3_config : lc3_codec_configs) {
2829 le_audio_config.leAudioCodecConfig
2830 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2831 DataMQDesc mq_desc;
2832 auto aidl_retval = audio_provider_->startSession(
2833 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2834 &mq_desc);
2835
2836 ASSERT_TRUE(aidl_retval.isOk());
2837 EXPECT_TRUE(audio_provider_->endSession().isOk());
2838 }
2839}
2840
2841/**
2842 * Test whether each provider of type
2843 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002844 * stopped with Unicast hardware encoding config
2845 */
2846TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
2847 StartAndEndLeAudioInputSessionWithPossibleUnicastConfig) {
2848 if (!IsOffloadInputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002849 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08002850 }
2851
2852 auto lc3_codec_configs =
2853 GetUnicastLc3SupportedList(true /* decoding */, true /* supported */);
2854 LeAudioConfiguration le_audio_config = {
2855 .codecType = CodecType::LC3,
2856 .peerDelayUs = 0,
2857 };
2858
2859 for (auto& lc3_config : lc3_codec_configs) {
2860 le_audio_config.leAudioCodecConfig
2861 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2862 DataMQDesc mq_desc;
2863 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002864 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2865 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002866
2867 ASSERT_TRUE(aidl_retval.isOk());
2868 EXPECT_TRUE(audio_provider_->endSession().isOk());
2869 }
2870}
2871
2872/**
2873 * Test whether each provider of type
Bao Doc36897d2023-12-06 01:27:54 +00002874 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002875 * stopped with Unicast hardware encoding config
2876 *
2877 * Disabled since offload codec checking is not ready
2878 */
2879TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
2880 DISABLED_StartAndEndLeAudioInputSessionWithInvalidAudioConfiguration) {
2881 if (!IsOffloadInputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002882 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08002883 }
2884
2885 auto lc3_codec_configs =
2886 GetUnicastLc3SupportedList(true /* decoding */, false /* supported */);
2887 LeAudioConfiguration le_audio_config = {
2888 .codecType = CodecType::LC3,
2889 .peerDelayUs = 0,
2890 };
2891
2892 for (auto& lc3_config : lc3_codec_configs) {
2893 le_audio_config.leAudioCodecConfig
2894 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2895
2896 DataMQDesc mq_desc;
2897 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002898 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
2899 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002900
2901 // AIDL call should fail on invalid codec
2902 ASSERT_FALSE(aidl_retval.isOk());
2903 EXPECT_TRUE(audio_provider_->endSession().isOk());
2904 }
2905}
2906
2907/**
2908 * openProvider LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH
2909 */
2910class BluetoothAudioProviderLeAudioBroadcastSoftwareAidl
2911 : public BluetoothAudioProviderFactoryAidl {
2912 public:
2913 virtual void SetUp() override {
2914 BluetoothAudioProviderFactoryAidl::SetUp();
2915 GetProviderCapabilitiesHelper(
2916 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
2917 OpenProviderHelper(
2918 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
2919 ASSERT_NE(audio_provider_, nullptr);
2920 }
2921
2922 virtual void TearDown() override {
2923 audio_port_ = nullptr;
2924 audio_provider_ = nullptr;
2925 BluetoothAudioProviderFactoryAidl::TearDown();
2926 }
2927
2928 static constexpr int32_t le_audio_output_sample_rates_[] = {
2929 0, 8000, 16000, 24000, 32000, 44100, 48000,
2930 };
2931 static constexpr int8_t le_audio_output_bits_per_samples_[] = {0, 16, 24};
2932 static constexpr ChannelMode le_audio_output_channel_modes_[] = {
2933 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
2934 static constexpr int32_t le_audio_output_data_interval_us_[] = {
2935 0 /* Invalid */, 10000 /* Valid 10ms */};
2936};
2937
2938/**
2939 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08002940 * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started
2941 * and stopped
Josh Wu049e2cd2022-01-12 05:42:58 -08002942 */
2943TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
Josh Wu3202eab2022-02-17 18:09:05 -08002944 OpenLeAudioOutputSoftwareProvider) {}
Josh Wu049e2cd2022-01-12 05:42:58 -08002945
2946/**
2947 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08002948 * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started
2949 * and stopped with different PCM config
Josh Wu049e2cd2022-01-12 05:42:58 -08002950 */
2951TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
Josh Wu3202eab2022-02-17 18:09:05 -08002952 StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
Josh Wu049e2cd2022-01-12 05:42:58 -08002953 for (auto sample_rate : le_audio_output_sample_rates_) {
2954 for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
2955 for (auto channel_mode : le_audio_output_channel_modes_) {
2956 for (auto data_interval_us : le_audio_output_data_interval_us_) {
2957 PcmConfiguration pcm_config{
2958 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08002959 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00002960 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08002961 .dataIntervalUs = data_interval_us,
2962 };
Josh Wu8a1be762022-02-15 09:37:29 -08002963 bool is_codec_config_valid =
2964 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
Josh Wu049e2cd2022-01-12 05:42:58 -08002965 DataMQDesc mq_desc;
2966 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002967 audio_port_, AudioConfiguration(pcm_config), latency_modes,
2968 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002969 DataMQ data_mq(mq_desc);
2970
2971 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
2972 if (is_codec_config_valid) {
2973 EXPECT_TRUE(data_mq.isValid());
2974 }
2975 EXPECT_TRUE(audio_provider_->endSession().isOk());
2976 }
2977 }
2978 }
2979 }
2980}
2981
Alice Kuo336d90c2022-02-16 09:09:59 +08002982/**
2983 * openProvider LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH
2984 */
2985class BluetoothAudioProviderLeAudioBroadcastHardwareAidl
2986 : public BluetoothAudioProviderFactoryAidl {
2987 public:
2988 virtual void SetUp() override {
2989 BluetoothAudioProviderFactoryAidl::SetUp();
2990 GetProviderCapabilitiesHelper(
2991 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
Bao Doc36897d2023-12-06 01:27:54 +00002992 GetProviderInfoHelper(
2993 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
Alice Kuo336d90c2022-02-16 09:09:59 +08002994 OpenProviderHelper(
2995 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
2996 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
2997 audio_provider_ != nullptr);
2998 }
2999
3000 virtual void TearDown() override {
3001 audio_port_ = nullptr;
3002 audio_provider_ = nullptr;
3003 BluetoothAudioProviderFactoryAidl::TearDown();
3004 }
3005
3006 bool IsBroadcastOffloadSupported() {
3007 for (auto& capability : temp_provider_capabilities_) {
3008 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
3009 continue;
3010 }
3011 auto& le_audio_capability =
3012 capability.get<AudioCapabilities::leAudioCapabilities>();
3013 if (le_audio_capability.broadcastCapability.codecType !=
3014 CodecType::UNKNOWN)
3015 return true;
3016 }
3017 return false;
3018 }
3019
Bao Doc36897d2023-12-06 01:27:54 +00003020 bool IsBroadcastOffloadProviderInfoSupported() {
3021 if (!temp_provider_info_.has_value()) return false;
3022 if (temp_provider_info_.value().codecInfos.empty()) return false;
3023 // Check if all codec info is of LeAudio type
3024 for (auto& codec_info : temp_provider_info_.value().codecInfos) {
3025 if (codec_info.transport.getTag() != CodecInfo::Transport::leAudio)
3026 return false;
3027 }
3028 return true;
3029 }
3030
3031 std::vector<Lc3Configuration> GetBroadcastLc3SupportedListFromProviderInfo() {
3032 std::vector<Lc3Configuration> le_audio_codec_configs;
3033 for (auto& codec_info : temp_provider_info_.value().codecInfos) {
3034 // Only gets LC3 codec information
3035 if (codec_info.id != CodecId::Core::LC3) continue;
3036 // Combine those parameters into one list of Lc3Configuration
3037 auto& transport =
3038 codec_info.transport.get<CodecInfo::Transport::Tag::leAudio>();
3039 for (int32_t samplingFrequencyHz : transport.samplingFrequencyHz) {
3040 for (int32_t frameDurationUs : transport.frameDurationUs) {
3041 for (int32_t octetsPerFrame : transport.bitdepth) {
3042 Lc3Configuration lc3_config = {
3043 .samplingFrequencyHz = samplingFrequencyHz,
3044 .frameDurationUs = frameDurationUs,
3045 .octetsPerFrame = octetsPerFrame,
3046 };
3047 le_audio_codec_configs.push_back(lc3_config);
3048 }
3049 }
3050 }
3051 }
3052
3053 return le_audio_codec_configs;
3054 }
3055
Alice Kuo336d90c2022-02-16 09:09:59 +08003056 std::vector<Lc3Configuration> GetBroadcastLc3SupportedList(bool supported) {
3057 std::vector<Lc3Configuration> le_audio_codec_configs;
3058 if (!supported) {
shihchienc3ab9f5e2022-09-23 08:18:05 +00003059 Lc3Configuration lc3_config{.pcmBitDepth = 0, .samplingFrequencyHz = 0};
Alice Kuo336d90c2022-02-16 09:09:59 +08003060 le_audio_codec_configs.push_back(lc3_config);
3061 return le_audio_codec_configs;
3062 }
3063
3064 // There might be more than one LeAudioCodecCapabilitiesSetting
3065 std::vector<Lc3Capabilities> lc3_capabilities;
3066 for (auto& capability : temp_provider_capabilities_) {
3067 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
3068 continue;
3069 }
3070 auto& le_audio_capability =
3071 capability.get<AudioCapabilities::leAudioCapabilities>();
3072 auto& broadcast_capability = le_audio_capability.broadcastCapability;
3073 if (broadcast_capability.codecType != CodecType::LC3) {
3074 continue;
3075 }
3076 auto& lc3_capability = broadcast_capability.leAudioCodecCapabilities.get<
3077 BroadcastCapability::LeAudioCodecCapabilities::lc3Capabilities>();
3078 for (int idx = 0; idx < lc3_capability->size(); idx++)
3079 lc3_capabilities.push_back(*lc3_capability->at(idx));
3080 }
3081
3082 // Combine those parameters into one list of LeAudioCodecConfiguration
3083 // This seems horrible, but usually each Lc3Capability only contains a
3084 // single Lc3Configuration, which means every array has a length of 1.
3085 for (auto& lc3_capability : lc3_capabilities) {
3086 for (int32_t samplingFrequencyHz : lc3_capability.samplingFrequencyHz) {
3087 for (int32_t frameDurationUs : lc3_capability.frameDurationUs) {
3088 for (int32_t octetsPerFrame : lc3_capability.octetsPerFrame) {
3089 Lc3Configuration lc3_config = {
3090 .samplingFrequencyHz = samplingFrequencyHz,
3091 .frameDurationUs = frameDurationUs,
3092 .octetsPerFrame = octetsPerFrame,
3093 };
3094 le_audio_codec_configs.push_back(lc3_config);
3095 }
3096 }
3097 }
3098 }
3099
3100 return le_audio_codec_configs;
3101 }
3102
3103 LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
3104};
3105
3106/**
3107 * Test whether each provider of type
3108 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
3109 * started and stopped
3110 */
3111TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3112 OpenLeAudioOutputHardwareProvider) {}
3113
3114/**
3115 * Test whether each provider of type
3116 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
Bao Doc36897d2023-12-06 01:27:54 +00003117 * started and stopped with broadcast hardware encoding config taken from
3118 * provider info
3119 */
3120TEST_P(
3121 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3122 StartAndEndLeAudioBroadcastSessionWithPossibleUnicastConfigFromProviderInfo) {
Bao Dob487a852023-12-25 10:12:09 +08003123 if (GetProviderFactoryInterfaceVersion() <
3124 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3125 GTEST_SKIP();
3126 }
Bao Doc36897d2023-12-06 01:27:54 +00003127 if (!IsBroadcastOffloadProviderInfoSupported()) {
3128 return;
3129 }
3130
3131 auto lc3_codec_configs = GetBroadcastLc3SupportedListFromProviderInfo();
3132 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
3133 .codecType = CodecType::LC3,
3134 .streamMap = {},
3135 };
3136
3137 for (auto& lc3_config : lc3_codec_configs) {
3138 le_audio_broadcast_config.streamMap.resize(1);
3139 le_audio_broadcast_config.streamMap[0]
3140 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
3141 lc3_config);
3142 le_audio_broadcast_config.streamMap[0].streamHandle = 0x0;
3143 le_audio_broadcast_config.streamMap[0].pcmStreamId = 0x0;
3144 le_audio_broadcast_config.streamMap[0].audioChannelAllocation = 0x1 << 0;
3145
3146 DataMQDesc mq_desc;
3147 auto aidl_retval = audio_provider_->startSession(
3148 audio_port_, AudioConfiguration(le_audio_broadcast_config),
3149 latency_modes, &mq_desc);
3150
3151 ASSERT_TRUE(aidl_retval.isOk());
3152 EXPECT_TRUE(audio_provider_->endSession().isOk());
3153 }
3154}
3155
Bao Do5b2fdab2023-11-20 08:02:55 +00003156TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3157 GetEmptyBroadcastConfigurationEmptyCapability) {
Bao Dob487a852023-12-25 10:12:09 +08003158 if (GetProviderFactoryInterfaceVersion() <
3159 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3160 GTEST_SKIP();
3161 }
Bao Do5b2fdab2023-11-20 08:02:55 +00003162 std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
3163 IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement
3164 empty_requirement;
3165
3166 IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting* configuration =
3167 new IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting();
3168
3169 // Check empty capability for source direction
3170 auto aidl_retval = audio_provider_->getLeAudioBroadcastConfiguration(
3171 empty_capability, empty_requirement, configuration);
3172
3173 ASSERT_TRUE(aidl_retval.isOk());
3174}
3175
Bao Doc36897d2023-12-06 01:27:54 +00003176/**
3177 * Test whether each provider of type
3178 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
Alice Kuo336d90c2022-02-16 09:09:59 +08003179 * started and stopped with broadcast hardware encoding config
3180 */
3181TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3182 StartAndEndLeAudioBroadcastSessionWithPossibleBroadcastConfig) {
3183 if (!IsBroadcastOffloadSupported()) {
3184 return;
3185 }
3186
3187 auto lc3_codec_configs = GetBroadcastLc3SupportedList(true /* supported */);
3188 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
3189 .codecType = CodecType::LC3,
3190 .streamMap = {},
3191 };
3192
3193 for (auto& lc3_config : lc3_codec_configs) {
Patty Huangac077ef2022-11-23 14:45:15 +08003194 le_audio_broadcast_config.streamMap.resize(1);
Alice Kuo336d90c2022-02-16 09:09:59 +08003195 le_audio_broadcast_config.streamMap[0]
3196 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
3197 lc3_config);
Rongxuan Liuc1aea322023-01-26 17:14:54 +00003198 le_audio_broadcast_config.streamMap[0].streamHandle = 0x0;
3199 le_audio_broadcast_config.streamMap[0].pcmStreamId = 0x0;
3200 le_audio_broadcast_config.streamMap[0].audioChannelAllocation = 0x1 << 0;
3201
Alice Kuo336d90c2022-02-16 09:09:59 +08003202 DataMQDesc mq_desc;
3203 auto aidl_retval = audio_provider_->startSession(
Chen Chen60d52e42022-02-16 12:19:12 -08003204 audio_port_, AudioConfiguration(le_audio_broadcast_config),
3205 latency_modes, &mq_desc);
Alice Kuo336d90c2022-02-16 09:09:59 +08003206
3207 ASSERT_TRUE(aidl_retval.isOk());
3208 EXPECT_TRUE(audio_provider_->endSession().isOk());
3209 }
3210}
3211
3212/**
3213 * Test whether each provider of type
3214 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
3215 * started and stopped with Broadcast hardware encoding config
3216 *
3217 * Disabled since offload codec checking is not ready
3218 */
3219TEST_P(
3220 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3221 DISABLED_StartAndEndLeAudioBroadcastSessionWithInvalidAudioConfiguration) {
3222 if (!IsBroadcastOffloadSupported()) {
3223 return;
3224 }
3225
3226 auto lc3_codec_configs = GetBroadcastLc3SupportedList(false /* supported */);
3227 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
3228 .codecType = CodecType::LC3,
3229 .streamMap = {},
3230 };
3231
3232 for (auto& lc3_config : lc3_codec_configs) {
3233 le_audio_broadcast_config.streamMap[0]
3234 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
3235 lc3_config);
3236 DataMQDesc mq_desc;
3237 auto aidl_retval = audio_provider_->startSession(
Chen Chen60d52e42022-02-16 12:19:12 -08003238 audio_port_, AudioConfiguration(le_audio_broadcast_config),
3239 latency_modes, &mq_desc);
Alice Kuo336d90c2022-02-16 09:09:59 +08003240
3241 // AIDL call should fail on invalid codec
3242 ASSERT_FALSE(aidl_retval.isOk());
3243 EXPECT_TRUE(audio_provider_->endSession().isOk());
3244 }
3245}
3246
Alice Kuoadcceec2022-03-28 13:28:43 +08003247/**
3248 * openProvider A2DP_SOFTWARE_DECODING_DATAPATH
3249 */
3250class BluetoothAudioProviderA2dpDecodingSoftwareAidl
3251 : public BluetoothAudioProviderFactoryAidl {
3252 public:
3253 virtual void SetUp() override {
3254 BluetoothAudioProviderFactoryAidl::SetUp();
3255 GetProviderCapabilitiesHelper(SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
3256 OpenProviderHelper(SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
3257 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
3258 audio_provider_ != nullptr);
3259 }
3260
3261 virtual void TearDown() override {
3262 audio_port_ = nullptr;
3263 audio_provider_ = nullptr;
3264 BluetoothAudioProviderFactoryAidl::TearDown();
3265 }
3266};
3267
3268/**
3269 * Test whether we can open a provider of type
3270 */
3271TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,
3272 OpenA2dpDecodingSoftwareProvider) {}
3273
3274/**
3275 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08003276 * SessionType::A2DP_SOFTWARE_DECODING_DATAPATH can be started and stopped
3277 * with different PCM config
Alice Kuoadcceec2022-03-28 13:28:43 +08003278 */
3279TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,
3280 StartAndEndA2dpDecodingSoftwareSessionWithPossiblePcmConfig) {
3281 for (auto sample_rate : a2dp_sample_rates) {
3282 for (auto bits_per_sample : a2dp_bits_per_samples) {
3283 for (auto channel_mode : a2dp_channel_modes) {
3284 PcmConfiguration pcm_config{
3285 .sampleRateHz = sample_rate,
Alice Kuoadcceec2022-03-28 13:28:43 +08003286 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00003287 .bitsPerSample = bits_per_sample,
Alice Kuoadcceec2022-03-28 13:28:43 +08003288 };
3289 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
3290 DataMQDesc mq_desc;
3291 auto aidl_retval = audio_provider_->startSession(
3292 audio_port_, AudioConfiguration(pcm_config), latency_modes,
3293 &mq_desc);
3294 DataMQ data_mq(mq_desc);
3295
3296 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
3297 if (is_codec_config_valid) {
3298 EXPECT_TRUE(data_mq.isValid());
3299 }
3300 EXPECT_TRUE(audio_provider_->endSession().isOk());
3301 }
3302 }
3303 }
3304}
3305
3306/**
3307 * openProvider A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH
3308 */
3309class BluetoothAudioProviderA2dpDecodingHardwareAidl
3310 : public BluetoothAudioProviderFactoryAidl {
3311 public:
3312 virtual void SetUp() override {
3313 BluetoothAudioProviderFactoryAidl::SetUp();
3314 GetProviderCapabilitiesHelper(
3315 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
3316 OpenProviderHelper(SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
3317 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
3318 audio_provider_ != nullptr);
3319 }
3320
3321 virtual void TearDown() override {
3322 audio_port_ = nullptr;
3323 audio_provider_ = nullptr;
3324 BluetoothAudioProviderFactoryAidl::TearDown();
3325 }
3326
3327 bool IsOffloadSupported() { return (temp_provider_capabilities_.size() > 0); }
3328};
3329
3330/**
3331 * Test whether we can open a provider of type
3332 */
3333TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3334 OpenA2dpDecodingHardwareProvider) {}
3335
3336/**
3337 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08003338 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
3339 * with SBC hardware encoding config
Alice Kuoadcceec2022-03-28 13:28:43 +08003340 */
3341TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3342 StartAndEndA2dpSbcDecodingHardwareSession) {
3343 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003344 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08003345 }
3346
3347 CodecConfiguration codec_config = {
3348 .codecType = CodecType::SBC,
3349 .encodedAudioBitrate = 328000,
3350 .peerMtu = 1005,
3351 .isScmstEnabled = false,
3352 };
3353 auto sbc_codec_specifics = GetSbcCodecSpecificSupportedList(true);
3354
3355 for (auto& codec_specific : sbc_codec_specifics) {
3356 copy_codec_specific(codec_config.config, codec_specific);
3357 DataMQDesc mq_desc;
3358 auto aidl_retval = audio_provider_->startSession(
3359 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
3360
3361 ASSERT_TRUE(aidl_retval.isOk());
3362 EXPECT_TRUE(audio_provider_->endSession().isOk());
3363 }
3364}
3365
3366/**
3367 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08003368 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
3369 * with AAC hardware encoding config
Alice Kuoadcceec2022-03-28 13:28:43 +08003370 */
3371TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3372 StartAndEndA2dpAacDecodingHardwareSession) {
3373 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003374 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08003375 }
3376
3377 CodecConfiguration codec_config = {
3378 .codecType = CodecType::AAC,
3379 .encodedAudioBitrate = 320000,
3380 .peerMtu = 1005,
3381 .isScmstEnabled = false,
3382 };
3383 auto aac_codec_specifics = GetAacCodecSpecificSupportedList(true);
3384
3385 for (auto& codec_specific : aac_codec_specifics) {
3386 copy_codec_specific(codec_config.config, codec_specific);
3387 DataMQDesc mq_desc;
3388 auto aidl_retval = audio_provider_->startSession(
3389 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
3390
3391 ASSERT_TRUE(aidl_retval.isOk());
3392 EXPECT_TRUE(audio_provider_->endSession().isOk());
3393 }
3394}
3395
3396/**
3397 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08003398 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
3399 * with LDAC hardware encoding config
Alice Kuoadcceec2022-03-28 13:28:43 +08003400 */
3401TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3402 StartAndEndA2dpLdacDecodingHardwareSession) {
3403 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003404 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08003405 }
3406
3407 CodecConfiguration codec_config = {
3408 .codecType = CodecType::LDAC,
3409 .encodedAudioBitrate = 990000,
3410 .peerMtu = 1005,
3411 .isScmstEnabled = false,
3412 };
3413 auto ldac_codec_specifics = GetLdacCodecSpecificSupportedList(true);
3414
3415 for (auto& codec_specific : ldac_codec_specifics) {
3416 copy_codec_specific(codec_config.config, codec_specific);
3417 DataMQDesc mq_desc;
3418 auto aidl_retval = audio_provider_->startSession(
3419 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
3420
3421 ASSERT_TRUE(aidl_retval.isOk());
3422 EXPECT_TRUE(audio_provider_->endSession().isOk());
3423 }
3424}
3425
3426/**
3427 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08003428 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
3429 * with Opus hardware encoding config
Alice Kuoadcceec2022-03-28 13:28:43 +08003430 */
3431TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
Omer Osmana2587da2022-05-01 03:54:11 +00003432 StartAndEndA2dpOpusDecodingHardwareSession) {
Alice Kuoadcceec2022-03-28 13:28:43 +08003433 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003434 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08003435 }
3436
3437 CodecConfiguration codec_config = {
Omer Osmana2587da2022-05-01 03:54:11 +00003438 .codecType = CodecType::OPUS,
Alice Kuoadcceec2022-03-28 13:28:43 +08003439 .encodedAudioBitrate = 990000,
3440 .peerMtu = 1005,
3441 .isScmstEnabled = false,
3442 };
Omer Osmana2587da2022-05-01 03:54:11 +00003443 auto opus_codec_specifics = GetOpusCodecSpecificSupportedList(true);
Alice Kuoadcceec2022-03-28 13:28:43 +08003444
Omer Osmana2587da2022-05-01 03:54:11 +00003445 for (auto& codec_specific : opus_codec_specifics) {
Alice Kuoadcceec2022-03-28 13:28:43 +08003446 copy_codec_specific(codec_config.config, codec_specific);
3447 DataMQDesc mq_desc;
3448 auto aidl_retval = audio_provider_->startSession(
3449 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
3450
3451 ASSERT_TRUE(aidl_retval.isOk());
3452 EXPECT_TRUE(audio_provider_->endSession().isOk());
3453 }
3454}
3455
3456/**
3457 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08003458 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
3459 * with AptX hardware encoding config
Alice Kuoadcceec2022-03-28 13:28:43 +08003460 */
3461TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3462 StartAndEndA2dpAptxDecodingHardwareSession) {
3463 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003464 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08003465 }
3466
3467 for (auto codec_type : {CodecType::APTX, CodecType::APTX_HD}) {
3468 CodecConfiguration codec_config = {
3469 .codecType = codec_type,
3470 .encodedAudioBitrate =
3471 (codec_type == CodecType::APTX ? 352000 : 576000),
3472 .peerMtu = 1005,
3473 .isScmstEnabled = false,
3474 };
3475
3476 auto aptx_codec_specifics = GetAptxCodecSpecificSupportedList(
3477 (codec_type == CodecType::APTX_HD ? true : false), true);
3478
3479 for (auto& codec_specific : aptx_codec_specifics) {
3480 copy_codec_specific(codec_config.config, codec_specific);
3481 DataMQDesc mq_desc;
3482 auto aidl_retval = audio_provider_->startSession(
3483 audio_port_, AudioConfiguration(codec_config), latency_modes,
3484 &mq_desc);
3485
3486 ASSERT_TRUE(aidl_retval.isOk());
3487 EXPECT_TRUE(audio_provider_->endSession().isOk());
3488 }
3489 }
3490}
3491
3492/**
3493 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08003494 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
3495 * with an invalid codec config
Alice Kuoadcceec2022-03-28 13:28:43 +08003496 */
3497TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
3498 StartAndEndA2dpDecodingHardwareSessionInvalidCodecConfig) {
3499 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003500 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08003501 }
3502 ASSERT_NE(audio_provider_, nullptr);
3503
3504 std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
Sagar Verma62df9102022-12-07 17:56:04 +05303505 for (auto codec_type : ndk::enum_range<CodecType>()) {
Alice Kuoadcceec2022-03-28 13:28:43 +08003506 switch (codec_type) {
3507 case CodecType::SBC:
3508 codec_specifics = GetSbcCodecSpecificSupportedList(false);
3509 break;
3510 case CodecType::AAC:
3511 codec_specifics = GetAacCodecSpecificSupportedList(false);
3512 break;
3513 case CodecType::LDAC:
3514 codec_specifics = GetLdacCodecSpecificSupportedList(false);
3515 break;
3516 case CodecType::APTX:
3517 codec_specifics = GetAptxCodecSpecificSupportedList(false, false);
3518 break;
3519 case CodecType::APTX_HD:
3520 codec_specifics = GetAptxCodecSpecificSupportedList(true, false);
3521 break;
Omer Osmana2587da2022-05-01 03:54:11 +00003522 case CodecType::OPUS:
3523 codec_specifics = GetOpusCodecSpecificSupportedList(false);
Alice Kuoadcceec2022-03-28 13:28:43 +08003524 continue;
3525 case CodecType::APTX_ADAPTIVE:
Sagar Verma62df9102022-12-07 17:56:04 +05303526 case CodecType::APTX_ADAPTIVE_LE:
3527 case CodecType::APTX_ADAPTIVE_LEX:
Omer Osmana2587da2022-05-01 03:54:11 +00003528 case CodecType::LC3:
Alice Kuoadcceec2022-03-28 13:28:43 +08003529 case CodecType::VENDOR:
3530 case CodecType::UNKNOWN:
3531 codec_specifics.clear();
3532 break;
3533 }
3534 if (codec_specifics.empty()) {
3535 continue;
3536 }
3537
3538 CodecConfiguration codec_config = {
3539 .codecType = codec_type,
3540 .encodedAudioBitrate = 328000,
3541 .peerMtu = 1005,
3542 .isScmstEnabled = false,
3543 };
3544 for (auto codec_specific : codec_specifics) {
3545 copy_codec_specific(codec_config.config, codec_specific);
3546 DataMQDesc mq_desc;
3547 auto aidl_retval = audio_provider_->startSession(
3548 audio_port_, AudioConfiguration(codec_config), latency_modes,
3549 &mq_desc);
3550
3551 // AIDL call should fail on invalid codec
3552 ASSERT_FALSE(aidl_retval.isOk());
3553 EXPECT_TRUE(audio_provider_->endSession().isOk());
3554 }
3555 }
3556}
3557
Josh Wu049e2cd2022-01-12 05:42:58 -08003558GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3559 BluetoothAudioProviderFactoryAidl);
3560INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderFactoryAidl,
3561 testing::ValuesIn(android::getAidlHalInstanceNames(
3562 IBluetoothAudioProviderFactory::descriptor)),
3563 android::PrintInstanceNameToString);
3564
Antoine SOULIER33c4e5a2023-09-28 21:59:19 +00003565GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothAudioProviderAidl);
3566INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderAidl,
3567 testing::ValuesIn(android::getAidlHalInstanceNames(
3568 IBluetoothAudioProviderFactory::descriptor)),
3569 android::PrintInstanceNameToString);
3570
Josh Wu049e2cd2022-01-12 05:42:58 -08003571GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
Alice Kuoadcceec2022-03-28 13:28:43 +08003572 BluetoothAudioProviderA2dpEncodingSoftwareAidl);
3573INSTANTIATE_TEST_SUITE_P(PerInstance,
3574 BluetoothAudioProviderA2dpEncodingSoftwareAidl,
Josh Wu049e2cd2022-01-12 05:42:58 -08003575 testing::ValuesIn(android::getAidlHalInstanceNames(
3576 IBluetoothAudioProviderFactory::descriptor)),
3577 android::PrintInstanceNameToString);
3578
3579GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
Alice Kuoadcceec2022-03-28 13:28:43 +08003580 BluetoothAudioProviderA2dpEncodingHardwareAidl);
3581INSTANTIATE_TEST_SUITE_P(PerInstance,
3582 BluetoothAudioProviderA2dpEncodingHardwareAidl,
Josh Wu049e2cd2022-01-12 05:42:58 -08003583 testing::ValuesIn(android::getAidlHalInstanceNames(
3584 IBluetoothAudioProviderFactory::descriptor)),
3585 android::PrintInstanceNameToString);
3586
3587GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3588 BluetoothAudioProviderHearingAidSoftwareAidl);
3589INSTANTIATE_TEST_SUITE_P(PerInstance,
3590 BluetoothAudioProviderHearingAidSoftwareAidl,
3591 testing::ValuesIn(android::getAidlHalInstanceNames(
3592 IBluetoothAudioProviderFactory::descriptor)),
3593 android::PrintInstanceNameToString);
3594
3595GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3596 BluetoothAudioProviderLeAudioOutputSoftwareAidl);
3597INSTANTIATE_TEST_SUITE_P(PerInstance,
3598 BluetoothAudioProviderLeAudioOutputSoftwareAidl,
3599 testing::ValuesIn(android::getAidlHalInstanceNames(
3600 IBluetoothAudioProviderFactory::descriptor)),
3601 android::PrintInstanceNameToString);
3602
3603GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3604 BluetoothAudioProviderLeAudioInputSoftwareAidl);
3605INSTANTIATE_TEST_SUITE_P(PerInstance,
3606 BluetoothAudioProviderLeAudioInputSoftwareAidl,
3607 testing::ValuesIn(android::getAidlHalInstanceNames(
3608 IBluetoothAudioProviderFactory::descriptor)),
3609 android::PrintInstanceNameToString);
3610
3611GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3612 BluetoothAudioProviderLeAudioOutputHardwareAidl);
3613INSTANTIATE_TEST_SUITE_P(PerInstance,
3614 BluetoothAudioProviderLeAudioOutputHardwareAidl,
3615 testing::ValuesIn(android::getAidlHalInstanceNames(
3616 IBluetoothAudioProviderFactory::descriptor)),
3617 android::PrintInstanceNameToString);
3618
3619GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3620 BluetoothAudioProviderLeAudioInputHardwareAidl);
3621INSTANTIATE_TEST_SUITE_P(PerInstance,
3622 BluetoothAudioProviderLeAudioInputHardwareAidl,
3623 testing::ValuesIn(android::getAidlHalInstanceNames(
3624 IBluetoothAudioProviderFactory::descriptor)),
3625 android::PrintInstanceNameToString);
3626
3627GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3628 BluetoothAudioProviderLeAudioBroadcastSoftwareAidl);
3629INSTANTIATE_TEST_SUITE_P(PerInstance,
3630 BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
3631 testing::ValuesIn(android::getAidlHalInstanceNames(
3632 IBluetoothAudioProviderFactory::descriptor)),
3633 android::PrintInstanceNameToString);
3634
Alice Kuo336d90c2022-02-16 09:09:59 +08003635GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3636 BluetoothAudioProviderLeAudioBroadcastHardwareAidl);
3637INSTANTIATE_TEST_SUITE_P(PerInstance,
3638 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
3639 testing::ValuesIn(android::getAidlHalInstanceNames(
3640 IBluetoothAudioProviderFactory::descriptor)),
3641 android::PrintInstanceNameToString);
Josh Wu049e2cd2022-01-12 05:42:58 -08003642
Alice Kuoadcceec2022-03-28 13:28:43 +08003643GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3644 BluetoothAudioProviderA2dpDecodingSoftwareAidl);
3645INSTANTIATE_TEST_SUITE_P(PerInstance,
3646 BluetoothAudioProviderA2dpDecodingSoftwareAidl,
3647 testing::ValuesIn(android::getAidlHalInstanceNames(
3648 IBluetoothAudioProviderFactory::descriptor)),
3649 android::PrintInstanceNameToString);
3650
3651GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3652 BluetoothAudioProviderA2dpDecodingHardwareAidl);
3653INSTANTIATE_TEST_SUITE_P(PerInstance,
3654 BluetoothAudioProviderA2dpDecodingHardwareAidl,
3655 testing::ValuesIn(android::getAidlHalInstanceNames(
3656 IBluetoothAudioProviderFactory::descriptor)),
3657 android::PrintInstanceNameToString);
3658
Bao Do72399432023-11-09 08:13:05 +00003659GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3660 BluetoothAudioProviderHfpHardwareAidl);
3661INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderHfpHardwareAidl,
3662 testing::ValuesIn(android::getAidlHalInstanceNames(
3663 IBluetoothAudioProviderFactory::descriptor)),
3664 android::PrintInstanceNameToString);
3665
3666GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3667 BluetoothAudioProviderHfpSoftwareDecodingAidl);
3668INSTANTIATE_TEST_SUITE_P(PerInstance,
3669 BluetoothAudioProviderHfpSoftwareDecodingAidl,
3670 testing::ValuesIn(android::getAidlHalInstanceNames(
3671 IBluetoothAudioProviderFactory::descriptor)),
3672 android::PrintInstanceNameToString);
3673
3674GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
3675 BluetoothAudioProviderHfpSoftwareEncodingAidl);
3676INSTANTIATE_TEST_SUITE_P(PerInstance,
3677 BluetoothAudioProviderHfpSoftwareEncodingAidl,
3678 testing::ValuesIn(android::getAidlHalInstanceNames(
3679 IBluetoothAudioProviderFactory::descriptor)),
3680 android::PrintInstanceNameToString);
3681
Josh Wu049e2cd2022-01-12 05:42:58 -08003682int main(int argc, char** argv) {
3683 ::testing::InitGoogleTest(&argc, argv);
3684 ABinderProcess_setThreadPoolMaxThreadCount(1);
3685 ABinderProcess_startThreadPool();
3686 return RUN_ALL_TESTS();
3687}