blob: 110a62888261a4b4cded1f3450de1599c799ec1c [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;
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +000061using aidl::android::hardware::bluetooth::audio::ConfigurationFlags;
Bao Do72399432023-11-09 08:13:05 +000062using aidl::android::hardware::bluetooth::audio::HfpConfiguration;
Josh Wu049e2cd2022-01-12 05:42:58 -080063using aidl::android::hardware::bluetooth::audio::IBluetoothAudioPort;
64using aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider;
65using aidl::android::hardware::bluetooth::audio::IBluetoothAudioProviderFactory;
66using aidl::android::hardware::bluetooth::audio::LatencyMode;
67using aidl::android::hardware::bluetooth::audio::Lc3Capabilities;
68using aidl::android::hardware::bluetooth::audio::Lc3Configuration;
69using aidl::android::hardware::bluetooth::audio::LdacCapabilities;
70using aidl::android::hardware::bluetooth::audio::LdacConfiguration;
Bao Doc36897d2023-12-06 01:27:54 +000071using aidl::android::hardware::bluetooth::audio::LeAudioAseConfiguration;
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +000072using aidl::android::hardware::bluetooth::audio::LeAudioBisConfiguration;
Alice Kuo336d90c2022-02-16 09:09:59 +080073using aidl::android::hardware::bluetooth::audio::LeAudioBroadcastConfiguration;
Josh Wu049e2cd2022-01-12 05:42:58 -080074using aidl::android::hardware::bluetooth::audio::
75 LeAudioCodecCapabilitiesSetting;
76using aidl::android::hardware::bluetooth::audio::LeAudioCodecConfiguration;
77using aidl::android::hardware::bluetooth::audio::LeAudioConfiguration;
Bao Doc36897d2023-12-06 01:27:54 +000078using aidl::android::hardware::bluetooth::audio::MetadataLtv;
Omer Osmana2587da2022-05-01 03:54:11 +000079using aidl::android::hardware::bluetooth::audio::OpusCapabilities;
80using aidl::android::hardware::bluetooth::audio::OpusConfiguration;
Josh Wu049e2cd2022-01-12 05:42:58 -080081using aidl::android::hardware::bluetooth::audio::PcmConfiguration;
82using aidl::android::hardware::bluetooth::audio::PresentationPosition;
83using aidl::android::hardware::bluetooth::audio::SbcAllocMethod;
84using aidl::android::hardware::bluetooth::audio::SbcCapabilities;
85using aidl::android::hardware::bluetooth::audio::SbcChannelMode;
86using aidl::android::hardware::bluetooth::audio::SbcConfiguration;
87using aidl::android::hardware::bluetooth::audio::SessionType;
88using aidl::android::hardware::bluetooth::audio::UnicastCapability;
89using aidl::android::hardware::common::fmq::MQDescriptor;
90using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
91using android::AidlMessageQueue;
92using android::ProcessState;
93using android::String16;
94using ndk::ScopedAStatus;
95using ndk::SpAIBinder;
96
97using MqDataType = int8_t;
98using MqDataMode = SynchronizedReadWrite;
99using DataMQ = AidlMessageQueue<MqDataType, MqDataMode>;
100using DataMQDesc = MQDescriptor<MqDataType, MqDataMode>;
101
Bao Doc36897d2023-12-06 01:27:54 +0000102using LeAudioAseConfigurationSetting =
103 IBluetoothAudioProvider::LeAudioAseConfigurationSetting;
104using AseDirectionRequirement = IBluetoothAudioProvider::
105 LeAudioConfigurationRequirement::AseDirectionRequirement;
106using AseDirectionConfiguration = IBluetoothAudioProvider::
107 LeAudioAseConfigurationSetting::AseDirectionConfiguration;
108using AseQosDirectionRequirement = IBluetoothAudioProvider::
109 LeAudioAseQosConfigurationRequirement::AseQosDirectionRequirement;
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +0000110using LeAudioAseQosConfigurationRequirement =
111 IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement;
Bao Doc36897d2023-12-06 01:27:54 +0000112using LeAudioAseQosConfiguration =
113 IBluetoothAudioProvider::LeAudioAseQosConfiguration;
114using LeAudioDeviceCapabilities =
115 IBluetoothAudioProvider::LeAudioDeviceCapabilities;
116using LeAudioConfigurationRequirement =
117 IBluetoothAudioProvider::LeAudioConfigurationRequirement;
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +0000118using LeAudioBroadcastConfigurationRequirement =
119 IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement;
120using LeAudioBroadcastSubgroupConfiguration =
121 IBluetoothAudioProvider::LeAudioBroadcastSubgroupConfiguration;
122using LeAudioBroadcastSubgroupConfigurationRequirement =
123 IBluetoothAudioProvider::LeAudioBroadcastSubgroupConfigurationRequirement;
124using LeAudioBroadcastConfigurationSetting =
125 IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting;
126using LeAudioSubgroupBisConfiguration =
127 IBluetoothAudioProvider::LeAudioSubgroupBisConfiguration;
Bao Doc36897d2023-12-06 01:27:54 +0000128
Josh Wu049e2cd2022-01-12 05:42:58 -0800129// Constants
130
131static constexpr int32_t a2dp_sample_rates[] = {0, 44100, 48000, 88200, 96000};
132static constexpr int8_t a2dp_bits_per_samples[] = {0, 16, 24, 32};
133static constexpr ChannelMode a2dp_channel_modes[] = {
134 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
Chen Chenc92270e2022-02-14 18:29:52 -0800135static std::vector<LatencyMode> latency_modes = {LatencyMode::FREE};
Bao Do72399432023-11-09 08:13:05 +0000136
Bao Dob487a852023-12-25 10:12:09 +0800137enum class BluetoothAudioHalVersion : int32_t {
138 VERSION_UNAVAILABLE = 0,
139 VERSION_2_0,
140 VERSION_2_1,
141 VERSION_AIDL_V1,
142 VERSION_AIDL_V2,
143 VERSION_AIDL_V3,
144 VERSION_AIDL_V4,
145};
146
Bao Do72399432023-11-09 08:13:05 +0000147// Some valid configs for HFP PCM configuration (software sessions)
148static constexpr int32_t hfp_sample_rates_[] = {8000, 16000, 32000};
149static constexpr int8_t hfp_bits_per_samples_[] = {16};
150static constexpr ChannelMode hfp_channel_modes_[] = {ChannelMode::MONO};
151static constexpr int32_t hfp_data_interval_us_[] = {7500};
152
Josh Wu049e2cd2022-01-12 05:42:58 -0800153// Helpers
154
155template <typename T>
156struct identity {
157 typedef T type;
158};
159
160template <class T>
161bool contained_in_vector(const std::vector<T>& vector,
162 const typename identity<T>::type& target) {
163 return std::find(vector.begin(), vector.end(), target) != vector.end();
164}
165
166void copy_codec_specific(CodecConfiguration::CodecSpecific& dst,
167 const CodecConfiguration::CodecSpecific& src) {
168 switch (src.getTag()) {
169 case CodecConfiguration::CodecSpecific::sbcConfig:
170 dst.set<CodecConfiguration::CodecSpecific::sbcConfig>(
171 src.get<CodecConfiguration::CodecSpecific::sbcConfig>());
172 break;
173 case CodecConfiguration::CodecSpecific::aacConfig:
174 dst.set<CodecConfiguration::CodecSpecific::aacConfig>(
175 src.get<CodecConfiguration::CodecSpecific::aacConfig>());
176 break;
177 case CodecConfiguration::CodecSpecific::ldacConfig:
178 dst.set<CodecConfiguration::CodecSpecific::ldacConfig>(
179 src.get<CodecConfiguration::CodecSpecific::ldacConfig>());
180 break;
181 case CodecConfiguration::CodecSpecific::aptxConfig:
182 dst.set<CodecConfiguration::CodecSpecific::aptxConfig>(
183 src.get<CodecConfiguration::CodecSpecific::aptxConfig>());
184 break;
Omer Osmana2587da2022-05-01 03:54:11 +0000185 case CodecConfiguration::CodecSpecific::opusConfig:
186 dst.set<CodecConfiguration::CodecSpecific::opusConfig>(
187 src.get<CodecConfiguration::CodecSpecific::opusConfig>());
Josh Wu049e2cd2022-01-12 05:42:58 -0800188 break;
189 case CodecConfiguration::CodecSpecific::aptxAdaptiveConfig:
190 dst.set<CodecConfiguration::CodecSpecific::aptxAdaptiveConfig>(
191 src.get<CodecConfiguration::CodecSpecific::aptxAdaptiveConfig>());
192 break;
193 default:
194 break;
195 }
196}
197
Jakub Tyszkowski11178a62024-06-18 10:07:26 +0000198static std::optional<CodecSpecificConfigurationLtv> GetConfigurationLtv(
199 const std::vector<CodecSpecificConfigurationLtv>& configurationLtvs,
200 CodecSpecificConfigurationLtv::Tag tag) {
201 for (const auto ltv : configurationLtvs) {
202 if (ltv.getTag() == tag) {
203 return ltv;
204 }
205 }
206 return std::nullopt;
207}
208
Josh Wu049e2cd2022-01-12 05:42:58 -0800209class BluetoothAudioPort : public BnBluetoothAudioPort {
210 public:
211 BluetoothAudioPort() {}
212
Chen Chen0a68a922022-02-15 18:43:26 -0800213 ndk::ScopedAStatus startStream(bool) { return ScopedAStatus::ok(); }
Josh Wu049e2cd2022-01-12 05:42:58 -0800214
215 ndk::ScopedAStatus suspendStream() { return ScopedAStatus::ok(); }
216
217 ndk::ScopedAStatus stopStream() { return ScopedAStatus::ok(); }
218
219 ndk::ScopedAStatus getPresentationPosition(PresentationPosition*) {
220 return ScopedAStatus::ok();
221 }
222
223 ndk::ScopedAStatus updateSourceMetadata(const SourceMetadata&) {
224 return ScopedAStatus::ok();
225 }
226
227 ndk::ScopedAStatus updateSinkMetadata(const SinkMetadata&) {
228 return ScopedAStatus::ok();
229 }
230
231 ndk::ScopedAStatus setLatencyMode(const LatencyMode) {
232 return ScopedAStatus::ok();
233 }
234
235 ndk::ScopedAStatus setCodecType(const CodecType) {
236 return ScopedAStatus::ok();
237 }
238
239 protected:
240 virtual ~BluetoothAudioPort() = default;
241};
242
243class BluetoothAudioProviderFactoryAidl
244 : public testing::TestWithParam<std::string> {
245 public:
246 virtual void SetUp() override {
247 provider_factory_ = IBluetoothAudioProviderFactory::fromBinder(
248 SpAIBinder(AServiceManager_getService(GetParam().c_str())));
249 audio_provider_ = nullptr;
250 ASSERT_NE(provider_factory_, nullptr);
251 }
252
253 virtual void TearDown() override { provider_factory_ = nullptr; }
254
Bao Doc36897d2023-12-06 01:27:54 +0000255 void GetProviderInfoHelper(const SessionType& session_type) {
256 temp_provider_info_ = std::nullopt;
257 auto aidl_reval =
258 provider_factory_->getProviderInfo(session_type, &temp_provider_info_);
Bao Doc36897d2023-12-06 01:27:54 +0000259 }
260
Josh Wu049e2cd2022-01-12 05:42:58 -0800261 void GetProviderCapabilitiesHelper(const SessionType& session_type) {
262 temp_provider_capabilities_.clear();
263 auto aidl_retval = provider_factory_->getProviderCapabilities(
264 session_type, &temp_provider_capabilities_);
265 // AIDL calls should not be failed and callback has to be executed
266 ASSERT_TRUE(aidl_retval.isOk());
267 switch (session_type) {
268 case SessionType::UNKNOWN: {
269 ASSERT_TRUE(temp_provider_capabilities_.empty());
270 } break;
271 case SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH:
272 case SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH:
273 case SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH:
274 case SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH:
Bao Do72399432023-11-09 08:13:05 +0000275 case SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH:
276 case SessionType::HFP_SOFTWARE_ENCODING_DATAPATH: {
Josh Wu049e2cd2022-01-12 05:42:58 -0800277 // All software paths are mandatory and must have exact 1
278 // "PcmParameters"
279 ASSERT_EQ(temp_provider_capabilities_.size(), 1);
280 ASSERT_EQ(temp_provider_capabilities_[0].getTag(),
281 AudioCapabilities::pcmCapabilities);
282 } break;
Alice Kuoadcceec2022-03-28 13:28:43 +0800283 case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
284 case SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH: {
Josh Wu049e2cd2022-01-12 05:42:58 -0800285 std::unordered_set<CodecType> codec_types;
286 // empty capability means offload is unsupported
287 for (auto& audio_capability : temp_provider_capabilities_) {
288 ASSERT_EQ(audio_capability.getTag(),
289 AudioCapabilities::a2dpCapabilities);
290 const auto& codec_capabilities =
291 audio_capability.get<AudioCapabilities::a2dpCapabilities>();
292 // Every codec can present once at most
293 ASSERT_EQ(codec_types.count(codec_capabilities.codecType), 0);
294 switch (codec_capabilities.codecType) {
295 case CodecType::SBC:
296 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
297 CodecCapabilities::Capabilities::sbcCapabilities);
298 break;
299 case CodecType::AAC:
300 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
301 CodecCapabilities::Capabilities::aacCapabilities);
302 break;
303 case CodecType::APTX:
304 case CodecType::APTX_HD:
305 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
306 CodecCapabilities::Capabilities::aptxCapabilities);
307 break;
308 case CodecType::LDAC:
309 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
310 CodecCapabilities::Capabilities::ldacCapabilities);
311 break;
Omer Osmana2587da2022-05-01 03:54:11 +0000312 case CodecType::OPUS:
Josh Wu049e2cd2022-01-12 05:42:58 -0800313 ASSERT_EQ(codec_capabilities.capabilities.getTag(),
Omer Osmana2587da2022-05-01 03:54:11 +0000314 CodecCapabilities::Capabilities::opusCapabilities);
Josh Wu049e2cd2022-01-12 05:42:58 -0800315 break;
316 case CodecType::APTX_ADAPTIVE:
Sagar Verma62df9102022-12-07 17:56:04 +0530317 case CodecType::APTX_ADAPTIVE_LE:
318 case CodecType::APTX_ADAPTIVE_LEX:
Omer Osmana2587da2022-05-01 03:54:11 +0000319 case CodecType::LC3:
Josh Wu049e2cd2022-01-12 05:42:58 -0800320 case CodecType::VENDOR:
321 case CodecType::UNKNOWN:
322 break;
323 }
324 codec_types.insert(codec_capabilities.codecType);
325 }
326 } break;
327 case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
328 case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
329 case SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH: {
shihchienc3ab9f5e2022-09-23 08:18:05 +0000330 // empty capability means offload is unsupported since capabilities are
331 // not hardcoded
Josh Wu049e2cd2022-01-12 05:42:58 -0800332 for (auto audio_capability : temp_provider_capabilities_) {
333 ASSERT_EQ(audio_capability.getTag(),
334 AudioCapabilities::leAudioCapabilities);
335 }
336 } break;
Bao Do72399432023-11-09 08:13:05 +0000337 case SessionType::A2DP_SOFTWARE_DECODING_DATAPATH:
338 case SessionType::HFP_SOFTWARE_DECODING_DATAPATH: {
Alice Kuoadcceec2022-03-28 13:28:43 +0800339 if (!temp_provider_capabilities_.empty()) {
340 ASSERT_EQ(temp_provider_capabilities_.size(), 1);
341 ASSERT_EQ(temp_provider_capabilities_[0].getTag(),
342 AudioCapabilities::pcmCapabilities);
343 }
344 } break;
345 default: {
346 ASSERT_TRUE(temp_provider_capabilities_.empty());
347 }
Josh Wu049e2cd2022-01-12 05:42:58 -0800348 }
349 }
350
351 /***
352 * This helps to open the specified provider and check the openProvider()
353 * has corruct return values. BUT, to keep it simple, it does not consider
354 * the capability, and please do so at the SetUp of each session's test.
355 ***/
356 void OpenProviderHelper(const SessionType& session_type) {
357 auto aidl_retval =
358 provider_factory_->openProvider(session_type, &audio_provider_);
359 if (aidl_retval.isOk()) {
360 ASSERT_NE(session_type, SessionType::UNKNOWN);
361 ASSERT_NE(audio_provider_, nullptr);
362 audio_port_ = ndk::SharedRefBase::make<BluetoothAudioPort>();
363 } else {
Alice Kuoadcceec2022-03-28 13:28:43 +0800364 // optional session type
Josh Wu049e2cd2022-01-12 05:42:58 -0800365 ASSERT_TRUE(
366 session_type == SessionType::UNKNOWN ||
367 session_type ==
368 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
369 session_type ==
370 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
371 session_type ==
372 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
373 session_type ==
374 SessionType::
Alice Kuoadcceec2022-03-28 13:28:43 +0800375 LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
376 session_type ==
377 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
Bao Do72399432023-11-09 08:13:05 +0000378 session_type == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH ||
379 session_type == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH ||
380 session_type == SessionType::HFP_SOFTWARE_DECODING_DATAPATH ||
381 session_type == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH);
Josh Wu049e2cd2022-01-12 05:42:58 -0800382 ASSERT_EQ(audio_provider_, nullptr);
383 }
384 }
385
Josh Wu049e2cd2022-01-12 05:42:58 -0800386 void GetA2dpOffloadCapabilityHelper(const CodecType& codec_type) {
387 temp_codec_capabilities_ = nullptr;
Josh Wu4d2938f2022-02-15 09:21:10 -0800388 for (auto& codec_capability : temp_provider_capabilities_) {
Josh Wu049e2cd2022-01-12 05:42:58 -0800389 auto& a2dp_capabilities =
390 codec_capability.get<AudioCapabilities::a2dpCapabilities>();
391 if (a2dp_capabilities.codecType != codec_type) {
392 continue;
393 }
394 temp_codec_capabilities_ = &a2dp_capabilities;
395 }
396 }
397
398 std::vector<CodecConfiguration::CodecSpecific>
399 GetSbcCodecSpecificSupportedList(bool supported) {
400 std::vector<CodecConfiguration::CodecSpecific> sbc_codec_specifics;
401 if (!supported) {
402 SbcConfiguration sbc_config{.sampleRateHz = 0, .bitsPerSample = 0};
403 sbc_codec_specifics.push_back(
404 CodecConfiguration::CodecSpecific(sbc_config));
405 return sbc_codec_specifics;
406 }
407 GetA2dpOffloadCapabilityHelper(CodecType::SBC);
408 if (temp_codec_capabilities_ == nullptr ||
409 temp_codec_capabilities_->codecType != CodecType::SBC) {
410 return sbc_codec_specifics;
411 }
412 // parse the capability
413 auto& sbc_capability =
414 temp_codec_capabilities_->capabilities
415 .get<CodecCapabilities::Capabilities::sbcCapabilities>();
416 if (sbc_capability.minBitpool > sbc_capability.maxBitpool) {
417 return sbc_codec_specifics;
418 }
419
420 // combine those parameters into one list of
421 // CodecConfiguration::CodecSpecific
422 for (int32_t sample_rate : sbc_capability.sampleRateHz) {
423 for (int8_t block_length : sbc_capability.blockLength) {
424 for (int8_t num_subbands : sbc_capability.numSubbands) {
425 for (int8_t bits_per_sample : sbc_capability.bitsPerSample) {
426 for (auto channel_mode : sbc_capability.channelMode) {
427 for (auto alloc_method : sbc_capability.allocMethod) {
428 SbcConfiguration sbc_data = {
429 .sampleRateHz = sample_rate,
430 .channelMode = channel_mode,
431 .blockLength = block_length,
432 .numSubbands = num_subbands,
433 .allocMethod = alloc_method,
434 .bitsPerSample = bits_per_sample,
435 .minBitpool = sbc_capability.minBitpool,
436 .maxBitpool = sbc_capability.maxBitpool};
437 sbc_codec_specifics.push_back(
438 CodecConfiguration::CodecSpecific(sbc_data));
439 }
440 }
441 }
442 }
443 }
444 }
445 return sbc_codec_specifics;
446 }
447
448 std::vector<CodecConfiguration::CodecSpecific>
449 GetAacCodecSpecificSupportedList(bool supported) {
450 std::vector<CodecConfiguration::CodecSpecific> aac_codec_specifics;
451 if (!supported) {
452 AacConfiguration aac_config{.sampleRateHz = 0, .bitsPerSample = 0};
453 aac_codec_specifics.push_back(
454 CodecConfiguration::CodecSpecific(aac_config));
455 return aac_codec_specifics;
456 }
457 GetA2dpOffloadCapabilityHelper(CodecType::AAC);
458 if (temp_codec_capabilities_ == nullptr ||
459 temp_codec_capabilities_->codecType != CodecType::AAC) {
460 return aac_codec_specifics;
461 }
462 // parse the capability
463 auto& aac_capability =
464 temp_codec_capabilities_->capabilities
465 .get<CodecCapabilities::Capabilities::aacCapabilities>();
466
467 std::vector<bool> variable_bit_rate_enableds = {false};
468 if (aac_capability.variableBitRateSupported) {
469 variable_bit_rate_enableds.push_back(true);
470 }
471
Sagar Verma62df9102022-12-07 17:56:04 +0530472 std::vector<bool> adaptive_bit_rate_supporteds = {false};
473 if (aac_capability.adaptiveBitRateSupported) {
474 adaptive_bit_rate_supporteds.push_back(true);
475 }
476
Josh Wu049e2cd2022-01-12 05:42:58 -0800477 // combine those parameters into one list of
478 // CodecConfiguration::CodecSpecific
479 for (auto object_type : aac_capability.objectType) {
480 for (int32_t sample_rate : aac_capability.sampleRateHz) {
481 for (auto channel_mode : aac_capability.channelMode) {
482 for (int8_t bits_per_sample : aac_capability.bitsPerSample) {
483 for (auto variable_bit_rate_enabled : variable_bit_rate_enableds) {
Sagar Verma62df9102022-12-07 17:56:04 +0530484 for (auto adaptive_bit_rate_supported :
485 adaptive_bit_rate_supporteds) {
486 AacConfiguration aac_data{
487 .objectType = object_type,
488 .sampleRateHz = sample_rate,
489 .channelMode = channel_mode,
490 .variableBitRateEnabled = variable_bit_rate_enabled,
491 .bitsPerSample = bits_per_sample,
492 .adaptiveBitRateSupported = adaptive_bit_rate_supported};
493 aac_codec_specifics.push_back(
494 CodecConfiguration::CodecSpecific(aac_data));
495 }
Josh Wu049e2cd2022-01-12 05:42:58 -0800496 }
497 }
498 }
499 }
500 }
501 return aac_codec_specifics;
502 }
503
504 std::vector<CodecConfiguration::CodecSpecific>
505 GetLdacCodecSpecificSupportedList(bool supported) {
506 std::vector<CodecConfiguration::CodecSpecific> ldac_codec_specifics;
507 if (!supported) {
508 LdacConfiguration ldac_config{.sampleRateHz = 0, .bitsPerSample = 0};
509 ldac_codec_specifics.push_back(
510 CodecConfiguration::CodecSpecific(ldac_config));
511 return ldac_codec_specifics;
512 }
513 GetA2dpOffloadCapabilityHelper(CodecType::LDAC);
514 if (temp_codec_capabilities_ == nullptr ||
515 temp_codec_capabilities_->codecType != CodecType::LDAC) {
516 return ldac_codec_specifics;
517 }
518 // parse the capability
519 auto& ldac_capability =
520 temp_codec_capabilities_->capabilities
521 .get<CodecCapabilities::Capabilities::ldacCapabilities>();
522
523 // combine those parameters into one list of
524 // CodecConfiguration::CodecSpecific
525 for (int32_t sample_rate : ldac_capability.sampleRateHz) {
526 for (int8_t bits_per_sample : ldac_capability.bitsPerSample) {
527 for (auto channel_mode : ldac_capability.channelMode) {
528 for (auto quality_index : ldac_capability.qualityIndex) {
529 LdacConfiguration ldac_data{.sampleRateHz = sample_rate,
530 .channelMode = channel_mode,
531 .qualityIndex = quality_index,
532 .bitsPerSample = bits_per_sample};
533 ldac_codec_specifics.push_back(
534 CodecConfiguration::CodecSpecific(ldac_data));
535 }
536 }
537 }
538 }
539 return ldac_codec_specifics;
540 }
541
542 std::vector<CodecConfiguration::CodecSpecific>
543 GetAptxCodecSpecificSupportedList(bool is_hd, bool supported) {
544 std::vector<CodecConfiguration::CodecSpecific> aptx_codec_specifics;
545 if (!supported) {
546 AptxConfiguration aptx_config{.sampleRateHz = 0, .bitsPerSample = 0};
547 aptx_codec_specifics.push_back(
548 CodecConfiguration::CodecSpecific(aptx_config));
549 return aptx_codec_specifics;
550 }
551 GetA2dpOffloadCapabilityHelper(
552 (is_hd ? CodecType::APTX_HD : CodecType::APTX));
553 if (temp_codec_capabilities_ == nullptr) {
554 return aptx_codec_specifics;
555 }
556 if ((is_hd && temp_codec_capabilities_->codecType != CodecType::APTX_HD) ||
557 (!is_hd && temp_codec_capabilities_->codecType != CodecType::APTX)) {
558 return aptx_codec_specifics;
559 }
560
561 // parse the capability
562 auto& aptx_capability =
563 temp_codec_capabilities_->capabilities
564 .get<CodecCapabilities::Capabilities::aptxCapabilities>();
565
566 // combine those parameters into one list of
567 // CodecConfiguration::CodecSpecific
568 for (int8_t bits_per_sample : aptx_capability.bitsPerSample) {
569 for (int32_t sample_rate : aptx_capability.sampleRateHz) {
570 for (auto channel_mode : aptx_capability.channelMode) {
571 AptxConfiguration aptx_data{.sampleRateHz = sample_rate,
572 .channelMode = channel_mode,
573 .bitsPerSample = bits_per_sample};
574 aptx_codec_specifics.push_back(
575 CodecConfiguration::CodecSpecific(aptx_data));
576 }
577 }
578 }
579 return aptx_codec_specifics;
580 }
581
582 std::vector<CodecConfiguration::CodecSpecific>
Omer Osmana2587da2022-05-01 03:54:11 +0000583 GetOpusCodecSpecificSupportedList(bool supported) {
584 std::vector<CodecConfiguration::CodecSpecific> opus_codec_specifics;
Josh Wu049e2cd2022-01-12 05:42:58 -0800585 if (!supported) {
Omer Osmana2587da2022-05-01 03:54:11 +0000586 OpusConfiguration opus_config{.samplingFrequencyHz = 0,
587 .frameDurationUs = 0};
588 opus_codec_specifics.push_back(
589 CodecConfiguration::CodecSpecific(opus_config));
590 return opus_codec_specifics;
Josh Wu049e2cd2022-01-12 05:42:58 -0800591 }
Omer Osmana2587da2022-05-01 03:54:11 +0000592 GetA2dpOffloadCapabilityHelper(CodecType::OPUS);
Josh Wu049e2cd2022-01-12 05:42:58 -0800593 if (temp_codec_capabilities_ == nullptr ||
Omer Osmana2587da2022-05-01 03:54:11 +0000594 temp_codec_capabilities_->codecType != CodecType::OPUS) {
595 return opus_codec_specifics;
Josh Wu049e2cd2022-01-12 05:42:58 -0800596 }
597 // parse the capability
Omer Osmana2587da2022-05-01 03:54:11 +0000598 auto& opus_capability =
Josh Wu049e2cd2022-01-12 05:42:58 -0800599 temp_codec_capabilities_->capabilities
Omer Osmana2587da2022-05-01 03:54:11 +0000600 .get<CodecCapabilities::Capabilities::opusCapabilities>();
Josh Wu049e2cd2022-01-12 05:42:58 -0800601
602 // combine those parameters into one list of
603 // CodecConfiguration::CodecSpecific
Omer Osmana2587da2022-05-01 03:54:11 +0000604 for (int32_t samplingFrequencyHz : opus_capability->samplingFrequencyHz) {
605 for (int32_t frameDurationUs : opus_capability->frameDurationUs) {
606 for (auto channel_mode : opus_capability->channelMode) {
607 OpusConfiguration opus_data{
608 .samplingFrequencyHz = samplingFrequencyHz,
shihchienc3ab9f5e2022-09-23 08:18:05 +0000609 .frameDurationUs = frameDurationUs,
Omer Osmana2587da2022-05-01 03:54:11 +0000610 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +0000611 };
Omer Osmana2587da2022-05-01 03:54:11 +0000612 opus_codec_specifics.push_back(
613 CodecConfiguration::CodecSpecific(opus_data));
Josh Wu049e2cd2022-01-12 05:42:58 -0800614 }
615 }
616 }
Omer Osmana2587da2022-05-01 03:54:11 +0000617 return opus_codec_specifics;
Josh Wu049e2cd2022-01-12 05:42:58 -0800618 }
619
Alice Kuoadcceec2022-03-28 13:28:43 +0800620 bool IsPcmConfigSupported(const PcmConfiguration& pcm_config) {
621 if (temp_provider_capabilities_.size() != 1 ||
622 temp_provider_capabilities_[0].getTag() !=
623 AudioCapabilities::pcmCapabilities) {
624 return false;
625 }
626 auto pcm_capability = temp_provider_capabilities_[0]
627 .get<AudioCapabilities::pcmCapabilities>();
628 return (contained_in_vector(pcm_capability.channelMode,
629 pcm_config.channelMode) &&
630 contained_in_vector(pcm_capability.sampleRateHz,
631 pcm_config.sampleRateHz) &&
632 contained_in_vector(pcm_capability.bitsPerSample,
633 pcm_config.bitsPerSample));
634 }
635
636 std::shared_ptr<IBluetoothAudioProviderFactory> provider_factory_;
637 std::shared_ptr<IBluetoothAudioProvider> audio_provider_;
638 std::shared_ptr<IBluetoothAudioPort> audio_port_;
639 std::vector<AudioCapabilities> temp_provider_capabilities_;
Bao Doc36897d2023-12-06 01:27:54 +0000640 std::optional<IBluetoothAudioProviderFactory::ProviderInfo>
641 temp_provider_info_;
Alice Kuoadcceec2022-03-28 13:28:43 +0800642
Josh Wu049e2cd2022-01-12 05:42:58 -0800643 // temp storage saves the specified codec capability by
644 // GetOffloadCodecCapabilityHelper()
645 CodecCapabilities* temp_codec_capabilities_;
Alice Kuoadcceec2022-03-28 13:28:43 +0800646
647 static constexpr SessionType kSessionTypes[] = {
648 SessionType::UNKNOWN,
649 SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
650 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
651 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
652 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
653 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
654 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
655 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
656 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
657 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
658 SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
659 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
Bao Dob487a852023-12-25 10:12:09 +0800660 };
661
662 static constexpr SessionType kAndroidVSessionType[] = {
Bao Do72399432023-11-09 08:13:05 +0000663 SessionType::HFP_SOFTWARE_ENCODING_DATAPATH,
664 SessionType::HFP_SOFTWARE_DECODING_DATAPATH,
Alice Kuoadcceec2022-03-28 13:28:43 +0800665 };
Bao Dob487a852023-12-25 10:12:09 +0800666
667 BluetoothAudioHalVersion GetProviderFactoryInterfaceVersion() {
668 int32_t aidl_version = 0;
669 if (provider_factory_ == nullptr) {
670 return BluetoothAudioHalVersion::VERSION_UNAVAILABLE;
671 }
672
673 auto aidl_retval = provider_factory_->getInterfaceVersion(&aidl_version);
674 if (!aidl_retval.isOk()) {
675 return BluetoothAudioHalVersion::VERSION_UNAVAILABLE;
676 }
677 switch (aidl_version) {
678 case 1:
679 return BluetoothAudioHalVersion::VERSION_AIDL_V1;
680 case 2:
681 return BluetoothAudioHalVersion::VERSION_AIDL_V2;
682 case 3:
683 return BluetoothAudioHalVersion::VERSION_AIDL_V3;
684 case 4:
685 return BluetoothAudioHalVersion::VERSION_AIDL_V4;
686 default:
687 return BluetoothAudioHalVersion::VERSION_UNAVAILABLE;
688 }
689
690 return BluetoothAudioHalVersion::VERSION_UNAVAILABLE;
691 }
Alice Kuoadcceec2022-03-28 13:28:43 +0800692};
693
694/**
695 * Test whether we can get the FactoryService from HIDL
696 */
697TEST_P(BluetoothAudioProviderFactoryAidl, GetProviderFactoryService) {}
698
699/**
700 * Test whether we can open a provider for each provider returned by
701 * getProviderCapabilities() with non-empty capabalities
702 */
703TEST_P(BluetoothAudioProviderFactoryAidl,
704 OpenProviderAndCheckCapabilitiesBySession) {
705 for (auto session_type : kSessionTypes) {
706 GetProviderCapabilitiesHelper(session_type);
707 OpenProviderHelper(session_type);
708 // We must be able to open a provider if its getProviderCapabilities()
709 // returns non-empty list.
710 EXPECT_TRUE(temp_provider_capabilities_.empty() ||
711 audio_provider_ != nullptr);
712 }
Bao Dob487a852023-12-25 10:12:09 +0800713 if (GetProviderFactoryInterfaceVersion() >=
714 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
715 for (auto session_type : kAndroidVSessionType) {
716 GetProviderCapabilitiesHelper(session_type);
717 OpenProviderHelper(session_type);
718 EXPECT_TRUE(temp_provider_capabilities_.empty() ||
719 audio_provider_ != nullptr);
720 }
721 }
Alice Kuoadcceec2022-03-28 13:28:43 +0800722}
723
724/**
Antoine SOULIER8c90f1f2023-09-26 18:55:17 +0000725 * Test that getProviderInfo, when implemented,
726 * returns empty information for session types for
727 * software data paths.
728 */
729TEST_P(BluetoothAudioProviderFactoryAidl, getProviderInfo_invalidSessionTypes) {
730 static constexpr SessionType kInvalidSessionTypes[]{
731 SessionType::UNKNOWN,
732 SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
733 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
734 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
735 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
736 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
737 SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
738 };
739
740 for (auto session_type : kInvalidSessionTypes) {
741 std::optional<IBluetoothAudioProviderFactory::ProviderInfo> provider_info =
742 std::nullopt;
743 auto aidl_retval =
744 provider_factory_->getProviderInfo(session_type, &provider_info);
745 if (!aidl_retval.isOk()) {
746 continue;
747 }
748
749 // If getProviderInfo is supported, the provider info
750 // must be empty for software session types.
751 ASSERT_FALSE(provider_info.has_value());
752 }
753}
754
755/**
756 * Test that getProviderInfo, when implemented,
757 * returns valid information for session types for
758 * a2dp hardware data paths.
759 */
760TEST_P(BluetoothAudioProviderFactoryAidl, getProviderInfo_a2dpSessionTypes) {
761 static constexpr SessionType kA2dpSessionTypes[]{
762 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
763 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
764 };
765
766 for (auto session_type : kA2dpSessionTypes) {
767 std::optional<IBluetoothAudioProviderFactory::ProviderInfo> provider_info =
768 std::nullopt;
769 auto aidl_retval =
770 provider_factory_->getProviderInfo(session_type, &provider_info);
771 if (!aidl_retval.isOk() || !provider_info.has_value()) {
772 continue;
773 }
774
775 for (auto const& codec_info : provider_info->codecInfos) {
776 // The codec id must not be core.
777 ASSERT_NE(codec_info.id.getTag(), CodecId::core);
778 // The codec info must contain the information
779 // for a2dp transport.
780 ASSERT_EQ(codec_info.transport.getTag(), CodecInfo::Transport::a2dp);
781 }
782 }
783}
784
785/**
786 * Test that getProviderInfo, when implemented,
787 * returns valid information for session types for
788 * le audio hardware data paths.
789 */
790TEST_P(BluetoothAudioProviderFactoryAidl, getProviderInfo_leAudioSessionTypes) {
791 static constexpr SessionType kLeAudioSessionTypes[]{
792 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
793 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
794 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
795 };
796
797 for (auto session_type : kLeAudioSessionTypes) {
798 std::optional<IBluetoothAudioProviderFactory::ProviderInfo> provider_info =
799 std::nullopt;
800 auto aidl_retval =
801 provider_factory_->getProviderInfo(session_type, &provider_info);
802 if (!aidl_retval.isOk() || !provider_info.has_value()) {
803 continue;
804 }
805
806 for (auto const& codec_info : provider_info->codecInfos) {
807 // The codec id must not be a2dp.
808 ASSERT_NE(codec_info.id.getTag(), CodecId::a2dp);
809 // The codec info must contain the information
810 // for le audio transport.
Jakub Tyszkowski06781c02024-01-08 13:16:42 +0000811 ASSERT_EQ(codec_info.transport.getTag(), CodecInfo::Transport::leAudio);
Antoine SOULIER8c90f1f2023-09-26 18:55:17 +0000812 }
813 }
814}
815
Antoine SOULIER33c4e5a2023-09-28 21:59:19 +0000816class BluetoothAudioProviderAidl : public BluetoothAudioProviderFactoryAidl {
817 protected:
818 std::optional<IBluetoothAudioProviderFactory::ProviderInfo>
819 a2dp_encoding_provider_info_{};
820 std::optional<IBluetoothAudioProviderFactory::ProviderInfo>
821 a2dp_decoding_provider_info_{};
822 std::shared_ptr<IBluetoothAudioProvider> a2dp_encoding_provider_{nullptr};
823 std::shared_ptr<IBluetoothAudioProvider> a2dp_decoding_provider_{nullptr};
824
825 public:
826 void SetUp() override {
827 BluetoothAudioProviderFactoryAidl::SetUp();
828 audio_port_ = ndk::SharedRefBase::make<BluetoothAudioPort>();
829
830 (void)provider_factory_->getProviderInfo(
831 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
832 &a2dp_encoding_provider_info_);
833
834 (void)provider_factory_->getProviderInfo(
835 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
836 &a2dp_decoding_provider_info_);
837
838 (void)provider_factory_->openProvider(
839 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
840 &a2dp_encoding_provider_);
841
842 (void)provider_factory_->openProvider(
843 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
844 &a2dp_decoding_provider_);
845 }
846};
847
848/**
849 * Calling parseA2dpConfiguration on a session of a different type than
850 * A2DP_HARDWARE_OFFLOAD_(ENCODING|DECODING)_DATAPATH must fail.
851 */
852TEST_P(BluetoothAudioProviderAidl, parseA2dpConfiguration_invalidSessionType) {
853 static constexpr SessionType kInvalidSessionTypes[] = {
854 SessionType::UNKNOWN,
855 SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
856 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
857 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
858 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
859 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
860 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
861 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
862 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
863 SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
864 };
865
866 for (auto session_type : kInvalidSessionTypes) {
867 // Open a BluetoothAudioProvider instance of the selected session type.
868 // Skip validation if the provider cannot be opened.
869 std::shared_ptr<IBluetoothAudioProvider> provider{nullptr};
870 (void)provider_factory_->openProvider(session_type, &provider);
871 if (provider == nullptr) {
872 continue;
873 }
874
875 // parseA2dpConfiguration must fail without returning an A2dpStatus.
876 CodecId codec_id(CodecId::A2dp::SBC);
877 CodecParameters codec_parameters;
878 A2dpStatus a2dp_status = A2dpStatus::OK;
879 auto aidl_retval = provider->parseA2dpConfiguration(
880 codec_id, std::vector<uint8_t>{}, &codec_parameters, &a2dp_status);
881 EXPECT_FALSE(aidl_retval.isOk());
882 }
883}
884
885/**
886 * Calling parseA2dpConfiguration with an unknown codec must fail
887 * with the A2dpStatus code INVALID_CODEC_TYPE or NOT_SUPPORTED_CODEC_TYPE.
888 */
889TEST_P(BluetoothAudioProviderAidl,
890 parseA2dpConfiguration_unsupportedCodecType) {
891 CodecId unsupported_core_id(CodecId::Core::CVSD);
892 CodecId unsupported_vendor_id(
893 CodecId::Vendor(0xFCB1, 0x42)); // Google Codec #42
894
895 for (auto& provider : {a2dp_encoding_provider_, a2dp_decoding_provider_}) {
896 if (provider == nullptr) {
897 continue;
898 }
899
900 CodecParameters codec_parameters;
901 A2dpStatus a2dp_status = A2dpStatus::OK;
902 ::ndk::ScopedAStatus aidl_retval;
903
904 // Test with two invalid codec identifiers: vendor or core.
905 aidl_retval = provider->parseA2dpConfiguration(
906 unsupported_core_id, std::vector<uint8_t>{}, &codec_parameters,
907 &a2dp_status);
908 EXPECT_TRUE(!aidl_retval.isOk() ||
909 a2dp_status == A2dpStatus::NOT_SUPPORTED_CODEC_TYPE);
910
911 aidl_retval = provider->parseA2dpConfiguration(
912 unsupported_vendor_id, std::vector<uint8_t>{}, &codec_parameters,
913 &a2dp_status);
914 EXPECT_TRUE(!aidl_retval.isOk() ||
915 a2dp_status == A2dpStatus::NOT_SUPPORTED_CODEC_TYPE);
916 }
917}
918
919/**
920 * Calling parseA2dpConfiguration with a known codec and invalid configuration
921 * must fail with an A2dpStatus code different from INVALID_CODEC_TYPE or
922 * NOT_SUPPORTED_CODEC_TYPE.
923 */
924TEST_P(BluetoothAudioProviderAidl,
925 parseA2dpConfiguration_invalidConfiguration) {
926 for (auto& [provider, provider_info] :
927 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
928 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
929 if (provider == nullptr || !provider_info.has_value() ||
930 provider_info->codecInfos.empty()) {
931 continue;
932 }
933
934 CodecParameters codec_parameters;
935 A2dpStatus a2dp_status = A2dpStatus::OK;
936 ::ndk::ScopedAStatus aidl_retval;
937
938 // Test with the first available codec in the provider info for testing.
939 // The test runs with an empty parameters array, anything more specific
940 // would need understanding the codec.
941 aidl_retval = provider->parseA2dpConfiguration(
942 provider_info->codecInfos[0].id, std::vector<uint8_t>{},
943 &codec_parameters, &a2dp_status);
944 ASSERT_TRUE(aidl_retval.isOk());
945 EXPECT_TRUE(a2dp_status != A2dpStatus::OK &&
946 a2dp_status != A2dpStatus::NOT_SUPPORTED_CODEC_TYPE &&
947 a2dp_status != A2dpStatus::INVALID_CODEC_TYPE);
948 }
949}
950
951/**
952 * Calling parseA2dpConfiguration with a known codec and valid parameters
953 * must return with A2dpStatus OK.
954 */
955TEST_P(BluetoothAudioProviderAidl, parseA2dpConfiguration_valid) {
956 for (auto& [provider, provider_info] :
957 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
958 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
959 if (provider == nullptr || !provider_info.has_value() ||
960 provider_info->codecInfos.empty()) {
961 continue;
962 }
963
964 CodecParameters codec_parameters;
965 A2dpStatus a2dp_status = A2dpStatus::OK;
966 ::ndk::ScopedAStatus aidl_retval;
967
968 // Test with the first available codec in the provider info for testing.
969 // To get a valid configuration (the capabilities array in the provider
970 // info is not a selection), getA2dpConfiguration is used with the
971 // selected codec parameters as input.
972 auto const& codec_info = provider_info->codecInfos[0];
973 auto transport = codec_info.transport.get<CodecInfo::Transport::a2dp>();
974 A2dpRemoteCapabilities remote_capabilities(/*seid*/ 0, codec_info.id,
975 transport.capabilities);
976 std::optional<A2dpConfiguration> configuration;
977 aidl_retval = provider->getA2dpConfiguration(
978 std::vector<A2dpRemoteCapabilities>{remote_capabilities},
979 A2dpConfigurationHint(), &configuration);
980 ASSERT_TRUE(aidl_retval.isOk());
981 ASSERT_TRUE(configuration.has_value());
982
983 aidl_retval = provider->parseA2dpConfiguration(
984 configuration->id, configuration->configuration, &codec_parameters,
985 &a2dp_status);
986 ASSERT_TRUE(aidl_retval.isOk());
987 EXPECT_TRUE(a2dp_status == A2dpStatus::OK);
988 EXPECT_EQ(codec_parameters, configuration->parameters);
989 }
990}
991
992/**
993 * Calling getA2dpConfiguration on a session of a different type than
994 * A2DP_HARDWARE_OFFLOAD_(ENCODING|DECODING)_DATAPATH must fail.
995 */
996TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_invalidSessionType) {
997 static constexpr SessionType kInvalidSessionTypes[] = {
998 SessionType::UNKNOWN,
999 SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
1000 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
1001 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
1002 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
1003 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
1004 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
1005 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
1006 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
1007 SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
1008 };
1009
1010 for (auto session_type : kInvalidSessionTypes) {
1011 // Open a BluetoothAudioProvider instance of the selected session type.
1012 // Skip validation if the provider cannot be opened.
1013 std::shared_ptr<IBluetoothAudioProvider> provider{nullptr};
1014 auto aidl_retval = provider_factory_->openProvider(session_type, &provider);
1015 if (provider == nullptr) {
1016 continue;
1017 }
1018
1019 // getA2dpConfiguration must fail without returning a configuration.
1020 std::optional<A2dpConfiguration> configuration;
1021 aidl_retval =
1022 provider->getA2dpConfiguration(std::vector<A2dpRemoteCapabilities>{},
1023 A2dpConfigurationHint(), &configuration);
1024 EXPECT_FALSE(aidl_retval.isOk());
1025 }
1026}
1027
1028/**
1029 * Calling getA2dpConfiguration with empty or unknown remote capabilities
1030 * must return an empty configuration.
1031 */
1032TEST_P(BluetoothAudioProviderAidl,
1033 getA2dpConfiguration_unknownRemoteCapabilities) {
1034 for (auto& [provider, provider_info] :
1035 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1036 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1037 if (provider == nullptr || !provider_info.has_value() ||
1038 provider_info->codecInfos.empty()) {
1039 continue;
1040 }
1041
1042 std::optional<A2dpConfiguration> configuration;
1043 ::ndk::ScopedAStatus aidl_retval;
1044
1045 // Test with empty remote capabilities.
1046 aidl_retval =
1047 provider->getA2dpConfiguration(std::vector<A2dpRemoteCapabilities>{},
1048 A2dpConfigurationHint(), &configuration);
1049 ASSERT_TRUE(aidl_retval.isOk());
1050 EXPECT_FALSE(configuration.has_value());
1051
1052 // Test with unknown remote capabilities.
1053 A2dpRemoteCapabilities unknown_core_remote_capabilities(
1054 /*seid*/ 0, CodecId::Core::CVSD, std::vector<uint8_t>{1, 2, 3});
1055 A2dpRemoteCapabilities unknown_vendor_remote_capabilities(
1056 /*seid*/ 1,
1057 /* Google Codec #42 */ CodecId::Vendor(0xFCB1, 0x42),
1058 std::vector<uint8_t>{1, 2, 3});
1059 aidl_retval = provider->getA2dpConfiguration(
1060 std::vector<A2dpRemoteCapabilities>{
1061 unknown_core_remote_capabilities,
1062 unknown_vendor_remote_capabilities,
1063 },
1064 A2dpConfigurationHint(), &configuration);
1065 ASSERT_TRUE(aidl_retval.isOk());
1066 EXPECT_FALSE(configuration.has_value());
1067 }
1068}
1069
1070/**
1071 * Calling getA2dpConfiguration with invalid remote capabilities
1072 * must return an empty configuration.
1073 */
1074TEST_P(BluetoothAudioProviderAidl,
1075 getA2dpConfiguration_invalidRemoteCapabilities) {
1076 for (auto& [provider, provider_info] :
1077 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1078 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1079 if (provider == nullptr || !provider_info.has_value() ||
1080 provider_info->codecInfos.empty()) {
1081 continue;
1082 }
1083
1084 std::optional<A2dpConfiguration> configuration;
1085 ::ndk::ScopedAStatus aidl_retval;
1086
1087 // Use the first available codec in the provider info for testing.
1088 // The capabilities are modified to make them invalid.
1089 auto const& codec_info = provider_info->codecInfos[0];
1090 auto transport = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1091 std::vector<uint8_t> invalid_capabilities = transport.capabilities;
1092 invalid_capabilities.push_back(0x42); // adding bytes should be invalid.
1093 aidl_retval = provider->getA2dpConfiguration(
1094 std::vector<A2dpRemoteCapabilities>{
1095 A2dpRemoteCapabilities(/*seid*/ 0, codec_info.id,
1096 std::vector<uint8_t>()),
1097 A2dpRemoteCapabilities(/*seid*/ 1, codec_info.id,
1098 invalid_capabilities),
1099 },
1100 A2dpConfigurationHint(), &configuration);
1101 ASSERT_TRUE(aidl_retval.isOk());
1102 EXPECT_FALSE(configuration.has_value());
1103 }
1104}
1105
1106/**
1107 * Calling getA2dpConfiguration with valid remote capabilities
1108 * must return a valid configuration. The selected parameters must
1109 * be contained in the original capabilities. The returned configuration
1110 * must match the returned parameters. The returned SEID must match the
1111 * input SEID.
1112 */
1113TEST_P(BluetoothAudioProviderAidl,
1114 getA2dpConfiguration_validRemoteCapabilities) {
1115 for (auto& [provider, provider_info] :
1116 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1117 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1118 if (provider == nullptr || !provider_info.has_value() ||
1119 provider_info->codecInfos.empty()) {
1120 continue;
1121 }
1122
1123 // Test with all available codecs in the provider info.
1124 for (auto const& codec_info : provider_info->codecInfos) {
1125 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1126 std::optional<A2dpConfiguration> configuration{};
1127 ::ndk::ScopedAStatus aidl_retval;
1128
1129 aidl_retval = provider->getA2dpConfiguration(
1130 std::vector<A2dpRemoteCapabilities>{
1131 A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
1132 a2dp_info.capabilities),
1133 },
1134 A2dpConfigurationHint(), &configuration);
1135
1136 ASSERT_TRUE(aidl_retval.isOk());
1137 ASSERT_TRUE(configuration.has_value());
1138
1139 // Returned configuration must have the same codec id
1140 // as the remote capability.
1141 EXPECT_EQ(configuration->id, codec_info.id);
1142
1143 // Returned configuration must have the same SEID
1144 // as the remote capability.
1145 EXPECT_EQ(configuration->remoteSeid, 42);
1146
1147 // Returned codec parameters must be in the range of input
1148 // parameters.
1149 EXPECT_NE(
1150 std::find(a2dp_info.channelMode.begin(), a2dp_info.channelMode.end(),
1151 configuration->parameters.channelMode),
1152 a2dp_info.channelMode.end());
1153 EXPECT_NE(std::find(a2dp_info.samplingFrequencyHz.begin(),
1154 a2dp_info.samplingFrequencyHz.end(),
1155 configuration->parameters.samplingFrequencyHz),
1156 a2dp_info.samplingFrequencyHz.end());
1157 EXPECT_NE(std::find(a2dp_info.bitdepth.begin(), a2dp_info.bitdepth.end(),
1158 configuration->parameters.bitdepth),
1159 a2dp_info.bitdepth.end());
1160 EXPECT_EQ(a2dp_info.lossless, configuration->parameters.lossless);
1161 EXPECT_TRUE(configuration->parameters.minBitrate <=
1162 configuration->parameters.maxBitrate);
1163
1164 // Returned configuration must be parsable by parseA2dpParameters
1165 // and match the codec parameters.
1166 CodecParameters codec_parameters;
1167 A2dpStatus a2dp_status = A2dpStatus::OK;
1168 aidl_retval = provider->parseA2dpConfiguration(
1169 configuration->id, configuration->configuration, &codec_parameters,
1170 &a2dp_status);
1171 ASSERT_TRUE(aidl_retval.isOk());
1172 EXPECT_TRUE(a2dp_status == A2dpStatus::OK);
1173 EXPECT_EQ(codec_parameters, configuration->parameters);
1174 }
1175 }
1176}
1177
1178/**
1179 * Calling getA2dpConfiguration with valid remote capabilities
1180 * with various hinted codec ids.
1181 */
1182TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_hintCodecId) {
1183 for (auto& [provider, provider_info] :
1184 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1185 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1186 if (provider == nullptr || !provider_info.has_value() ||
1187 provider_info->codecInfos.empty()) {
1188 continue;
1189 }
1190
1191 // Build the remote capabilities with all supported codecs.
1192 std::vector<A2dpRemoteCapabilities> remote_capabilities;
1193 for (size_t n = 0; n < provider_info->codecInfos.size(); n++) {
1194 auto const& codec_info = provider_info->codecInfos[n];
1195 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1196 remote_capabilities.push_back(A2dpRemoteCapabilities(
1197 /*seid*/ n, codec_info.id, a2dp_info.capabilities));
1198 }
1199
1200 // Test with all supported codec identifiers,
1201 for (auto const& codec_info : provider_info->codecInfos) {
1202 std::optional<A2dpConfiguration> configuration{};
1203 ::ndk::ScopedAStatus aidl_retval;
1204
1205 A2dpConfigurationHint hint;
1206 hint.codecId = codec_info.id;
1207
1208 aidl_retval = provider->getA2dpConfiguration(remote_capabilities, hint,
1209 &configuration);
1210
1211 ASSERT_TRUE(aidl_retval.isOk());
1212 ASSERT_TRUE(configuration.has_value());
1213 EXPECT_EQ(configuration->id, codec_info.id);
1214 }
1215
1216 // Test with unknown codec identifiers: either core or vendor.
1217 for (auto& codec_id :
1218 {CodecId(CodecId::Core::CVSD),
1219 CodecId(CodecId::Vendor(0xFCB1, 0x42)) /*Google Codec #42*/}) {
1220 std::optional<A2dpConfiguration> configuration{};
1221 ::ndk::ScopedAStatus aidl_retval;
1222
1223 A2dpConfigurationHint hint;
1224 hint.codecId = codec_id;
1225
1226 aidl_retval = provider->getA2dpConfiguration(remote_capabilities, hint,
1227 &configuration);
1228
1229 ASSERT_TRUE(aidl_retval.isOk());
1230 ASSERT_TRUE(configuration.has_value());
1231 EXPECT_NE(configuration->id, codec_id);
1232 }
1233 }
1234}
1235
1236/**
1237 * Calling getA2dpConfiguration with valid remote capabilities
1238 * with various hinted channel modes.
1239 */
1240TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_hintChannelMode) {
1241 for (auto& [provider, provider_info] :
1242 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1243 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1244 if (provider == nullptr || !provider_info.has_value() ||
1245 provider_info->codecInfos.empty()) {
1246 continue;
1247 }
1248
1249 // Test with all available codecs in the provider info.
1250 for (auto const& codec_info : provider_info->codecInfos) {
1251 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1252 std::optional<A2dpConfiguration> configuration{};
1253 ::ndk::ScopedAStatus aidl_retval;
1254
1255 for (auto& channel_mode :
1256 {ChannelMode::STEREO, ChannelMode::MONO, ChannelMode::DUALMONO}) {
1257 // Add the hint for the channel mode.
1258 A2dpConfigurationHint hint;
1259 auto& codec_parameters = hint.codecParameters.emplace();
1260 codec_parameters.channelMode = channel_mode;
1261
1262 aidl_retval = provider->getA2dpConfiguration(
1263 std::vector<A2dpRemoteCapabilities>{
1264 A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
1265 a2dp_info.capabilities),
1266 },
1267 hint, &configuration);
1268
1269 ASSERT_TRUE(aidl_retval.isOk());
1270 ASSERT_TRUE(configuration.has_value());
1271
1272 // The hint must be ignored if the channel mode is not supported
1273 // by the codec, and applied otherwise.
1274 ASSERT_EQ(configuration->parameters.channelMode == channel_mode,
1275 std::find(a2dp_info.channelMode.begin(),
1276 a2dp_info.channelMode.end(),
1277 channel_mode) != a2dp_info.channelMode.end());
1278 }
1279 }
1280 }
1281}
1282
1283/**
1284 * Calling getA2dpConfiguration with valid remote capabilities
1285 * with various hinted sampling frequencies.
1286 */
1287TEST_P(BluetoothAudioProviderAidl,
1288 getA2dpConfiguration_hintSamplingFrequencyHz) {
1289 for (auto& [provider, provider_info] :
1290 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1291 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1292 if (provider == nullptr || !provider_info.has_value() ||
1293 provider_info->codecInfos.empty()) {
1294 continue;
1295 }
1296
1297 // Test with all available codecs in the provider info.
1298 for (auto const& codec_info : provider_info->codecInfos) {
1299 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1300 std::optional<A2dpConfiguration> configuration{};
1301 ::ndk::ScopedAStatus aidl_retval;
1302
1303 for (auto& sampling_frequency_hz : {
1304 0,
1305 1,
1306 8000,
1307 16000,
1308 24000,
1309 32000,
1310 44100,
1311 48000,
1312 88200,
1313 96000,
1314 176400,
1315 192000,
1316 }) {
1317 // Add the hint for the sampling frequency.
1318 A2dpConfigurationHint hint;
1319 auto& codec_parameters = hint.codecParameters.emplace();
1320 codec_parameters.samplingFrequencyHz = sampling_frequency_hz;
1321
1322 aidl_retval = provider->getA2dpConfiguration(
1323 std::vector<A2dpRemoteCapabilities>{
1324 A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
1325 a2dp_info.capabilities),
1326 },
1327 hint, &configuration);
1328
1329 ASSERT_TRUE(aidl_retval.isOk());
1330 ASSERT_TRUE(configuration.has_value());
1331
1332 // The hint must be ignored if the sampling frequency is not supported
1333 // by the codec, and applied otherwise.
1334 ASSERT_EQ(configuration->parameters.samplingFrequencyHz ==
1335 sampling_frequency_hz,
1336 std::find(a2dp_info.samplingFrequencyHz.begin(),
1337 a2dp_info.samplingFrequencyHz.end(),
1338 sampling_frequency_hz) !=
1339 a2dp_info.samplingFrequencyHz.end());
1340 }
1341 }
1342 }
1343}
1344
1345/**
1346 * Calling getA2dpConfiguration with valid remote capabilities
1347 * with various hinted sampling bit-depths.
1348 */
1349TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_hintBitdepth) {
1350 for (auto& [provider, provider_info] :
1351 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1352 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1353 if (provider == nullptr || !provider_info.has_value() ||
1354 provider_info->codecInfos.empty()) {
1355 continue;
1356 }
1357
1358 // Test with all available codecs in the provider info.
1359 for (auto const& codec_info : provider_info->codecInfos) {
1360 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1361 std::optional<A2dpConfiguration> configuration{};
1362 ::ndk::ScopedAStatus aidl_retval;
1363
1364 for (auto& bitdepth : {0, 1, 16, 24, 32}) {
1365 // Add the hint for the bit depth.
1366 A2dpConfigurationHint hint;
1367 auto& codec_parameters = hint.codecParameters.emplace();
1368 codec_parameters.bitdepth = bitdepth;
1369
1370 aidl_retval = provider->getA2dpConfiguration(
1371 std::vector<A2dpRemoteCapabilities>{
1372 A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
1373 a2dp_info.capabilities),
1374 },
1375 hint, &configuration);
1376
1377 ASSERT_TRUE(aidl_retval.isOk());
1378 ASSERT_TRUE(configuration.has_value());
1379
1380 // The hint must be ignored if the bitdepth is not supported
1381 // by the codec, and applied otherwise.
1382 ASSERT_EQ(
1383 configuration->parameters.bitdepth == bitdepth,
1384 std::find(a2dp_info.bitdepth.begin(), a2dp_info.bitdepth.end(),
1385 bitdepth) != a2dp_info.bitdepth.end());
1386 }
1387 }
1388 }
1389}
1390
1391/**
1392 * Calling startSession with an unknown codec id must fail.
1393 */
1394TEST_P(BluetoothAudioProviderAidl, startSession_unknownCodecId) {
1395 for (auto& [provider, provider_info] :
1396 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1397 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1398 if (provider == nullptr || !provider_info.has_value() ||
1399 provider_info->codecInfos.empty()) {
1400 continue;
1401 }
1402
1403 for (auto& codec_id :
1404 {CodecId(CodecId::Core::CVSD),
1405 CodecId(CodecId::Vendor(0xFCB1, 0x42) /*Google Codec #42*/)}) {
1406 A2dpStreamConfiguration a2dp_config;
1407 DataMQDesc data_mq_desc;
1408
1409 a2dp_config.codecId = codec_id;
1410 a2dp_config.configuration = std::vector<uint8_t>{1, 2, 3};
1411
1412 auto aidl_retval =
1413 provider->startSession(audio_port_, AudioConfiguration(a2dp_config),
1414 std::vector<LatencyMode>{}, &data_mq_desc);
1415
1416 EXPECT_FALSE(aidl_retval.isOk());
1417 }
1418 }
1419}
1420
1421/**
1422 * Calling startSession with a known codec and a valid configuration
1423 * must succeed.
1424 */
1425TEST_P(BluetoothAudioProviderAidl, startSession_valid) {
1426 for (auto& [provider, provider_info] :
1427 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1428 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1429 if (provider == nullptr || !provider_info.has_value() ||
1430 provider_info->codecInfos.empty()) {
1431 continue;
1432 }
1433
1434 // Use the first available codec in the provider info for testing.
1435 // To get a valid configuration (the capabilities array in the provider
1436 // info is not a selection), getA2dpConfiguration is used with the
1437 // selected codec parameters as input.
1438 auto const& codec_info = provider_info->codecInfos[0];
1439 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1440 ::ndk::ScopedAStatus aidl_retval;
1441 A2dpRemoteCapabilities remote_capabilities(/*seid*/ 0, codec_info.id,
1442 a2dp_info.capabilities);
1443 std::optional<A2dpConfiguration> configuration;
1444 aidl_retval = provider->getA2dpConfiguration(
1445 std::vector<A2dpRemoteCapabilities>{remote_capabilities},
1446 A2dpConfigurationHint(), &configuration);
1447 ASSERT_TRUE(aidl_retval.isOk());
1448 ASSERT_TRUE(configuration.has_value());
1449
1450 // Build the stream configuration.
1451 A2dpStreamConfiguration a2dp_config;
1452 DataMQDesc data_mq_desc;
1453
1454 a2dp_config.codecId = codec_info.id;
1455 a2dp_config.configuration = configuration->configuration;
1456
1457 aidl_retval =
1458 provider->startSession(audio_port_, AudioConfiguration(a2dp_config),
1459 std::vector<LatencyMode>{}, &data_mq_desc);
1460
1461 EXPECT_TRUE(aidl_retval.isOk());
1462 }
1463}
1464
1465/**
1466 * Calling startSession with a known codec but an invalid configuration
1467 * must fail.
1468 */
1469TEST_P(BluetoothAudioProviderAidl, startSession_invalidConfiguration) {
1470 for (auto& [provider, provider_info] :
1471 {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
1472 std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
1473 if (provider == nullptr || !provider_info.has_value() ||
1474 provider_info->codecInfos.empty()) {
1475 continue;
1476 }
1477
1478 // Use the first available codec in the provider info for testing.
1479 // To get a valid configuration (the capabilities array in the provider
1480 // info is not a selection), getA2dpConfiguration is used with the
1481 // selected codec parameters as input.
1482 ::ndk::ScopedAStatus aidl_retval;
1483 auto const& codec_info = provider_info->codecInfos[0];
1484 auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
1485 A2dpRemoteCapabilities remote_capabilities(/*seid*/ 0, codec_info.id,
1486 a2dp_info.capabilities);
1487 std::optional<A2dpConfiguration> configuration;
1488 aidl_retval = provider->getA2dpConfiguration(
1489 std::vector<A2dpRemoteCapabilities>{remote_capabilities},
1490 A2dpConfigurationHint(), &configuration);
1491 ASSERT_TRUE(aidl_retval.isOk());
1492 ASSERT_TRUE(configuration.has_value());
1493
1494 // Build the stream configuration but edit the configuration bytes
1495 // to make it invalid.
1496 A2dpStreamConfiguration a2dp_config;
1497 DataMQDesc data_mq_desc;
1498
1499 a2dp_config.codecId = codec_info.id;
1500 a2dp_config.configuration = configuration->configuration;
1501 a2dp_config.configuration.push_back(42);
1502
1503 aidl_retval =
1504 provider->startSession(audio_port_, AudioConfiguration(a2dp_config),
1505 std::vector<LatencyMode>{}, &data_mq_desc);
1506
1507 EXPECT_FALSE(aidl_retval.isOk());
1508 }
1509}
1510
Antoine SOULIER8c90f1f2023-09-26 18:55:17 +00001511/**
Alice Kuoadcceec2022-03-28 13:28:43 +08001512 * openProvider A2DP_SOFTWARE_ENCODING_DATAPATH
1513 */
1514class BluetoothAudioProviderA2dpEncodingSoftwareAidl
1515 : public BluetoothAudioProviderFactoryAidl {
1516 public:
1517 virtual void SetUp() override {
1518 BluetoothAudioProviderFactoryAidl::SetUp();
1519 GetProviderCapabilitiesHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
1520 OpenProviderHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
1521 ASSERT_NE(audio_provider_, nullptr);
1522 }
1523
1524 virtual void TearDown() override {
1525 audio_port_ = nullptr;
1526 audio_provider_ = nullptr;
1527 BluetoothAudioProviderFactoryAidl::TearDown();
1528 }
Josh Wu049e2cd2022-01-12 05:42:58 -08001529};
1530
1531/**
1532 * Test whether we can open a provider of type
1533 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001534TEST_P(BluetoothAudioProviderA2dpEncodingSoftwareAidl,
1535 OpenA2dpEncodingSoftwareProvider) {}
1536
1537/**
1538 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08001539 * SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH can be started and stopped
1540 * with different PCM config
Alice Kuoadcceec2022-03-28 13:28:43 +08001541 */
1542TEST_P(BluetoothAudioProviderA2dpEncodingSoftwareAidl,
1543 StartAndEndA2dpEncodingSoftwareSessionWithPossiblePcmConfig) {
1544 for (auto sample_rate : a2dp_sample_rates) {
1545 for (auto bits_per_sample : a2dp_bits_per_samples) {
1546 for (auto channel_mode : a2dp_channel_modes) {
1547 PcmConfiguration pcm_config{
1548 .sampleRateHz = sample_rate,
Alice Kuoadcceec2022-03-28 13:28:43 +08001549 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00001550 .bitsPerSample = bits_per_sample,
Alice Kuoadcceec2022-03-28 13:28:43 +08001551 };
1552 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
1553 DataMQDesc mq_desc;
1554 auto aidl_retval = audio_provider_->startSession(
1555 audio_port_, AudioConfiguration(pcm_config), latency_modes,
1556 &mq_desc);
1557 DataMQ data_mq(mq_desc);
1558
1559 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
1560 if (is_codec_config_valid) {
1561 EXPECT_TRUE(data_mq.isValid());
1562 }
1563 EXPECT_TRUE(audio_provider_->endSession().isOk());
1564 }
1565 }
1566 }
1567}
1568
1569/**
Bao Do72399432023-11-09 08:13:05 +00001570 * openProvider HFP_SOFTWARE_ENCODING_DATAPATH
1571 */
1572class BluetoothAudioProviderHfpSoftwareEncodingAidl
1573 : public BluetoothAudioProviderFactoryAidl {
1574 public:
1575 virtual void SetUp() override {
1576 BluetoothAudioProviderFactoryAidl::SetUp();
Bao Dob487a852023-12-25 10:12:09 +08001577 if (GetProviderFactoryInterfaceVersion() <
1578 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
1579 GTEST_SKIP();
1580 }
Bao Do72399432023-11-09 08:13:05 +00001581 GetProviderCapabilitiesHelper(SessionType::HFP_SOFTWARE_ENCODING_DATAPATH);
1582 OpenProviderHelper(SessionType::HFP_SOFTWARE_ENCODING_DATAPATH);
1583 ASSERT_NE(audio_provider_, nullptr);
1584 }
1585
1586 virtual void TearDown() override {
1587 audio_port_ = nullptr;
1588 audio_provider_ = nullptr;
1589 BluetoothAudioProviderFactoryAidl::TearDown();
1590 }
1591
1592 bool OpenSession(int32_t sample_rate, int8_t bits_per_sample,
Bao Do5b2fdab2023-11-20 08:02:55 +00001593 ChannelMode channel_mode, int32_t data_interval_us) {
Bao Do72399432023-11-09 08:13:05 +00001594 PcmConfiguration pcm_config{
1595 .sampleRateHz = sample_rate,
1596 .channelMode = channel_mode,
1597 .bitsPerSample = bits_per_sample,
1598 .dataIntervalUs = data_interval_us,
1599 };
1600 // Checking against provider capability from getProviderCapabilities
1601 // For HFP software, it's
1602 // BluetoothAudioCodecs::GetSoftwarePcmCapabilities();
1603 DataMQDesc mq_desc;
1604 auto aidl_retval = audio_provider_->startSession(
1605 audio_port_, AudioConfiguration(pcm_config), latency_modes, &mq_desc);
1606 DataMQ data_mq(mq_desc);
1607
1608 if (!aidl_retval.isOk()) return false;
1609 if (!data_mq.isValid()) return false;
1610 return true;
1611 }
1612};
1613
1614/**
1615 * Test whether we can open a provider of type
1616 */
1617TEST_P(BluetoothAudioProviderHfpSoftwareEncodingAidl,
1618 OpenHfpSoftwareEncodingProvider) {}
1619
1620/**
1621 * Test whether each provider of type
1622 * SessionType::HFP_SOFTWARE_ENCODING_DATAPATH can be started and stopped with
1623 * different PCM config
1624 */
1625TEST_P(BluetoothAudioProviderHfpSoftwareEncodingAidl,
1626 StartAndEndHfpEncodingSoftwareSessionWithPossiblePcmConfig) {
1627 for (auto sample_rate : hfp_sample_rates_) {
1628 for (auto bits_per_sample : hfp_bits_per_samples_) {
1629 for (auto channel_mode : hfp_channel_modes_) {
Bao Do5b2fdab2023-11-20 08:02:55 +00001630 for (auto data_interval_us : hfp_data_interval_us_) {
1631 EXPECT_TRUE(OpenSession(sample_rate, bits_per_sample, channel_mode,
1632 data_interval_us));
Bao Do72399432023-11-09 08:13:05 +00001633 EXPECT_TRUE(audio_provider_->endSession().isOk());
1634 }
1635 }
1636 }
1637 }
1638}
1639
1640/**
1641 * openProvider HFP_SOFTWARE_DECODING_DATAPATH
1642 */
1643class BluetoothAudioProviderHfpSoftwareDecodingAidl
1644 : public BluetoothAudioProviderFactoryAidl {
1645 public:
1646 virtual void SetUp() override {
1647 BluetoothAudioProviderFactoryAidl::SetUp();
Bao Dob487a852023-12-25 10:12:09 +08001648 if (GetProviderFactoryInterfaceVersion() <
1649 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
1650 GTEST_SKIP();
1651 }
Bao Do72399432023-11-09 08:13:05 +00001652 GetProviderCapabilitiesHelper(SessionType::HFP_SOFTWARE_DECODING_DATAPATH);
1653 OpenProviderHelper(SessionType::HFP_SOFTWARE_DECODING_DATAPATH);
1654 ASSERT_NE(audio_provider_, nullptr);
1655 }
1656
1657 virtual void TearDown() override {
1658 audio_port_ = nullptr;
1659 audio_provider_ = nullptr;
1660 BluetoothAudioProviderFactoryAidl::TearDown();
1661 }
1662
1663 bool OpenSession(int32_t sample_rate, int8_t bits_per_sample,
Bao Do5b2fdab2023-11-20 08:02:55 +00001664 ChannelMode channel_mode, int32_t data_interval_us) {
Bao Do72399432023-11-09 08:13:05 +00001665 PcmConfiguration pcm_config{
1666 .sampleRateHz = sample_rate,
1667 .channelMode = channel_mode,
1668 .bitsPerSample = bits_per_sample,
1669 .dataIntervalUs = data_interval_us,
1670 };
1671 DataMQDesc mq_desc;
1672 auto aidl_retval = audio_provider_->startSession(
1673 audio_port_, AudioConfiguration(pcm_config), latency_modes, &mq_desc);
1674 DataMQ data_mq(mq_desc);
1675
1676 if (!aidl_retval.isOk()) return false;
1677 if (!data_mq.isValid()) return false;
1678 return true;
1679 }
1680};
1681
1682/**
1683 * Test whether we can open a provider of type
1684 */
1685TEST_P(BluetoothAudioProviderHfpSoftwareDecodingAidl,
1686 OpenHfpSoftwareDecodingProvider) {}
1687
1688/**
1689 * Test whether each provider of type
1690 * SessionType::HFP_SOFTWARE_DECODING_DATAPATH can be started and stopped with
1691 * different PCM config
1692 */
1693TEST_P(BluetoothAudioProviderHfpSoftwareDecodingAidl,
1694 StartAndEndHfpDecodingSoftwareSessionWithPossiblePcmConfig) {
1695 for (auto sample_rate : hfp_sample_rates_) {
1696 for (auto bits_per_sample : hfp_bits_per_samples_) {
1697 for (auto channel_mode : hfp_channel_modes_) {
Bao Do5b2fdab2023-11-20 08:02:55 +00001698 for (auto data_interval_us : hfp_data_interval_us_) {
1699 EXPECT_TRUE(OpenSession(sample_rate, bits_per_sample, channel_mode,
1700 data_interval_us));
1701 EXPECT_TRUE(audio_provider_->endSession().isOk());
Bao Do72399432023-11-09 08:13:05 +00001702 }
1703 }
1704 }
1705 }
1706}
1707
1708/**
Alice Kuoadcceec2022-03-28 13:28:43 +08001709 * openProvider A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH
1710 */
1711class BluetoothAudioProviderA2dpEncodingHardwareAidl
1712 : public BluetoothAudioProviderFactoryAidl {
1713 public:
1714 virtual void SetUp() override {
1715 BluetoothAudioProviderFactoryAidl::SetUp();
1716 GetProviderCapabilitiesHelper(
1717 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
1718 OpenProviderHelper(SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
1719 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
1720 audio_provider_ != nullptr);
1721 }
1722
1723 virtual void TearDown() override {
1724 audio_port_ = nullptr;
1725 audio_provider_ = nullptr;
1726 BluetoothAudioProviderFactoryAidl::TearDown();
1727 }
1728
1729 bool IsOffloadSupported() { return (temp_provider_capabilities_.size() > 0); }
1730};
1731
1732/**
1733 * Test whether we can open a provider of type
1734 */
1735TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1736 OpenA2dpEncodingHardwareProvider) {}
Josh Wu049e2cd2022-01-12 05:42:58 -08001737
1738/**
1739 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08001740 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped
1741 * with SBC hardware encoding config
Josh Wu049e2cd2022-01-12 05:42:58 -08001742 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001743TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1744 StartAndEndA2dpSbcEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001745 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00001746 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08001747 }
1748
1749 CodecConfiguration codec_config = {
1750 .codecType = CodecType::SBC,
1751 .encodedAudioBitrate = 328000,
1752 .peerMtu = 1005,
1753 .isScmstEnabled = false,
1754 };
1755 auto sbc_codec_specifics = GetSbcCodecSpecificSupportedList(true);
1756
1757 for (auto& codec_specific : sbc_codec_specifics) {
1758 copy_codec_specific(codec_config.config, codec_specific);
1759 DataMQDesc mq_desc;
1760 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001761 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001762
1763 ASSERT_TRUE(aidl_retval.isOk());
1764 EXPECT_TRUE(audio_provider_->endSession().isOk());
1765 }
1766}
1767
1768/**
1769 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08001770 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped
1771 * with AAC hardware encoding config
Josh Wu049e2cd2022-01-12 05:42:58 -08001772 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001773TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1774 StartAndEndA2dpAacEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001775 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00001776 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08001777 }
1778
1779 CodecConfiguration codec_config = {
1780 .codecType = CodecType::AAC,
1781 .encodedAudioBitrate = 320000,
1782 .peerMtu = 1005,
1783 .isScmstEnabled = false,
1784 };
1785 auto aac_codec_specifics = GetAacCodecSpecificSupportedList(true);
1786
1787 for (auto& codec_specific : aac_codec_specifics) {
1788 copy_codec_specific(codec_config.config, codec_specific);
1789 DataMQDesc mq_desc;
1790 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001791 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001792
1793 ASSERT_TRUE(aidl_retval.isOk());
1794 EXPECT_TRUE(audio_provider_->endSession().isOk());
1795 }
1796}
1797
1798/**
1799 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08001800 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped
1801 * with LDAC hardware encoding config
Josh Wu049e2cd2022-01-12 05:42:58 -08001802 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001803TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1804 StartAndEndA2dpLdacEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001805 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00001806 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08001807 }
1808
1809 CodecConfiguration codec_config = {
1810 .codecType = CodecType::LDAC,
1811 .encodedAudioBitrate = 990000,
1812 .peerMtu = 1005,
1813 .isScmstEnabled = false,
1814 };
1815 auto ldac_codec_specifics = GetLdacCodecSpecificSupportedList(true);
1816
1817 for (auto& codec_specific : ldac_codec_specifics) {
1818 copy_codec_specific(codec_config.config, codec_specific);
1819 DataMQDesc mq_desc;
1820 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001821 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001822
1823 ASSERT_TRUE(aidl_retval.isOk());
1824 EXPECT_TRUE(audio_provider_->endSession().isOk());
1825 }
1826}
1827
1828/**
1829 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08001830 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped
1831 * with Opus hardware encoding config
Josh Wu049e2cd2022-01-12 05:42:58 -08001832 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001833TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
Omer Osmana2587da2022-05-01 03:54:11 +00001834 StartAndEndA2dpOpusEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001835 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00001836 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08001837 }
1838
1839 CodecConfiguration codec_config = {
Omer Osmana2587da2022-05-01 03:54:11 +00001840 .codecType = CodecType::OPUS,
Josh Wu049e2cd2022-01-12 05:42:58 -08001841 .encodedAudioBitrate = 990000,
1842 .peerMtu = 1005,
1843 .isScmstEnabled = false,
1844 };
Omer Osmana2587da2022-05-01 03:54:11 +00001845 auto opus_codec_specifics = GetOpusCodecSpecificSupportedList(true);
Josh Wu049e2cd2022-01-12 05:42:58 -08001846
Omer Osmana2587da2022-05-01 03:54:11 +00001847 for (auto& codec_specific : opus_codec_specifics) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001848 copy_codec_specific(codec_config.config, codec_specific);
1849 DataMQDesc mq_desc;
1850 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001851 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001852
1853 ASSERT_TRUE(aidl_retval.isOk());
1854 EXPECT_TRUE(audio_provider_->endSession().isOk());
1855 }
1856}
1857
1858/**
1859 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08001860 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped
1861 * with AptX hardware encoding config
Josh Wu049e2cd2022-01-12 05:42:58 -08001862 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001863TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1864 StartAndEndA2dpAptxEncodingHardwareSession) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001865 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00001866 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08001867 }
1868
1869 for (auto codec_type : {CodecType::APTX, CodecType::APTX_HD}) {
1870 CodecConfiguration codec_config = {
1871 .codecType = codec_type,
1872 .encodedAudioBitrate =
1873 (codec_type == CodecType::APTX ? 352000 : 576000),
1874 .peerMtu = 1005,
1875 .isScmstEnabled = false,
1876 };
1877
1878 auto aptx_codec_specifics = GetAptxCodecSpecificSupportedList(
1879 (codec_type == CodecType::APTX_HD ? true : false), true);
1880
1881 for (auto& codec_specific : aptx_codec_specifics) {
1882 copy_codec_specific(codec_config.config, codec_specific);
1883 DataMQDesc mq_desc;
1884 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001885 audio_port_, AudioConfiguration(codec_config), latency_modes,
1886 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001887
1888 ASSERT_TRUE(aidl_retval.isOk());
1889 EXPECT_TRUE(audio_provider_->endSession().isOk());
1890 }
1891 }
1892}
1893
1894/**
1895 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08001896 * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped
1897 * with an invalid codec config
Josh Wu049e2cd2022-01-12 05:42:58 -08001898 */
Alice Kuoadcceec2022-03-28 13:28:43 +08001899TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
1900 StartAndEndA2dpEncodingHardwareSessionInvalidCodecConfig) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001901 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00001902 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08001903 }
1904 ASSERT_NE(audio_provider_, nullptr);
1905
1906 std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
Sagar Verma62df9102022-12-07 17:56:04 +05301907 for (auto codec_type : ndk::enum_range<CodecType>()) {
Josh Wu049e2cd2022-01-12 05:42:58 -08001908 switch (codec_type) {
1909 case CodecType::SBC:
1910 codec_specifics = GetSbcCodecSpecificSupportedList(false);
1911 break;
1912 case CodecType::AAC:
1913 codec_specifics = GetAacCodecSpecificSupportedList(false);
1914 break;
1915 case CodecType::LDAC:
1916 codec_specifics = GetLdacCodecSpecificSupportedList(false);
1917 break;
1918 case CodecType::APTX:
1919 codec_specifics = GetAptxCodecSpecificSupportedList(false, false);
1920 break;
1921 case CodecType::APTX_HD:
1922 codec_specifics = GetAptxCodecSpecificSupportedList(true, false);
1923 break;
Omer Osmana2587da2022-05-01 03:54:11 +00001924 case CodecType::OPUS:
1925 codec_specifics = GetOpusCodecSpecificSupportedList(false);
Josh Wu049e2cd2022-01-12 05:42:58 -08001926 continue;
1927 case CodecType::APTX_ADAPTIVE:
Sagar Verma62df9102022-12-07 17:56:04 +05301928 case CodecType::APTX_ADAPTIVE_LE:
1929 case CodecType::APTX_ADAPTIVE_LEX:
Omer Osmana2587da2022-05-01 03:54:11 +00001930 case CodecType::LC3:
Josh Wu049e2cd2022-01-12 05:42:58 -08001931 case CodecType::VENDOR:
1932 case CodecType::UNKNOWN:
1933 codec_specifics.clear();
1934 break;
1935 }
1936 if (codec_specifics.empty()) {
1937 continue;
1938 }
1939
1940 CodecConfiguration codec_config = {
1941 .codecType = codec_type,
1942 .encodedAudioBitrate = 328000,
1943 .peerMtu = 1005,
1944 .isScmstEnabled = false,
1945 };
1946 for (auto codec_specific : codec_specifics) {
1947 copy_codec_specific(codec_config.config, codec_specific);
1948 DataMQDesc mq_desc;
1949 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08001950 audio_port_, AudioConfiguration(codec_config), latency_modes,
1951 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08001952
1953 // AIDL call should fail on invalid codec
1954 ASSERT_FALSE(aidl_retval.isOk());
1955 EXPECT_TRUE(audio_provider_->endSession().isOk());
1956 }
1957 }
1958}
1959
1960/**
Bao Do72399432023-11-09 08:13:05 +00001961 * openProvider HFP_HARDWARE_OFFLOAD_DATAPATH
1962 */
1963class BluetoothAudioProviderHfpHardwareAidl
1964 : public BluetoothAudioProviderFactoryAidl {
1965 public:
1966 virtual void SetUp() override {
1967 BluetoothAudioProviderFactoryAidl::SetUp();
Bao Dob487a852023-12-25 10:12:09 +08001968 if (GetProviderFactoryInterfaceVersion() <
1969 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
1970 GTEST_SKIP();
1971 }
Bao Do2fa1ab42024-01-29 17:50:34 +08001972 GetProviderInfoHelper(SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH);
Bao Do72399432023-11-09 08:13:05 +00001973 OpenProviderHelper(SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH);
1974 // Can open or empty capability
1975 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
1976 audio_provider_ != nullptr);
1977 }
1978
1979 virtual void TearDown() override {
1980 audio_port_ = nullptr;
1981 audio_provider_ = nullptr;
1982 BluetoothAudioProviderFactoryAidl::TearDown();
1983 }
1984
1985 bool OpenSession(CodecId codec_id, int connection_handle, bool nrec,
Bao Do5b2fdab2023-11-20 08:02:55 +00001986 bool controller_codec) {
Bao Do72399432023-11-09 08:13:05 +00001987 // Check if can open session with a Hfp configuration
1988 HfpConfiguration hfp_configuration{
1989 .codecId = codec_id,
1990 .connectionHandle = connection_handle,
1991 .nrec = nrec,
1992 .controllerCodec = controller_codec,
1993 };
1994 DataMQDesc mq_desc;
1995 auto aidl_retval = audio_provider_->startSession(
1996 audio_port_, AudioConfiguration(hfp_configuration), latency_modes,
1997 &mq_desc);
1998
1999 // Only check if aidl is ok to start session.
2000 return aidl_retval.isOk();
2001 }
2002};
2003
2004/**
2005 * Test whether we can open a provider of type
2006 */
2007TEST_P(BluetoothAudioProviderHfpHardwareAidl, OpenHfpHardwareProvider) {}
2008
2009/**
2010 * Test whether each provider of type
2011 * SessionType::HFP_SOFTWARE_DECODING_DATAPATH can be started and stopped with
2012 * different HFP config
2013 */
2014TEST_P(BluetoothAudioProviderHfpHardwareAidl,
2015 StartAndEndHfpHardwareSessionWithPossiblePcmConfig) {
2016 // Try to open with a sample configuration
2017 EXPECT_TRUE(OpenSession(CodecId::Core::CVSD, 6, false, true));
2018 EXPECT_TRUE(audio_provider_->endSession().isOk());
2019}
2020
2021/**
Josh Wu049e2cd2022-01-12 05:42:58 -08002022 * openProvider HEARING_AID_SOFTWARE_ENCODING_DATAPATH
2023 */
2024class BluetoothAudioProviderHearingAidSoftwareAidl
2025 : public BluetoothAudioProviderFactoryAidl {
2026 public:
2027 virtual void SetUp() override {
2028 BluetoothAudioProviderFactoryAidl::SetUp();
2029 GetProviderCapabilitiesHelper(
2030 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
2031 OpenProviderHelper(SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
2032 ASSERT_NE(audio_provider_, nullptr);
2033 }
2034
2035 virtual void TearDown() override {
2036 audio_port_ = nullptr;
2037 audio_provider_ = nullptr;
2038 BluetoothAudioProviderFactoryAidl::TearDown();
2039 }
2040
2041 static constexpr int32_t hearing_aid_sample_rates_[] = {0, 16000, 24000};
2042 static constexpr int8_t hearing_aid_bits_per_samples_[] = {0, 16, 24};
2043 static constexpr ChannelMode hearing_aid_channel_modes_[] = {
2044 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
2045};
2046
2047/**
2048 * Test whether we can open a provider of type
2049 */
2050TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl,
2051 OpenHearingAidSoftwareProvider) {}
2052
2053/**
2054 * Test whether each provider of type
2055 * SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH can be started and
2056 * stopped with different PCM config
2057 */
2058TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl,
2059 StartAndEndHearingAidSessionWithPossiblePcmConfig) {
2060 for (int32_t sample_rate : hearing_aid_sample_rates_) {
2061 for (int8_t bits_per_sample : hearing_aid_bits_per_samples_) {
2062 for (auto channel_mode : hearing_aid_channel_modes_) {
2063 PcmConfiguration pcm_config{
2064 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08002065 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00002066 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08002067 };
2068 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
2069 DataMQDesc mq_desc;
2070 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002071 audio_port_, AudioConfiguration(pcm_config), latency_modes,
2072 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002073 DataMQ data_mq(mq_desc);
2074
2075 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
2076 if (is_codec_config_valid) {
2077 EXPECT_TRUE(data_mq.isValid());
2078 }
2079 EXPECT_TRUE(audio_provider_->endSession().isOk());
2080 }
2081 }
2082 }
2083}
2084
2085/**
2086 * openProvider LE_AUDIO_SOFTWARE_ENCODING_DATAPATH
2087 */
2088class BluetoothAudioProviderLeAudioOutputSoftwareAidl
2089 : public BluetoothAudioProviderFactoryAidl {
2090 public:
2091 virtual void SetUp() override {
2092 BluetoothAudioProviderFactoryAidl::SetUp();
2093 GetProviderCapabilitiesHelper(
2094 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
2095 OpenProviderHelper(SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
2096 ASSERT_NE(audio_provider_, nullptr);
2097 }
2098
2099 virtual void TearDown() override {
2100 audio_port_ = nullptr;
2101 audio_provider_ = nullptr;
2102 BluetoothAudioProviderFactoryAidl::TearDown();
2103 }
2104
2105 static constexpr int32_t le_audio_output_sample_rates_[] = {
2106 0, 8000, 16000, 24000, 32000, 44100, 48000,
2107 };
2108 static constexpr int8_t le_audio_output_bits_per_samples_[] = {0, 16, 24};
2109 static constexpr ChannelMode le_audio_output_channel_modes_[] = {
2110 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
2111 static constexpr int32_t le_audio_output_data_interval_us_[] = {
2112 0 /* Invalid */, 10000 /* Valid 10ms */};
2113};
2114
2115/**
2116 * Test whether each provider of type
2117 * SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH can be started and
2118 * stopped
2119 */
2120TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl,
2121 OpenLeAudioOutputSoftwareProvider) {}
2122
2123/**
2124 * Test whether each provider of type
2125 * SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH can be started and
2126 * stopped with different PCM config
2127 */
2128TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl,
2129 StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
2130 for (auto sample_rate : le_audio_output_sample_rates_) {
2131 for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
2132 for (auto channel_mode : le_audio_output_channel_modes_) {
2133 for (auto data_interval_us : le_audio_output_data_interval_us_) {
2134 PcmConfiguration pcm_config{
2135 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08002136 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00002137 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08002138 .dataIntervalUs = data_interval_us,
2139 };
Josh Wu8a1be762022-02-15 09:37:29 -08002140 bool is_codec_config_valid =
2141 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
Josh Wu049e2cd2022-01-12 05:42:58 -08002142 DataMQDesc mq_desc;
2143 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002144 audio_port_, AudioConfiguration(pcm_config), latency_modes,
2145 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002146 DataMQ data_mq(mq_desc);
2147
2148 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
2149 if (is_codec_config_valid) {
2150 EXPECT_TRUE(data_mq.isValid());
2151 }
2152 EXPECT_TRUE(audio_provider_->endSession().isOk());
2153 }
2154 }
2155 }
2156 }
2157}
2158
2159/**
Alice Kuo04a399a2022-02-16 09:19:56 +08002160 * openProvider LE_AUDIO_SOFTWARE_DECODING_DATAPATH
Josh Wu049e2cd2022-01-12 05:42:58 -08002161 */
2162class BluetoothAudioProviderLeAudioInputSoftwareAidl
2163 : public BluetoothAudioProviderFactoryAidl {
2164 public:
2165 virtual void SetUp() override {
2166 BluetoothAudioProviderFactoryAidl::SetUp();
2167 GetProviderCapabilitiesHelper(
2168 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH);
2169 OpenProviderHelper(SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH);
2170 ASSERT_NE(audio_provider_, nullptr);
2171 }
2172
2173 virtual void TearDown() override {
2174 audio_port_ = nullptr;
2175 audio_provider_ = nullptr;
2176 BluetoothAudioProviderFactoryAidl::TearDown();
2177 }
2178
2179 static constexpr int32_t le_audio_input_sample_rates_[] = {
2180 0, 8000, 16000, 24000, 32000, 44100, 48000};
2181 static constexpr int8_t le_audio_input_bits_per_samples_[] = {0, 16, 24};
2182 static constexpr ChannelMode le_audio_input_channel_modes_[] = {
2183 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
2184 static constexpr int32_t le_audio_input_data_interval_us_[] = {
2185 0 /* Invalid */, 10000 /* Valid 10ms */};
2186};
2187
2188/**
2189 * Test whether each provider of type
Alice Kuo04a399a2022-02-16 09:19:56 +08002190 * SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002191 * stopped
2192 */
2193TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl,
2194 OpenLeAudioInputSoftwareProvider) {}
2195
2196/**
2197 * Test whether each provider of type
Alice Kuo04a399a2022-02-16 09:19:56 +08002198 * SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08002199 * stopped with different PCM config
2200 */
2201TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl,
2202 StartAndEndLeAudioInputSessionWithPossiblePcmConfig) {
2203 for (auto sample_rate : le_audio_input_sample_rates_) {
2204 for (auto bits_per_sample : le_audio_input_bits_per_samples_) {
2205 for (auto channel_mode : le_audio_input_channel_modes_) {
2206 for (auto data_interval_us : le_audio_input_data_interval_us_) {
2207 PcmConfiguration pcm_config{
2208 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08002209 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00002210 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08002211 .dataIntervalUs = data_interval_us,
2212 };
Josh Wu8a1be762022-02-15 09:37:29 -08002213 bool is_codec_config_valid =
2214 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
Josh Wu049e2cd2022-01-12 05:42:58 -08002215 DataMQDesc mq_desc;
2216 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08002217 audio_port_, AudioConfiguration(pcm_config), latency_modes,
2218 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08002219 DataMQ data_mq(mq_desc);
2220
2221 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
2222 if (is_codec_config_valid) {
2223 EXPECT_TRUE(data_mq.isValid());
2224 }
2225 EXPECT_TRUE(audio_provider_->endSession().isOk());
2226 }
2227 }
2228 }
2229 }
2230}
2231
2232/**
Alice Kuo04a399a2022-02-16 09:19:56 +08002233 * openProvider LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH
Josh Wu049e2cd2022-01-12 05:42:58 -08002234 */
2235class BluetoothAudioProviderLeAudioOutputHardwareAidl
2236 : public BluetoothAudioProviderFactoryAidl {
2237 public:
2238 virtual void SetUp() override {
2239 BluetoothAudioProviderFactoryAidl::SetUp();
2240 GetProviderCapabilitiesHelper(
2241 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
Bao Doc36897d2023-12-06 01:27:54 +00002242 GetProviderInfoHelper(
2243 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
Josh Wu049e2cd2022-01-12 05:42:58 -08002244 OpenProviderHelper(
2245 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
2246 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
2247 audio_provider_ != nullptr);
2248 }
2249
2250 virtual void TearDown() override {
2251 audio_port_ = nullptr;
2252 audio_provider_ = nullptr;
2253 BluetoothAudioProviderFactoryAidl::TearDown();
2254 }
2255
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00002256 bool IsMultidirectionalCapabilitiesEnabled() {
2257 if (!temp_provider_info_.has_value()) return false;
2258
2259 return temp_provider_info_.value().supportsMultidirectionalCapabilities;
2260 }
2261
2262 bool IsAsymmetricConfigurationAllowed() {
2263 if (!temp_provider_info_.has_value()) return false;
2264 if (temp_provider_info_.value().codecInfos.empty()) return false;
2265
2266 for (auto& codec_info : temp_provider_info_.value().codecInfos) {
2267 if (codec_info.transport.getTag() != CodecInfo::Transport::leAudio) {
2268 return false;
2269 }
2270
2271 auto flags =
2272 codec_info.transport.get<CodecInfo::Transport::leAudio>().flags;
2273
2274 if (!flags) {
2275 continue;
2276 }
2277
2278 if (flags->bitmask &
2279 ConfigurationFlags::ALLOW_ASYMMETRIC_CONFIGURATIONS) {
2280 return true;
2281 }
2282 }
2283
2284 return false;
2285 }
2286
Josh Wu049e2cd2022-01-12 05:42:58 -08002287 bool IsOffloadOutputSupported() {
2288 for (auto& capability : temp_provider_capabilities_) {
2289 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2290 continue;
2291 }
2292 auto& le_audio_capability =
2293 capability.get<AudioCapabilities::leAudioCapabilities>();
2294 if (le_audio_capability.unicastEncodeCapability.codecType !=
2295 CodecType::UNKNOWN)
2296 return true;
2297 }
2298 return false;
2299 }
2300
Bao Doc36897d2023-12-06 01:27:54 +00002301 bool IsOffloadOutputProviderInfoSupported() {
2302 if (!temp_provider_info_.has_value()) return false;
2303 if (temp_provider_info_.value().codecInfos.empty()) return false;
2304 // Check if all codec info is of LeAudio type
2305 for (auto& codec_info : temp_provider_info_.value().codecInfos) {
2306 if (codec_info.transport.getTag() != CodecInfo::Transport::leAudio)
2307 return false;
2308 }
2309 return true;
2310 }
2311
2312 std::vector<Lc3Configuration> GetUnicastLc3SupportedListFromProviderInfo() {
2313 std::vector<Lc3Configuration> le_audio_codec_configs;
2314 for (auto& codec_info : temp_provider_info_.value().codecInfos) {
2315 // Only gets LC3 codec information
2316 if (codec_info.id != CodecId::Core::LC3) continue;
2317 // Combine those parameters into one list of Lc3Configuration
2318 auto& transport =
2319 codec_info.transport.get<CodecInfo::Transport::Tag::leAudio>();
2320 for (int32_t samplingFrequencyHz : transport.samplingFrequencyHz) {
2321 for (int32_t frameDurationUs : transport.frameDurationUs) {
2322 for (int32_t octetsPerFrame : transport.bitdepth) {
2323 Lc3Configuration lc3_config = {
2324 .samplingFrequencyHz = samplingFrequencyHz,
2325 .frameDurationUs = frameDurationUs,
2326 .octetsPerFrame = octetsPerFrame,
2327 };
2328 le_audio_codec_configs.push_back(lc3_config);
2329 }
2330 }
2331 }
2332 }
2333
2334 return le_audio_codec_configs;
2335 }
2336
2337 AudioContext GetAudioContext(int32_t bitmask) {
2338 AudioContext media_audio_context;
2339 media_audio_context.bitmask = bitmask;
2340 return media_audio_context;
2341 }
2342
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00002343 LeAudioDeviceCapabilities GetDefaultRemoteSinkCapability() {
Bao Doc36897d2023-12-06 01:27:54 +00002344 // Create a capability
2345 LeAudioDeviceCapabilities capability;
2346
2347 capability.codecId = CodecId::Core::LC3;
2348
2349 auto pref_context_metadata = MetadataLtv::PreferredAudioContexts();
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00002350 pref_context_metadata.values =
2351 GetAudioContext(AudioContext::MEDIA | AudioContext::CONVERSATIONAL |
2352 AudioContext::GAME);
Bao Doc36897d2023-12-06 01:27:54 +00002353 capability.metadata = {pref_context_metadata};
2354
2355 auto sampling_rate =
2356 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies();
2357 sampling_rate.bitmask =
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00002358 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ16000 |
Bao Doc36897d2023-12-06 01:27:54 +00002359 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ8000;
2360 auto frame_duration =
2361 CodecSpecificCapabilitiesLtv::SupportedFrameDurations();
2362 frame_duration.bitmask =
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00002363 CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US7500 |
2364 CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US10000;
Bao Doc36897d2023-12-06 01:27:54 +00002365 auto octets = CodecSpecificCapabilitiesLtv::SupportedOctetsPerCodecFrame();
Jakub Tyszkowski1d214222024-01-16 09:44:48 +00002366 octets.min = 0;
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00002367 octets.max = 120;
Bao Doc36897d2023-12-06 01:27:54 +00002368 auto frames = CodecSpecificCapabilitiesLtv::SupportedMaxCodecFramesPerSDU();
2369 frames.value = 2;
2370 capability.codecSpecificCapabilities = {sampling_rate, frame_duration,
2371 octets, frames};
2372 return capability;
2373 }
2374
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00002375 LeAudioDeviceCapabilities GetDefaultRemoteSourceCapability() {
2376 // Create a capability
2377 LeAudioDeviceCapabilities capability;
2378
2379 capability.codecId = CodecId::Core::LC3;
2380
2381 auto pref_context_metadata = MetadataLtv::PreferredAudioContexts();
2382 pref_context_metadata.values =
2383 GetAudioContext(AudioContext::LIVE_AUDIO |
2384 AudioContext::CONVERSATIONAL | AudioContext::GAME);
2385 capability.metadata = {pref_context_metadata};
2386
2387 auto sampling_rate =
2388 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies();
2389 sampling_rate.bitmask =
2390 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ16000 |
2391 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ8000;
2392 auto frame_duration =
2393 CodecSpecificCapabilitiesLtv::SupportedFrameDurations();
2394 frame_duration.bitmask =
2395 CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US7500 |
2396 CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US10000;
2397 auto octets = CodecSpecificCapabilitiesLtv::SupportedOctetsPerCodecFrame();
2398 octets.min = 0;
2399 octets.max = 120;
2400 auto frames = CodecSpecificCapabilitiesLtv::SupportedMaxCodecFramesPerSDU();
2401 frames.value = 2;
2402 capability.codecSpecificCapabilities = {sampling_rate, frame_duration,
2403 octets, frames};
2404 return capability;
2405 }
2406
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00002407 bool IsAseRequirementSatisfiedWithUnknownChannelCount(
2408 const std::vector<std::optional<AseDirectionRequirement>>&
2409 ase_requirements,
2410 const std::vector<std::optional<AseDirectionConfiguration>>&
2411 ase_configurations) {
2412 /* This is mandatory to match sample freq, allocation however, when in the
2413 * device group there is only one device which supports left and right
2414 * allocation, and channel count is hidden from the BT stack, the BT stack
2415 * will send single requirement but it can receive two configurations if the
2416 * channel count is 1.
2417 */
2418
2419 int num_of_ase_requirements = 0;
2420 for (const auto& ase_req : ase_requirements) {
2421 auto required_allocation_ltv = GetConfigurationLtv(
2422 ase_req->aseConfiguration.codecConfiguration,
2423 CodecSpecificConfigurationLtv::Tag::audioChannelAllocation);
2424 if (required_allocation_ltv == std::nullopt) {
2425 continue;
2426 }
2427 int required_allocation =
2428 required_allocation_ltv
2429 ->get<
2430 CodecSpecificConfigurationLtv::Tag::audioChannelAllocation>()
2431 .bitmask;
2432 num_of_ase_requirements += std::bitset<32>(required_allocation).count();
2433 }
2434
2435 int num_of_satisfied_ase_requirements = 0;
2436 for (const auto& ase_req : ase_requirements) {
2437 if (!ase_req) {
2438 continue;
2439 }
2440 auto required_sample_freq_ltv = GetConfigurationLtv(
2441 ase_req->aseConfiguration.codecConfiguration,
2442 CodecSpecificConfigurationLtv::Tag::samplingFrequency);
2443 auto required_allocation_ltv = GetConfigurationLtv(
2444 ase_req->aseConfiguration.codecConfiguration,
2445 CodecSpecificConfigurationLtv::Tag::audioChannelAllocation);
2446
2447 /* Allocation and sample freq shall be always in the requirement */
2448 if (!required_sample_freq_ltv || !required_allocation_ltv) {
2449 return false;
2450 }
2451
2452 int required_allocation =
2453 required_allocation_ltv
2454 ->get<
2455 CodecSpecificConfigurationLtv::Tag::audioChannelAllocation>()
2456 .bitmask;
2457
2458 for (const auto& ase_conf : ase_configurations) {
2459 if (!ase_conf) {
2460 continue;
2461 }
2462 auto config_sample_freq_ltv = GetConfigurationLtv(
2463 ase_conf->aseConfiguration.codecConfiguration,
2464 CodecSpecificConfigurationLtv::Tag::samplingFrequency);
2465 auto config_allocation_ltv = GetConfigurationLtv(
2466 ase_conf->aseConfiguration.codecConfiguration,
2467 CodecSpecificConfigurationLtv::Tag::audioChannelAllocation);
2468 if (config_sample_freq_ltv == std::nullopt ||
2469 config_allocation_ltv == std::nullopt) {
2470 return false;
2471 }
2472
2473 int configured_allocation = config_allocation_ltv
2474 ->get<CodecSpecificConfigurationLtv::
2475 Tag::audioChannelAllocation>()
2476 .bitmask;
2477
2478 if (config_sample_freq_ltv == required_sample_freq_ltv &&
2479 (required_allocation & configured_allocation)) {
2480 num_of_satisfied_ase_requirements +=
2481 std::bitset<32>(configured_allocation).count();
2482 }
2483 }
2484 }
2485
2486 return (num_of_satisfied_ase_requirements == num_of_ase_requirements);
2487 }
2488
2489 bool IsAseRequirementSatisfied(
2490 const std::vector<std::optional<AseDirectionRequirement>>&
2491 ase_requirements,
2492 const std::vector<std::optional<AseDirectionConfiguration>>&
2493 ase_configurations) {
2494 // This is mandatory to match sample freq, allocation
2495 int num_of_satisfied_ase_requirements = 0;
2496
2497 int required_allocations = 0;
2498 for (const auto& ase_req : ase_requirements) {
2499 auto required_allocation_ltv = GetConfigurationLtv(
2500 ase_req->aseConfiguration.codecConfiguration,
2501 CodecSpecificConfigurationLtv::Tag::audioChannelAllocation);
2502 if (required_allocation_ltv == std::nullopt) {
2503 continue;
2504 }
2505
2506 int allocations =
2507 required_allocation_ltv
2508 ->get<
2509 CodecSpecificConfigurationLtv::Tag::audioChannelAllocation>()
2510 .bitmask;
2511 required_allocations += std::bitset<32>(allocations).count();
2512 }
2513
2514 if (ase_requirements.size() != required_allocations) {
2515 /* If more than one allication is requested in the requirement, then use
2516 * different verifier */
2517 return IsAseRequirementSatisfiedWithUnknownChannelCount(
2518 ase_requirements, ase_configurations);
2519 }
2520
2521 for (const auto& ase_req : ase_requirements) {
2522 if (!ase_req) {
2523 continue;
2524 }
2525 auto required_sample_freq_ltv = GetConfigurationLtv(
2526 ase_req->aseConfiguration.codecConfiguration,
2527 CodecSpecificConfigurationLtv::Tag::samplingFrequency);
2528 auto required_allocation_ltv = GetConfigurationLtv(
2529 ase_req->aseConfiguration.codecConfiguration,
2530 CodecSpecificConfigurationLtv::Tag::audioChannelAllocation);
2531
2532 /* Allocation and sample freq shall be always in the requirement */
2533 if (!required_sample_freq_ltv || !required_allocation_ltv) {
2534 return false;
2535 }
2536
2537 for (const auto& ase_conf : ase_configurations) {
2538 if (!ase_conf) {
2539 continue;
2540 }
2541 auto config_sample_freq_ltv = GetConfigurationLtv(
2542 ase_conf->aseConfiguration.codecConfiguration,
2543 CodecSpecificConfigurationLtv::Tag::samplingFrequency);
2544 auto config_allocation_ltv = GetConfigurationLtv(
2545 ase_conf->aseConfiguration.codecConfiguration,
2546 CodecSpecificConfigurationLtv::Tag::audioChannelAllocation);
2547 if (config_sample_freq_ltv == std::nullopt ||
2548 config_allocation_ltv == std::nullopt) {
2549 return false;
2550 }
2551
2552 if (config_sample_freq_ltv == required_sample_freq_ltv &&
2553 config_allocation_ltv == required_allocation_ltv) {
2554 num_of_satisfied_ase_requirements++;
2555 break;
2556 }
2557 }
2558 }
2559
2560 return (num_of_satisfied_ase_requirements == ase_requirements.size());
2561 }
2562
Jakub Tyszkowski11178a62024-06-18 10:07:26 +00002563 static void VerifyCodecParameters(
2564 ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
2565 LeAudioAseConfigurationSetting::AseDirectionConfiguration config) {
2566 ASSERT_NE(config.aseConfiguration.codecConfiguration.size(), 0lu);
2567 ASSERT_TRUE(config.qosConfiguration.has_value());
2568
2569 int32_t frame_blocks = 1; // by default 1 if not set
2570 int8_t frame_duration = 0;
2571 int32_t octets_per_frame = 0;
2572 std::bitset<32> allocation_bitmask = 0;
2573
2574 for (auto const& param : config.aseConfiguration.codecConfiguration) {
2575 if (param.getTag() ==
2576 ::aidl::android::hardware::bluetooth::audio::
2577 CodecSpecificConfigurationLtv::Tag::codecFrameBlocksPerSDU) {
2578 frame_blocks = param
2579 .get<::aidl::android::hardware::bluetooth::audio::
2580 CodecSpecificConfigurationLtv::Tag::
2581 codecFrameBlocksPerSDU>()
2582 .value;
2583 } else if (param.getTag() ==
2584 ::aidl::android::hardware::bluetooth::audio::
2585 CodecSpecificConfigurationLtv::Tag::frameDuration) {
2586 frame_duration = static_cast<int8_t>(
2587 param.get<::aidl::android::hardware::bluetooth::audio::
2588 CodecSpecificConfigurationLtv::Tag::frameDuration>());
2589 } else if (param.getTag() ==
2590 ::aidl::android::hardware::bluetooth::audio::
2591 CodecSpecificConfigurationLtv::Tag::octetsPerCodecFrame) {
2592 octets_per_frame = static_cast<int32_t>(
2593 param
2594 .get<::aidl::android::hardware::bluetooth::audio::
2595 CodecSpecificConfigurationLtv::Tag::
2596 octetsPerCodecFrame>()
2597 .value);
2598 } else if (param.getTag() == ::aidl::android::hardware::bluetooth::audio::
2599 CodecSpecificConfigurationLtv::Tag::
2600 audioChannelAllocation) {
2601 allocation_bitmask = static_cast<int32_t>(
2602 param
2603 .get<::aidl::android::hardware::bluetooth::audio::
2604 CodecSpecificConfigurationLtv::Tag::
2605 audioChannelAllocation>()
2606 .bitmask);
2607 }
2608 }
2609
2610 ASSERT_NE(frame_blocks, 0);
2611 ASSERT_NE(frame_duration, 0);
2612 ASSERT_NE(octets_per_frame, 0);
2613
2614 auto const num_channels_per_cis = allocation_bitmask.count();
2615 ASSERT_NE(num_channels_per_cis, 0);
2616
2617 // Verify if QoS takes the codec frame blocks per SDU into the account
2618 ASSERT_TRUE(config.qosConfiguration->sduIntervalUs >=
2619 frame_blocks * frame_duration);
2620 ASSERT_TRUE(config.qosConfiguration->maxSdu >=
2621 (frame_blocks * num_channels_per_cis * octets_per_frame));
2622 }
2623
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00002624 void VerifyIfRequirementsSatisfied(
2625 const std::vector<LeAudioConfigurationRequirement>& requirements,
2626 const std::vector<LeAudioAseConfigurationSetting>& configurations) {
2627 if (requirements.empty() && configurations.empty()) {
2628 return;
2629 }
2630
2631 /* It might happen that vendor lib will provide same configuration for
2632 * multiple contexts and it should be accepted
2633 */
2634
2635 int num_of_requirements = 0;
2636 for (const auto& req : requirements) {
2637 num_of_requirements += std::bitset<32>(req.audioContext.bitmask).count();
2638 }
2639
2640 int num_of_configurations = 0;
2641 for (const auto& conf : configurations) {
2642 num_of_configurations +=
2643 std::bitset<32>(conf.audioContext.bitmask).count();
2644 }
2645
2646 ASSERT_EQ(num_of_requirements, num_of_configurations);
2647
2648 int num_of_satisfied_requirements = 0;
2649 for (const auto& req : requirements) {
2650 for (const auto& conf : configurations) {
2651 if ((req.audioContext.bitmask & conf.audioContext.bitmask) !=
2652 req.audioContext.bitmask) {
2653 continue;
2654 }
2655
Jakub Tyszkowski11178a62024-06-18 10:07:26 +00002656 bool sink_req_satisfied = false;
2657 if (req.sinkAseRequirement) {
2658 ASSERT_TRUE(conf.sinkAseConfiguration.has_value());
2659 sink_req_satisfied = IsAseRequirementSatisfied(
2660 *req.sinkAseRequirement, *conf.sinkAseConfiguration);
2661
2662 ASSERT_NE(conf.sinkAseConfiguration->size(), 0lu);
2663 for (auto const& cfg : conf.sinkAseConfiguration.value()) {
2664 ASSERT_TRUE(cfg.has_value());
2665 VerifyCodecParameters(cfg.value());
2666 }
2667 }
2668
2669 bool source_req_satisfied = false;
2670 if (req.sourceAseRequirement) {
2671 ASSERT_TRUE(conf.sourceAseConfiguration.has_value());
2672 source_req_satisfied = IsAseRequirementSatisfied(
2673 *req.sourceAseRequirement, *conf.sourceAseConfiguration);
2674
2675 ASSERT_NE(conf.sourceAseConfiguration->size(), 0lu);
2676 for (auto const& cfg : conf.sourceAseConfiguration.value()) {
2677 ASSERT_TRUE(cfg.has_value());
2678 VerifyCodecParameters(cfg.value());
2679 }
2680 }
2681
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00002682 if (req.sinkAseRequirement && req.sourceAseRequirement) {
2683 if (!conf.sinkAseConfiguration || !conf.sourceAseConfiguration) {
2684 continue;
2685 }
2686
Jakub Tyszkowski11178a62024-06-18 10:07:26 +00002687 if (!sink_req_satisfied || !source_req_satisfied) {
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00002688 continue;
2689 }
2690 num_of_satisfied_requirements +=
2691 std::bitset<32>(req.audioContext.bitmask).count();
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00002692 break;
2693 } else if (req.sinkAseRequirement) {
Jakub Tyszkowski11178a62024-06-18 10:07:26 +00002694 if (!sink_req_satisfied) {
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00002695 continue;
2696 }
2697 num_of_satisfied_requirements +=
2698 std::bitset<32>(req.audioContext.bitmask).count();
2699 break;
2700 } else if (req.sourceAseRequirement) {
Jakub Tyszkowski11178a62024-06-18 10:07:26 +00002701 if (!source_req_satisfied) {
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00002702 continue;
2703 }
2704 num_of_satisfied_requirements +=
2705 std::bitset<32>(req.audioContext.bitmask).count();
2706 break;
2707 }
2708 }
2709 }
2710 ASSERT_EQ(num_of_satisfied_requirements, num_of_requirements);
2711 }
2712
2713 LeAudioConfigurationRequirement GetUnicastDefaultRequirement(
2714 int32_t context_bits, bool is_sink_requirement,
2715 bool is_source_requriement,
2716 CodecSpecificConfigurationLtv::SamplingFrequency freq =
2717 CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000) {
Bao Doc36897d2023-12-06 01:27:54 +00002718 // Create a requirements
2719 LeAudioConfigurationRequirement requirement;
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00002720 requirement.audioContext = GetAudioContext(context_bits);
2721
2722 auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
2723 allocation.bitmask =
2724 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
2725 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
Bao Doc36897d2023-12-06 01:27:54 +00002726
2727 auto direction_ase_requriement = AseDirectionRequirement();
2728 direction_ase_requriement.aseConfiguration.codecId = CodecId::Core::LC3;
2729 direction_ase_requriement.aseConfiguration.targetLatency =
2730 LeAudioAseConfiguration::TargetLatency::BALANCED_LATENCY_RELIABILITY;
2731
Bao Doc36897d2023-12-06 01:27:54 +00002732 direction_ase_requriement.aseConfiguration.codecConfiguration = {
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00002733 freq, CodecSpecificConfigurationLtv::FrameDuration::US10000, allocation
2734
Bao Doc36897d2023-12-06 01:27:54 +00002735 };
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00002736 if (is_sink_requirement)
2737 requirement.sinkAseRequirement = {direction_ase_requriement};
2738
Bao Doc36897d2023-12-06 01:27:54 +00002739 if (is_source_requriement)
2740 requirement.sourceAseRequirement = {direction_ase_requriement};
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00002741
Bao Doc36897d2023-12-06 01:27:54 +00002742 return requirement;
2743 }
2744
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00002745 LeAudioConfigurationRequirement GetUnicastGameRequirement(bool asymmetric) {
2746 // Create a requirements
2747 LeAudioConfigurationRequirement requirement;
2748 requirement.audioContext = GetAudioContext(AudioContext::GAME);
2749
2750 auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
2751 allocation.bitmask =
2752 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
2753 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
2754
2755 auto sink_ase_requriement = AseDirectionRequirement();
2756 sink_ase_requriement.aseConfiguration.codecId = CodecId::Core::LC3;
2757 sink_ase_requriement.aseConfiguration.targetLatency =
2758 LeAudioAseConfiguration::TargetLatency::BALANCED_LATENCY_RELIABILITY;
2759
2760 sink_ase_requriement.aseConfiguration.codecConfiguration = {
2761 CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000,
2762 CodecSpecificConfigurationLtv::FrameDuration::US10000, allocation};
2763
2764 auto source_ase_requriement = AseDirectionRequirement();
2765 source_ase_requriement.aseConfiguration.codecId = CodecId::Core::LC3;
2766 source_ase_requriement.aseConfiguration.targetLatency =
2767 LeAudioAseConfiguration::TargetLatency::BALANCED_LATENCY_RELIABILITY;
2768
2769 if (asymmetric) {
2770 source_ase_requriement.aseConfiguration.codecConfiguration = {
2771 CodecSpecificConfigurationLtv::SamplingFrequency::HZ8000,
2772 CodecSpecificConfigurationLtv::FrameDuration::US10000, allocation};
2773 } else {
2774 source_ase_requriement.aseConfiguration.codecConfiguration = {
2775 CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000,
2776 CodecSpecificConfigurationLtv::FrameDuration::US10000, allocation};
2777 }
2778
2779 requirement.sinkAseRequirement = {sink_ase_requriement};
2780 requirement.sourceAseRequirement = {source_ase_requriement};
2781
2782 return requirement;
2783 }
2784
2785 LeAudioAseQosConfigurationRequirement GetQosRequirements(
2786 bool is_sink_requirement, bool is_source_requriement, bool valid = true) {
2787 LeAudioAseQosConfigurationRequirement qosRequirement;
2788
2789 auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
2790 allocation.bitmask =
2791 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
2792 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
2793
2794 AseQosDirectionRequirement directionalRequirement = {
2795 .framing = IBluetoothAudioProvider::Framing::UNFRAMED,
2796 .preferredRetransmissionNum = 2,
2797 .maxTransportLatencyMs = 10,
2798 .presentationDelayMinUs = 40000,
2799 .presentationDelayMaxUs = 40000,
2800 .aseConfiguration =
2801 {
2802 .targetLatency = LeAudioAseConfiguration::TargetLatency::
2803 BALANCED_LATENCY_RELIABILITY,
2804 .codecId = CodecId::Core::LC3,
2805 .codecConfiguration =
2806 {CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000,
2807 CodecSpecificConfigurationLtv::FrameDuration::US10000,
2808 allocation},
2809 },
2810 };
2811
2812 if (!valid) {
2813 // clear some required values;
2814 directionalRequirement.maxTransportLatencyMs = 0;
2815 directionalRequirement.presentationDelayMaxUs = 0;
2816 }
2817
2818 qosRequirement.sinkAseQosRequirement = directionalRequirement;
2819 if (is_source_requriement && is_sink_requirement) {
2820 qosRequirement.sourceAseQosRequirement = directionalRequirement;
2821 qosRequirement.sinkAseQosRequirement = directionalRequirement;
2822 } else if (is_source_requriement) {
2823 qosRequirement.sourceAseQosRequirement = directionalRequirement;
2824 qosRequirement.sinkAseQosRequirement = std::nullopt;
2825 } else if (is_sink_requirement) {
2826 qosRequirement.sourceAseQosRequirement = std::nullopt;
2827 qosRequirement.sinkAseQosRequirement = directionalRequirement;
2828 }
2829
2830 return qosRequirement;
2831 }
2832
Josh Wu049e2cd2022-01-12 05:42:58 -08002833 std::vector<Lc3Configuration> GetUnicastLc3SupportedList(bool decoding,
2834 bool supported) {
2835 std::vector<Lc3Configuration> le_audio_codec_configs;
2836 if (!supported) {
shihchienc3ab9f5e2022-09-23 08:18:05 +00002837 Lc3Configuration lc3_config{.pcmBitDepth = 0, .samplingFrequencyHz = 0};
Josh Wu049e2cd2022-01-12 05:42:58 -08002838 le_audio_codec_configs.push_back(lc3_config);
2839 return le_audio_codec_configs;
2840 }
2841
2842 // There might be more than one LeAudioCodecCapabilitiesSetting
2843 std::vector<Lc3Capabilities> lc3_capabilities;
2844 for (auto& capability : temp_provider_capabilities_) {
2845 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2846 continue;
2847 }
2848 auto& le_audio_capability =
2849 capability.get<AudioCapabilities::leAudioCapabilities>();
2850 auto& unicast_capability =
2851 decoding ? le_audio_capability.unicastDecodeCapability
2852 : le_audio_capability.unicastEncodeCapability;
2853 if (unicast_capability.codecType != CodecType::LC3) {
2854 continue;
2855 }
2856 auto& lc3_capability = unicast_capability.leAudioCodecCapabilities.get<
2857 UnicastCapability::LeAudioCodecCapabilities::lc3Capabilities>();
2858 lc3_capabilities.push_back(lc3_capability);
2859 }
2860
2861 // Combine those parameters into one list of LeAudioCodecConfiguration
2862 // This seems horrible, but usually each Lc3Capability only contains a
2863 // single Lc3Configuration, which means every array has a length of 1.
2864 for (auto& lc3_capability : lc3_capabilities) {
2865 for (int32_t samplingFrequencyHz : lc3_capability.samplingFrequencyHz) {
2866 for (int32_t frameDurationUs : lc3_capability.frameDurationUs) {
2867 for (int32_t octetsPerFrame : lc3_capability.octetsPerFrame) {
2868 Lc3Configuration lc3_config = {
2869 .samplingFrequencyHz = samplingFrequencyHz,
2870 .frameDurationUs = frameDurationUs,
2871 .octetsPerFrame = octetsPerFrame,
2872 };
2873 le_audio_codec_configs.push_back(lc3_config);
2874 }
2875 }
2876 }
2877 }
2878
2879 return le_audio_codec_configs;
2880 }
2881
Sagar Verma62df9102022-12-07 17:56:04 +05302882 static constexpr int32_t apx_adaptive_le_config_codec_modes[] = {0, 1, 2, 3};
2883
2884 std::vector<AptxAdaptiveLeConfiguration>
2885 GetUnicastAptxAdaptiveLeSupportedList(bool decoding, bool supported,
2886 bool is_le_extended) {
2887 std::vector<AptxAdaptiveLeConfiguration> le_audio_codec_configs;
2888 if (!supported) {
2889 AptxAdaptiveLeConfiguration aptx_adaptive_le_config{
2890 .pcmBitDepth = 0, .samplingFrequencyHz = 0};
2891 le_audio_codec_configs.push_back(aptx_adaptive_le_config);
2892 return le_audio_codec_configs;
2893 }
2894
2895 // There might be more than one LeAudioCodecCapabilitiesSetting
2896 std::vector<AptxAdaptiveLeCapabilities> aptx_adaptive_le_capabilities;
2897 for (auto& capability : temp_provider_capabilities_) {
2898 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
2899 continue;
2900 }
2901 auto& le_audio_capability =
2902 capability.get<AudioCapabilities::leAudioCapabilities>();
2903 auto& unicast_capability =
2904 decoding ? le_audio_capability.unicastDecodeCapability
2905 : le_audio_capability.unicastEncodeCapability;
2906 if ((!is_le_extended &&
2907 unicast_capability.codecType != CodecType::APTX_ADAPTIVE_LE) ||
2908 (is_le_extended &&
2909 unicast_capability.codecType != CodecType::APTX_ADAPTIVE_LEX)) {
2910 continue;
2911 }
2912
2913 auto& aptx_adaptive_le_capability =
2914 unicast_capability.leAudioCodecCapabilities
2915 .get<UnicastCapability::LeAudioCodecCapabilities::
2916 aptxAdaptiveLeCapabilities>();
2917
2918 aptx_adaptive_le_capabilities.push_back(aptx_adaptive_le_capability);
2919 }
2920
2921 for (auto& aptx_adaptive_le_capability : aptx_adaptive_le_capabilities) {
2922 for (int32_t samplingFrequencyHz :
2923 aptx_adaptive_le_capability.samplingFrequencyHz) {
2924 for (int32_t frameDurationUs :
2925 aptx_adaptive_le_capability.frameDurationUs) {
2926 for (int32_t octetsPerFrame :
2927 aptx_adaptive_le_capability.octetsPerFrame) {
2928 for (int8_t blocksPerSdu :
2929 aptx_adaptive_le_capability.blocksPerSdu) {
2930 for (int32_t codecMode : apx_adaptive_le_config_codec_modes) {
2931 AptxAdaptiveLeConfiguration aptx_adaptive_le_config = {
2932 .samplingFrequencyHz = samplingFrequencyHz,
2933 .frameDurationUs = frameDurationUs,
2934 .octetsPerFrame = octetsPerFrame,
2935 .blocksPerSdu = blocksPerSdu,
2936 .codecMode = codecMode,
2937 };
2938 le_audio_codec_configs.push_back(aptx_adaptive_le_config);
2939 }
2940 }
2941 }
2942 }
2943 }
2944 }
2945
2946 return le_audio_codec_configs;
2947 }
2948
Josh Wu049e2cd2022-01-12 05:42:58 -08002949 LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
Bao Doc36897d2023-12-06 01:27:54 +00002950 std::vector<int32_t> all_context_bitmasks = {
2951 AudioContext::UNSPECIFIED, AudioContext::CONVERSATIONAL,
2952 AudioContext::MEDIA, AudioContext::GAME,
2953 AudioContext::INSTRUCTIONAL, AudioContext::VOICE_ASSISTANTS,
2954 AudioContext::LIVE_AUDIO, AudioContext::SOUND_EFFECTS,
2955 AudioContext::NOTIFICATIONS, AudioContext::RINGTONE_ALERTS,
2956 AudioContext::ALERTS, AudioContext::EMERGENCY_ALARM,
2957 };
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00002958
2959 AudioContext bidirectional_contexts = {
2960 .bitmask = AudioContext::CONVERSATIONAL | AudioContext::GAME |
2961 AudioContext::VOICE_ASSISTANTS | AudioContext::LIVE_AUDIO,
2962 };
Josh Wu049e2cd2022-01-12 05:42:58 -08002963};
2964
2965/**
2966 * Test whether each provider of type
2967 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
2968 * stopped
2969 */
2970TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
2971 OpenLeAudioOutputHardwareProvider) {}
2972
2973/**
2974 * Test whether each provider of type
2975 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
Bao Doc36897d2023-12-06 01:27:54 +00002976 * stopped with Unicast hardware encoding config taken from provider info
2977 */
2978TEST_P(
2979 BluetoothAudioProviderLeAudioOutputHardwareAidl,
2980 StartAndEndLeAudioOutputSessionWithPossibleUnicastConfigFromProviderInfo) {
Bao Dob487a852023-12-25 10:12:09 +08002981 if (GetProviderFactoryInterfaceVersion() <
2982 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
2983 GTEST_SKIP();
2984 }
Bao Doc36897d2023-12-06 01:27:54 +00002985 if (!IsOffloadOutputProviderInfoSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00002986 GTEST_SKIP();
Bao Doc36897d2023-12-06 01:27:54 +00002987 }
2988
2989 auto lc3_codec_configs = GetUnicastLc3SupportedListFromProviderInfo();
2990 LeAudioConfiguration le_audio_config = {
2991 .codecType = CodecType::LC3,
2992 .peerDelayUs = 0,
2993 };
2994
2995 for (auto& lc3_config : lc3_codec_configs) {
2996 le_audio_config.leAudioCodecConfig
2997 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
2998 DataMQDesc mq_desc;
2999 auto aidl_retval = audio_provider_->startSession(
3000 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
3001 &mq_desc);
3002
3003 ASSERT_TRUE(aidl_retval.isOk());
3004 EXPECT_TRUE(audio_provider_->endSession().isOk());
3005 }
3006}
3007
3008TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
3009 GetEmptyAseConfigurationEmptyCapability) {
Bao Dob487a852023-12-25 10:12:09 +08003010 if (GetProviderFactoryInterfaceVersion() <
3011 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3012 GTEST_SKIP();
3013 }
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00003014
3015 if (IsMultidirectionalCapabilitiesEnabled()) {
3016 GTEST_SKIP();
3017 }
3018
3019 std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
3020 std::vector<LeAudioConfigurationRequirement> empty_requirement;
3021 std::vector<LeAudioAseConfigurationSetting> configurations;
3022
3023 // Check empty capability for source direction
3024 auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3025 std::nullopt, empty_capability, empty_requirement, &configurations);
3026
3027 ASSERT_FALSE(aidl_retval.isOk());
3028
3029 // Check empty capability for sink direction
3030 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3031 empty_capability, std::nullopt, empty_requirement, &configurations);
3032
3033 ASSERT_TRUE(aidl_retval.isOk());
3034 ASSERT_TRUE(configurations.empty());
3035}
3036
3037TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
3038 GetEmptyAseConfigurationEmptyCapability_Multidirectiona) {
3039 if (GetProviderFactoryInterfaceVersion() <
3040 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3041 GTEST_SKIP();
3042 }
3043
3044 if (!IsMultidirectionalCapabilitiesEnabled()) {
3045 GTEST_SKIP();
3046 }
3047
Bao Doc36897d2023-12-06 01:27:54 +00003048 std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
3049 std::vector<LeAudioConfigurationRequirement> empty_requirement;
3050 std::vector<LeAudioAseConfigurationSetting> configurations;
3051
3052 // Check empty capability for source direction
3053 auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3054 std::nullopt, empty_capability, empty_requirement, &configurations);
3055
3056 ASSERT_TRUE(aidl_retval.isOk());
3057 ASSERT_TRUE(configurations.empty());
3058
3059 // Check empty capability for sink direction
3060 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3061 empty_capability, std::nullopt, empty_requirement, &configurations);
3062
3063 ASSERT_TRUE(aidl_retval.isOk());
3064 ASSERT_TRUE(configurations.empty());
3065}
3066
3067TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
3068 GetEmptyAseConfigurationMismatchedRequirement) {
Bao Dob487a852023-12-25 10:12:09 +08003069 if (GetProviderFactoryInterfaceVersion() <
3070 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3071 GTEST_SKIP();
3072 }
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00003073 std::vector<std::optional<LeAudioDeviceCapabilities>> sink_capabilities = {
3074 GetDefaultRemoteSinkCapability()};
3075 std::vector<std::optional<LeAudioDeviceCapabilities>> source_capabilities = {
3076 GetDefaultRemoteSourceCapability()};
3077
3078 auto not_supported_sampling_rate_by_remote =
3079 CodecSpecificConfigurationLtv::SamplingFrequency::HZ11025;
Bao Doc36897d2023-12-06 01:27:54 +00003080
3081 // Check empty capability for source direction
3082 std::vector<LeAudioAseConfigurationSetting> configurations;
3083 std::vector<LeAudioConfigurationRequirement> source_requirements = {
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00003084 GetUnicastDefaultRequirement(AudioContext::LIVE_AUDIO, false /*sink */,
3085 true /* source */,
3086 not_supported_sampling_rate_by_remote)};
Bao Doc36897d2023-12-06 01:27:54 +00003087 auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00003088 std::nullopt, source_capabilities, source_requirements, &configurations);
Bao Doc36897d2023-12-06 01:27:54 +00003089
3090 ASSERT_TRUE(aidl_retval.isOk());
3091 ASSERT_TRUE(configurations.empty());
3092
3093 // Check empty capability for sink direction
3094 std::vector<LeAudioConfigurationRequirement> sink_requirements = {
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00003095 GetUnicastDefaultRequirement(AudioContext::MEDIA, true /*sink */,
3096 false /* source */,
3097 not_supported_sampling_rate_by_remote)};
Bao Doc36897d2023-12-06 01:27:54 +00003098 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00003099 sink_capabilities, std::nullopt, sink_requirements, &configurations);
Bao Doc36897d2023-12-06 01:27:54 +00003100
3101 ASSERT_TRUE(aidl_retval.isOk());
3102 ASSERT_TRUE(configurations.empty());
3103}
3104
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00003105TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl, GetAseConfiguration) {
3106 if (GetProviderFactoryInterfaceVersion() <
3107 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3108 GTEST_SKIP();
3109 }
3110
3111 if (IsMultidirectionalCapabilitiesEnabled()) {
3112 GTEST_SKIP();
3113 }
3114
3115 std::vector<std::optional<LeAudioDeviceCapabilities>> sink_capabilities = {
3116 GetDefaultRemoteSinkCapability()};
3117 std::vector<std::optional<LeAudioDeviceCapabilities>> source_capabilities = {
3118 GetDefaultRemoteSourceCapability()};
3119
3120 // Should not ask for Source on ENCODING session if Multidiretional not
3121 // supported
3122 std::vector<LeAudioAseConfigurationSetting> configurations;
3123 std::vector<LeAudioConfigurationRequirement> source_requirements = {
3124 GetUnicastDefaultRequirement(AudioContext::LIVE_AUDIO, false /* sink */,
3125 true /* source */)};
3126 auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3127 std::nullopt, source_capabilities, source_requirements, &configurations);
3128
3129 ASSERT_FALSE(aidl_retval.isOk());
3130 ASSERT_TRUE(configurations.empty());
3131
3132 // Check capability for remote sink direction
3133 std::vector<LeAudioConfigurationRequirement> sink_requirements = {
3134 GetUnicastDefaultRequirement(AudioContext::MEDIA, true /* sink */,
3135 false /* source */)};
3136 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3137 sink_capabilities, std::nullopt, sink_requirements, &configurations);
3138
3139 ASSERT_TRUE(aidl_retval.isOk());
3140 ASSERT_FALSE(configurations.empty());
3141 VerifyIfRequirementsSatisfied(sink_requirements, configurations);
3142
3143 // Check multiple capability for remote sink direction
3144 std::vector<LeAudioConfigurationRequirement> multi_sink_requirements = {
3145 GetUnicastDefaultRequirement(AudioContext::MEDIA, true /* sink */,
3146 false /* source */),
3147 GetUnicastDefaultRequirement(AudioContext::CONVERSATIONAL,
3148 true /* sink */, false /* source */)};
3149 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3150 sink_capabilities, std::nullopt, multi_sink_requirements,
3151 &configurations);
3152
3153 ASSERT_TRUE(aidl_retval.isOk());
3154 ASSERT_FALSE(configurations.empty());
3155 VerifyIfRequirementsSatisfied(multi_sink_requirements, configurations);
3156
3157 // Check multiple context types in a single requirement.
3158 std::vector<LeAudioConfigurationRequirement> multi_context_sink_requirements =
3159 {GetUnicastDefaultRequirement(
3160 AudioContext::MEDIA | AudioContext::SOUND_EFFECTS, true /* sink */,
3161 false /* source */)};
3162 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3163 sink_capabilities, std::nullopt, multi_context_sink_requirements,
3164 &configurations);
3165
3166 ASSERT_TRUE(aidl_retval.isOk());
3167 ASSERT_FALSE(configurations.empty());
3168 VerifyIfRequirementsSatisfied(multi_sink_requirements, configurations);
3169}
3170
3171TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
3172 GetAseConfiguration_Multidirectional) {
3173 if (GetProviderFactoryInterfaceVersion() <
3174 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3175 GTEST_SKIP();
3176 }
3177
3178 if (!IsMultidirectionalCapabilitiesEnabled()) {
3179 GTEST_SKIP();
3180 }
3181
3182 std::vector<std::optional<LeAudioDeviceCapabilities>> sink_capabilities = {
3183 GetDefaultRemoteSinkCapability()};
3184 std::vector<std::optional<LeAudioDeviceCapabilities>> source_capabilities = {
3185 GetDefaultRemoteSourceCapability()};
3186
3187 // Verify source configuration is received
3188 std::vector<LeAudioAseConfigurationSetting> configurations;
3189 std::vector<LeAudioConfigurationRequirement> source_requirements = {
3190 GetUnicastDefaultRequirement(AudioContext::LIVE_AUDIO, false /* sink */,
3191 true /* source */)};
3192 auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3193 std::nullopt, source_capabilities, source_requirements, &configurations);
3194
3195 ASSERT_TRUE(aidl_retval.isOk());
3196 ASSERT_FALSE(configurations.empty());
3197 VerifyIfRequirementsSatisfied(source_requirements, configurations);
3198
3199 // Verify sink configuration is received
3200 std::vector<LeAudioConfigurationRequirement> sink_requirements = {
3201 GetUnicastDefaultRequirement(AudioContext::MEDIA, true /* sink */,
3202 false /* source */)};
3203 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3204 sink_capabilities, std::nullopt, sink_requirements, &configurations);
3205
3206 ASSERT_TRUE(aidl_retval.isOk());
3207 ASSERT_FALSE(configurations.empty());
3208 VerifyIfRequirementsSatisfied(sink_requirements, configurations);
3209
3210 std::vector<LeAudioConfigurationRequirement> combined_requirements = {
3211 GetUnicastDefaultRequirement(AudioContext::LIVE_AUDIO, false /* sink */,
3212 true /* source */),
3213 GetUnicastDefaultRequirement(AudioContext::CONVERSATIONAL,
3214 true /* sink */, true /* source */),
3215 GetUnicastDefaultRequirement(AudioContext::MEDIA, true /* sink */,
3216 false /* source */)};
3217
3218 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3219 sink_capabilities, source_capabilities, combined_requirements,
3220 &configurations);
3221
3222 ASSERT_TRUE(aidl_retval.isOk());
3223 ASSERT_FALSE(configurations.empty());
3224 VerifyIfRequirementsSatisfied(combined_requirements, configurations);
3225}
3226
3227TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
3228 GetAsymmetricAseConfiguration_Multidirectional) {
3229 if (GetProviderFactoryInterfaceVersion() <
3230 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3231 GTEST_SKIP();
3232 }
3233
3234 if (!IsMultidirectionalCapabilitiesEnabled()) {
3235 GTEST_SKIP();
3236 }
3237
3238 if (!IsAsymmetricConfigurationAllowed()) {
3239 GTEST_SKIP();
3240 }
3241
3242 std::vector<LeAudioAseConfigurationSetting> configurations;
3243 std::vector<std::optional<LeAudioDeviceCapabilities>> sink_capabilities = {
3244 GetDefaultRemoteSinkCapability()};
3245 std::vector<std::optional<LeAudioDeviceCapabilities>> source_capabilities = {
3246 GetDefaultRemoteSourceCapability()};
3247
3248 std::vector<LeAudioConfigurationRequirement> asymmetric_requirements = {
3249 GetUnicastGameRequirement(true /* Asymmetric */)};
3250
3251 auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3252 sink_capabilities, source_capabilities, asymmetric_requirements,
3253 &configurations);
3254
3255 ASSERT_TRUE(aidl_retval.isOk());
3256 ASSERT_FALSE(configurations.empty());
3257 VerifyIfRequirementsSatisfied(asymmetric_requirements, configurations);
3258}
3259
3260TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
3261 GetQoSConfiguration_Multidirectional) {
3262 if (GetProviderFactoryInterfaceVersion() <
3263 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3264 GTEST_SKIP();
3265 }
3266
3267 if (!IsMultidirectionalCapabilitiesEnabled()) {
3268 GTEST_SKIP();
3269 }
3270
3271 auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
3272 allocation.bitmask =
3273 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
3274 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
3275
3276 LeAudioAseQosConfigurationRequirement requirement =
3277 GetQosRequirements(true, true);
3278
3279 std::vector<IBluetoothAudioProvider::LeAudioAseQosConfiguration>
3280 QoSConfigurations;
3281 bool is_supported = false;
3282 for (auto bitmask : all_context_bitmasks) {
3283 requirement.audioContext = GetAudioContext(bitmask);
3284 bool is_bidirectional = bidirectional_contexts.bitmask & bitmask;
3285
3286 if (is_bidirectional) {
3287 requirement.sourceAseQosRequirement = requirement.sinkAseQosRequirement;
3288 } else {
3289 requirement.sourceAseQosRequirement = std::nullopt;
3290 }
3291
3292 IBluetoothAudioProvider::LeAudioAseQosConfigurationPair result;
3293 auto aidl_retval =
3294 audio_provider_->getLeAudioAseQosConfiguration(requirement, &result);
3295 if (!aidl_retval.isOk()) {
3296 // If not OK, then it could be not supported, as it is an optional
3297 // feature
3298 ASSERT_EQ(aidl_retval.getExceptionCode(), EX_UNSUPPORTED_OPERATION);
3299 }
3300
3301 is_supported = true;
3302 if (result.sinkQosConfiguration.has_value()) {
3303 if (is_bidirectional) {
3304 ASSERT_TRUE(result.sourceQosConfiguration.has_value());
3305 } else {
3306 ASSERT_FALSE(result.sourceQosConfiguration.has_value());
3307 }
3308 QoSConfigurations.push_back(result.sinkQosConfiguration.value());
3309 }
3310 }
3311 if (is_supported) {
3312 // QoS Configurations should not be empty, as we searched for all contexts
3313 ASSERT_FALSE(QoSConfigurations.empty());
3314 }
3315}
3316
3317TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
3318 GetQoSConfiguration_InvalidRequirements) {
3319 if (GetProviderFactoryInterfaceVersion() <
3320 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3321 GTEST_SKIP();
3322 }
3323 auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
3324 allocation.bitmask =
3325 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
3326 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
3327
3328 LeAudioAseQosConfigurationRequirement invalid_requirement =
3329 GetQosRequirements(true /* sink */, false /* source */,
3330 false /* valid */);
3331
3332 std::vector<IBluetoothAudioProvider::LeAudioAseQosConfiguration>
3333 QoSConfigurations;
3334 for (auto bitmask : all_context_bitmasks) {
3335 invalid_requirement.audioContext = GetAudioContext(bitmask);
3336 IBluetoothAudioProvider::LeAudioAseQosConfigurationPair result;
3337 auto aidl_retval = audio_provider_->getLeAudioAseQosConfiguration(
3338 invalid_requirement, &result);
3339 ASSERT_FALSE(aidl_retval.isOk());
3340 }
3341}
3342
Bao Doc36897d2023-12-06 01:27:54 +00003343TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl, GetQoSConfiguration) {
Bao Dob487a852023-12-25 10:12:09 +08003344 if (GetProviderFactoryInterfaceVersion() <
3345 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3346 GTEST_SKIP();
3347 }
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00003348 auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
3349 allocation.bitmask =
3350 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
3351 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
3352
Bao Doc36897d2023-12-06 01:27:54 +00003353 IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement requirement;
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00003354 requirement = GetQosRequirements(true /* sink */, false /* source */);
3355
Bao Doc36897d2023-12-06 01:27:54 +00003356 std::vector<IBluetoothAudioProvider::LeAudioAseQosConfiguration>
3357 QoSConfigurations;
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00003358 bool is_supported = false;
Bao Doc36897d2023-12-06 01:27:54 +00003359 for (auto bitmask : all_context_bitmasks) {
Jakub Tyszkowski1d214222024-01-16 09:44:48 +00003360 requirement.audioContext = GetAudioContext(bitmask);
Bao Doc36897d2023-12-06 01:27:54 +00003361 IBluetoothAudioProvider::LeAudioAseQosConfigurationPair result;
3362 auto aidl_retval =
3363 audio_provider_->getLeAudioAseQosConfiguration(requirement, &result);
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00003364 if (!aidl_retval.isOk()) {
3365 // If not OK, then it could be not supported, as it is an optional
3366 // feature
3367 ASSERT_EQ(aidl_retval.getExceptionCode(), EX_UNSUPPORTED_OPERATION);
3368 } else {
3369 is_supported = true;
3370 if (result.sinkQosConfiguration.has_value()) {
3371 QoSConfigurations.push_back(result.sinkQosConfiguration.value());
3372 }
3373 }
Bao Doc36897d2023-12-06 01:27:54 +00003374 }
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00003375
3376 if (is_supported) {
3377 // QoS Configurations should not be empty, as we searched for all contexts
3378 ASSERT_FALSE(QoSConfigurations.empty());
3379 }
3380}
3381
3382TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
3383 GetDataPathConfiguration_Multidirectional) {
3384 IBluetoothAudioProvider::StreamConfig sink_requirement;
3385 IBluetoothAudioProvider::StreamConfig source_requirement;
3386 std::vector<IBluetoothAudioProvider::LeAudioDataPathConfiguration>
3387 DataPathConfigurations;
3388
3389 if (!IsMultidirectionalCapabilitiesEnabled()) {
3390 GTEST_SKIP();
3391 }
3392
3393 bool is_supported = false;
3394 auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
3395 allocation.bitmask =
3396 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
3397 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
3398
3399 auto streamMap = LeAudioConfiguration::StreamMap();
3400
3401 // Use some mandatory configuration
3402 streamMap.streamHandle = 0x0001;
3403 streamMap.audioChannelAllocation = 0x03;
3404 streamMap.aseConfiguration = {
3405 .targetLatency =
3406 LeAudioAseConfiguration::TargetLatency::BALANCED_LATENCY_RELIABILITY,
3407 .codecId = CodecId::Core::LC3,
3408 .codecConfiguration =
3409 {CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000,
3410 CodecSpecificConfigurationLtv::FrameDuration::US10000, allocation},
3411 };
3412
3413 // Bidirectional
3414 sink_requirement.streamMap = {streamMap};
3415 source_requirement.streamMap = {streamMap};
3416
3417 for (auto bitmask : all_context_bitmasks) {
3418 sink_requirement.audioContext = GetAudioContext(bitmask);
3419 source_requirement.audioContext = sink_requirement.audioContext;
3420
3421 IBluetoothAudioProvider::LeAudioDataPathConfigurationPair result;
3422 ::ndk::ScopedAStatus aidl_retval;
3423
3424 bool is_bidirectional = bidirectional_contexts.bitmask & bitmask;
3425 if (is_bidirectional) {
3426 aidl_retval = audio_provider_->getLeAudioAseDatapathConfiguration(
3427 sink_requirement, source_requirement, &result);
3428 } else {
3429 aidl_retval = audio_provider_->getLeAudioAseDatapathConfiguration(
3430 sink_requirement, std::nullopt, &result);
3431 }
3432
3433 if (!aidl_retval.isOk()) {
3434 // If not OK, then it could be not supported, as it is an optional
3435 // feature
3436 ASSERT_EQ(aidl_retval.getExceptionCode(), EX_UNSUPPORTED_OPERATION);
3437 } else {
3438 is_supported = true;
3439 if (result.outputConfig.has_value()) {
3440 if (is_bidirectional) {
3441 ASSERT_TRUE(result.inputConfig.has_value());
3442 } else {
3443 ASSERT_TRUE(!result.inputConfig.has_value());
3444 }
3445 DataPathConfigurations.push_back(result.outputConfig.value());
3446 }
3447 }
3448 }
3449
3450 if (is_supported) {
3451 // Datapath Configurations should not be empty, as we searched for all
3452 // contexts
3453 ASSERT_FALSE(DataPathConfigurations.empty());
3454 }
Bao Doc36897d2023-12-06 01:27:54 +00003455}
Jakub Tyszkowskic8a62242024-01-05 15:25:49 +00003456
3457TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
3458 GetDataPathConfiguration) {
Jakub Tyszkowskie77f8722024-01-29 13:21:21 +00003459 if (GetProviderFactoryInterfaceVersion() <
3460 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3461 GTEST_SKIP();
3462 }
Jakub Tyszkowskic8a62242024-01-05 15:25:49 +00003463 IBluetoothAudioProvider::StreamConfig sink_requirement;
Jakub Tyszkowskic8a62242024-01-05 15:25:49 +00003464 std::vector<IBluetoothAudioProvider::LeAudioDataPathConfiguration>
3465 DataPathConfigurations;
3466 bool is_supported = false;
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00003467 auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
3468 allocation.bitmask =
3469 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
3470 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
3471
3472 auto streamMap = LeAudioConfiguration::StreamMap();
3473
3474 // Use some mandatory configuration
3475 streamMap.streamHandle = 0x0001;
3476 streamMap.audioChannelAllocation = 0x03;
3477 streamMap.aseConfiguration = {
3478 .targetLatency =
3479 LeAudioAseConfiguration::TargetLatency::BALANCED_LATENCY_RELIABILITY,
3480 .codecId = CodecId::Core::LC3,
3481 .codecConfiguration =
3482 {CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000,
3483 CodecSpecificConfigurationLtv::FrameDuration::US10000, allocation},
3484 };
3485
3486 sink_requirement.streamMap = {streamMap};
Jakub Tyszkowskic8a62242024-01-05 15:25:49 +00003487
3488 for (auto bitmask : all_context_bitmasks) {
Jakub Tyszkowski1d214222024-01-16 09:44:48 +00003489 sink_requirement.audioContext = GetAudioContext(bitmask);
Jakub Tyszkowskic8a62242024-01-05 15:25:49 +00003490 IBluetoothAudioProvider::LeAudioDataPathConfigurationPair result;
3491 auto aidl_retval = audio_provider_->getLeAudioAseDatapathConfiguration(
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00003492 sink_requirement, std::nullopt, &result);
3493
Jakub Tyszkowskic8a62242024-01-05 15:25:49 +00003494 if (!aidl_retval.isOk()) {
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00003495 // If not OK, then it could be not supported, as it is an optional
3496 // feature
Jakub Tyszkowskic8a62242024-01-05 15:25:49 +00003497 ASSERT_EQ(aidl_retval.getExceptionCode(), EX_UNSUPPORTED_OPERATION);
3498 } else {
3499 is_supported = true;
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00003500 if (result.outputConfig.has_value()) {
3501 DataPathConfigurations.push_back(result.outputConfig.value());
3502 }
Jakub Tyszkowskic8a62242024-01-05 15:25:49 +00003503 }
3504 }
3505
3506 if (is_supported) {
3507 // Datapath Configurations should not be empty, as we searched for all
3508 // contexts
3509 ASSERT_FALSE(DataPathConfigurations.empty());
3510 }
3511}
3512
Bao Doc36897d2023-12-06 01:27:54 +00003513/**
3514 * Test whether each provider of type
3515 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08003516 * stopped with Unicast hardware encoding config
3517 */
3518TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
3519 StartAndEndLeAudioOutputSessionWithPossibleUnicastConfig) {
3520 if (!IsOffloadOutputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003521 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08003522 }
3523
3524 auto lc3_codec_configs =
3525 GetUnicastLc3SupportedList(false /* decoding */, true /* supported */);
3526 LeAudioConfiguration le_audio_config = {
3527 .codecType = CodecType::LC3,
3528 .peerDelayUs = 0,
3529 };
3530
3531 for (auto& lc3_config : lc3_codec_configs) {
3532 le_audio_config.leAudioCodecConfig
3533 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
3534 DataMQDesc mq_desc;
3535 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08003536 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
3537 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08003538
3539 ASSERT_TRUE(aidl_retval.isOk());
3540 EXPECT_TRUE(audio_provider_->endSession().isOk());
3541 }
3542}
3543
3544/**
3545 * Test whether each provider of type
3546 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
3547 * stopped with Unicast hardware encoding config
3548 *
Josh Wu049e2cd2022-01-12 05:42:58 -08003549 */
3550TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00003551 StartAndEndLeAudioOutputSessionWithInvalidAudioConfiguration) {
Josh Wu049e2cd2022-01-12 05:42:58 -08003552 if (!IsOffloadOutputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003553 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08003554 }
3555
3556 auto lc3_codec_configs =
3557 GetUnicastLc3SupportedList(false /* decoding */, false /* supported */);
3558 LeAudioConfiguration le_audio_config = {
3559 .codecType = CodecType::LC3,
3560 .peerDelayUs = 0,
3561 };
3562
3563 for (auto& lc3_config : lc3_codec_configs) {
3564 le_audio_config.leAudioCodecConfig
3565 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
3566 DataMQDesc mq_desc;
3567 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08003568 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
3569 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08003570
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00003571 // It is OK to start session with invalid configuration
3572 ASSERT_TRUE(aidl_retval.isOk());
Josh Wu049e2cd2022-01-12 05:42:58 -08003573 EXPECT_TRUE(audio_provider_->endSession().isOk());
3574 }
3575}
3576
Sagar Verma62df9102022-12-07 17:56:04 +05303577static std::vector<uint8_t> vendorMetadata = {0x0B, // Length
3578 0xFF, // Type: Vendor-specific
3579 0x0A, 0x00, // Company_ID
3580 0x01, 0x02, 0x03, 0x04, // Data
3581 0x05, 0x06, 0x07, 0x08};
3582
3583/**
3584 * Test whether each provider of type
3585 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
3586 * stopped with Unicast hardware encoding config
3587 */
3588TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
3589 StartAndEndLeAudioOutputSessionWithAptxAdaptiveLeUnicastConfig) {
3590 if (!IsOffloadOutputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003591 GTEST_SKIP();
Sagar Verma62df9102022-12-07 17:56:04 +05303592 }
3593 for (auto codec_type :
3594 {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
3595 bool is_le_extended = (codec_type == CodecType::APTX_ADAPTIVE_LEX);
3596 auto aptx_adaptive_le_codec_configs =
3597 GetUnicastAptxAdaptiveLeSupportedList(false, true, is_le_extended);
3598 LeAudioConfiguration le_audio_config = {
3599 .codecType = codec_type,
3600 .peerDelayUs = 0,
3601 .vendorSpecificMetadata = vendorMetadata,
3602 };
3603
3604 for (auto& aptx_adaptive_le_config : aptx_adaptive_le_codec_configs) {
3605 le_audio_config.leAudioCodecConfig
3606 .set<LeAudioCodecConfiguration::aptxAdaptiveLeConfig>(
3607 aptx_adaptive_le_config);
3608 DataMQDesc mq_desc;
3609 auto aidl_retval = audio_provider_->startSession(
3610 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
3611 &mq_desc);
3612
3613 ASSERT_TRUE(aidl_retval.isOk());
3614 EXPECT_TRUE(audio_provider_->endSession().isOk());
3615 }
3616 }
3617}
3618
3619/**
3620 * Test whether each provider of type
3621 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
3622 * stopped with Unicast hardware encoding config
3623 */
3624TEST_P(
3625 BluetoothAudioProviderLeAudioOutputHardwareAidl,
3626 BluetoothAudioProviderLeAudioOutputHardwareAidl_StartAndEndLeAudioOutputSessionWithInvalidAptxAdaptiveLeAudioConfiguration) {
3627 if (!IsOffloadOutputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003628 GTEST_SKIP();
Sagar Verma62df9102022-12-07 17:56:04 +05303629 }
3630
3631 for (auto codec_type :
3632 {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
3633 bool is_le_extended = (codec_type == CodecType::APTX_ADAPTIVE_LEX);
3634 auto aptx_adaptive_le_codec_configs =
3635 GetUnicastAptxAdaptiveLeSupportedList(false, true, is_le_extended);
3636 LeAudioConfiguration le_audio_config = {
3637 .codecType = codec_type,
3638 .peerDelayUs = 0,
3639 .vendorSpecificMetadata = vendorMetadata,
3640 };
3641
3642 for (auto& aptx_adaptive_le_config : aptx_adaptive_le_codec_configs) {
3643 le_audio_config.leAudioCodecConfig
3644 .set<LeAudioCodecConfiguration::aptxAdaptiveLeConfig>(
3645 aptx_adaptive_le_config);
3646 DataMQDesc mq_desc;
3647 auto aidl_retval = audio_provider_->startSession(
3648 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
3649 &mq_desc);
3650
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00003651 // It is OK to start session with invalid configuration
3652 ASSERT_TRUE(aidl_retval.isOk());
Sagar Verma62df9102022-12-07 17:56:04 +05303653 EXPECT_TRUE(audio_provider_->endSession().isOk());
3654 }
3655 }
3656}
3657
Josh Wu049e2cd2022-01-12 05:42:58 -08003658/**
3659 * openProvider LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH
3660 */
3661class BluetoothAudioProviderLeAudioInputHardwareAidl
3662 : public BluetoothAudioProviderLeAudioOutputHardwareAidl {
3663 public:
3664 virtual void SetUp() override {
3665 BluetoothAudioProviderFactoryAidl::SetUp();
3666 GetProviderCapabilitiesHelper(
3667 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
Bao Doc36897d2023-12-06 01:27:54 +00003668 GetProviderInfoHelper(
3669 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
Josh Wu049e2cd2022-01-12 05:42:58 -08003670 OpenProviderHelper(
3671 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
3672 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
3673 audio_provider_ != nullptr);
3674 }
3675
3676 bool IsOffloadInputSupported() {
3677 for (auto& capability : temp_provider_capabilities_) {
3678 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
3679 continue;
3680 }
3681 auto& le_audio_capability =
3682 capability.get<AudioCapabilities::leAudioCapabilities>();
3683 if (le_audio_capability.unicastDecodeCapability.codecType !=
3684 CodecType::UNKNOWN)
3685 return true;
3686 }
3687 return false;
3688 }
3689
3690 virtual void TearDown() override {
3691 audio_port_ = nullptr;
3692 audio_provider_ = nullptr;
3693 BluetoothAudioProviderFactoryAidl::TearDown();
3694 }
3695};
3696
3697/**
3698 * Test whether each provider of type
Bao Doc36897d2023-12-06 01:27:54 +00003699 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08003700 * stopped
3701 */
3702TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
3703 OpenLeAudioInputHardwareProvider) {}
3704
3705/**
3706 * Test whether each provider of type
Bao Doc36897d2023-12-06 01:27:54 +00003707 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
3708 * stopped with Unicast hardware encoding config taken from provider info
3709 */
3710TEST_P(
3711 BluetoothAudioProviderLeAudioInputHardwareAidl,
3712 StartAndEndLeAudioInputSessionWithPossibleUnicastConfigFromProviderInfo) {
3713 if (!IsOffloadOutputProviderInfoSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003714 GTEST_SKIP();
Bao Doc36897d2023-12-06 01:27:54 +00003715 }
3716
3717 auto lc3_codec_configs = GetUnicastLc3SupportedListFromProviderInfo();
3718 LeAudioConfiguration le_audio_config = {
3719 .codecType = CodecType::LC3,
3720 .peerDelayUs = 0,
3721 };
3722
3723 for (auto& lc3_config : lc3_codec_configs) {
3724 le_audio_config.leAudioCodecConfig
3725 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
3726 DataMQDesc mq_desc;
3727 auto aidl_retval = audio_provider_->startSession(
3728 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
3729 &mq_desc);
3730
3731 ASSERT_TRUE(aidl_retval.isOk());
3732 EXPECT_TRUE(audio_provider_->endSession().isOk());
3733 }
3734}
3735
3736/**
3737 * Test whether each provider of type
3738 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08003739 * stopped with Unicast hardware encoding config
3740 */
3741TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
3742 StartAndEndLeAudioInputSessionWithPossibleUnicastConfig) {
3743 if (!IsOffloadInputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003744 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08003745 }
3746
3747 auto lc3_codec_configs =
3748 GetUnicastLc3SupportedList(true /* decoding */, true /* supported */);
3749 LeAudioConfiguration le_audio_config = {
3750 .codecType = CodecType::LC3,
3751 .peerDelayUs = 0,
3752 };
3753
3754 for (auto& lc3_config : lc3_codec_configs) {
3755 le_audio_config.leAudioCodecConfig
3756 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
3757 DataMQDesc mq_desc;
3758 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08003759 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
3760 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08003761
3762 ASSERT_TRUE(aidl_retval.isOk());
3763 EXPECT_TRUE(audio_provider_->endSession().isOk());
3764 }
3765}
3766
3767/**
3768 * Test whether each provider of type
Bao Doc36897d2023-12-06 01:27:54 +00003769 * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
Josh Wu049e2cd2022-01-12 05:42:58 -08003770 * stopped with Unicast hardware encoding config
3771 *
Josh Wu049e2cd2022-01-12 05:42:58 -08003772 */
3773TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00003774 StartAndEndLeAudioInputSessionWithInvalidAudioConfiguration) {
Josh Wu049e2cd2022-01-12 05:42:58 -08003775 if (!IsOffloadInputSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00003776 GTEST_SKIP();
Josh Wu049e2cd2022-01-12 05:42:58 -08003777 }
3778
3779 auto lc3_codec_configs =
3780 GetUnicastLc3SupportedList(true /* decoding */, false /* supported */);
3781 LeAudioConfiguration le_audio_config = {
3782 .codecType = CodecType::LC3,
3783 .peerDelayUs = 0,
3784 };
3785
3786 for (auto& lc3_config : lc3_codec_configs) {
3787 le_audio_config.leAudioCodecConfig
3788 .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
3789
3790 DataMQDesc mq_desc;
3791 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08003792 audio_port_, AudioConfiguration(le_audio_config), latency_modes,
3793 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08003794
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00003795 // It is OK to start with invalid configuration as it might be unknown on
3796 // start
3797 ASSERT_TRUE(aidl_retval.isOk());
Josh Wu049e2cd2022-01-12 05:42:58 -08003798 EXPECT_TRUE(audio_provider_->endSession().isOk());
3799 }
3800}
3801
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00003802TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
3803 GetEmptyAseConfigurationEmptyCapability) {
3804 if (GetProviderFactoryInterfaceVersion() <
3805 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3806 GTEST_SKIP();
3807 }
3808
3809 if (IsMultidirectionalCapabilitiesEnabled()) {
3810 GTEST_SKIP();
3811 }
3812
3813 std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
3814 std::vector<LeAudioConfigurationRequirement> empty_requirement;
3815 std::vector<LeAudioAseConfigurationSetting> configurations;
3816
3817 // Check success for source direction (Input == DecodingSession == remote
3818 // source)
3819 auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3820 std::nullopt, empty_capability, empty_requirement, &configurations);
3821
3822 ASSERT_TRUE(aidl_retval.isOk());
3823 ASSERT_TRUE(configurations.empty());
3824
3825 // Check failure for sink direction
3826 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3827 empty_capability, std::nullopt, empty_requirement, &configurations);
3828
3829 ASSERT_FALSE(aidl_retval.isOk());
3830}
3831
3832TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
3833 GetEmptyAseConfigurationEmptyCapability_Multidirectional) {
3834 if (GetProviderFactoryInterfaceVersion() <
3835 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3836 GTEST_SKIP();
3837 }
3838
3839 if (!IsMultidirectionalCapabilitiesEnabled()) {
3840 GTEST_SKIP();
3841 }
3842
3843 std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
3844 std::vector<LeAudioConfigurationRequirement> empty_requirement;
3845 std::vector<LeAudioAseConfigurationSetting> configurations;
3846
3847 // Check empty capability for source direction
3848 auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3849 std::nullopt, empty_capability, empty_requirement, &configurations);
3850
3851 ASSERT_TRUE(aidl_retval.isOk());
3852 ASSERT_TRUE(configurations.empty());
3853
3854 // Check empty capability for sink direction
3855 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3856 empty_capability, std::nullopt, empty_requirement, &configurations);
3857
3858 ASSERT_TRUE(aidl_retval.isOk());
3859 ASSERT_TRUE(configurations.empty());
3860}
3861
3862TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl, GetAseConfiguration) {
3863 if (GetProviderFactoryInterfaceVersion() <
3864 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3865 GTEST_SKIP();
3866 }
3867
3868 if (IsMultidirectionalCapabilitiesEnabled()) {
3869 GTEST_SKIP();
3870 }
3871
3872 std::vector<std::optional<LeAudioDeviceCapabilities>> sink_capabilities = {
3873 GetDefaultRemoteSinkCapability()};
3874 std::vector<std::optional<LeAudioDeviceCapabilities>> source_capabilities = {
3875 GetDefaultRemoteSourceCapability()};
3876
3877 // Check source configuration is received
3878 std::vector<LeAudioAseConfigurationSetting> configurations;
3879 std::vector<LeAudioConfigurationRequirement> source_requirements = {
3880 GetUnicastDefaultRequirement(AudioContext::LIVE_AUDIO, false /* sink */,
3881 true /* source */)};
3882 auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3883 std::nullopt, source_capabilities, source_requirements, &configurations);
3884
3885 ASSERT_TRUE(aidl_retval.isOk());
3886 ASSERT_FALSE(configurations.empty());
3887
3888 // Check error result when requesting sink on DECODING session
3889 std::vector<LeAudioConfigurationRequirement> sink_requirements = {
3890 GetUnicastDefaultRequirement(AudioContext::MEDIA, true /* sink */,
3891 false /* source */)};
3892 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3893 sink_capabilities, std::nullopt, sink_requirements, &configurations);
3894
3895 ASSERT_FALSE(aidl_retval.isOk());
3896}
3897
3898TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
3899 GetAseConfiguration_Multidirectional) {
3900 if (GetProviderFactoryInterfaceVersion() <
3901 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3902 GTEST_SKIP();
3903 }
3904
3905 if (!IsMultidirectionalCapabilitiesEnabled()) {
3906 GTEST_SKIP();
3907 }
3908
3909 std::vector<std::optional<LeAudioDeviceCapabilities>> sink_capabilities = {
3910 GetDefaultRemoteSinkCapability()};
3911 std::vector<std::optional<LeAudioDeviceCapabilities>> source_capabilities = {
3912 GetDefaultRemoteSourceCapability()};
3913
3914 // Check source configuration is received
3915 std::vector<LeAudioAseConfigurationSetting> configurations;
3916 std::vector<LeAudioConfigurationRequirement> source_requirements = {
3917 GetUnicastDefaultRequirement(AudioContext::LIVE_AUDIO, false /* sink */,
3918 true /* source */)};
3919 auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3920 std::nullopt, source_capabilities, source_requirements, &configurations);
3921
3922 ASSERT_TRUE(aidl_retval.isOk());
3923 ASSERT_FALSE(configurations.empty());
3924 VerifyIfRequirementsSatisfied(source_requirements, configurations);
3925
3926 // Check empty capability for sink direction
3927 std::vector<LeAudioConfigurationRequirement> sink_requirements = {
3928 GetUnicastDefaultRequirement(AudioContext::MEDIA, true /* sink */,
3929 false /* source */)};
3930 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3931 sink_capabilities, std::nullopt, sink_requirements, &configurations);
3932
3933 ASSERT_TRUE(aidl_retval.isOk());
3934 ASSERT_FALSE(configurations.empty());
3935 VerifyIfRequirementsSatisfied(sink_requirements, configurations);
3936
3937 std::vector<LeAudioConfigurationRequirement> combined_requirements = {
3938 GetUnicastDefaultRequirement(AudioContext::LIVE_AUDIO, false /* sink */,
3939 true /* source */),
3940 GetUnicastDefaultRequirement(AudioContext::CONVERSATIONAL,
3941 true /* sink */, true /* source */),
3942 GetUnicastDefaultRequirement(AudioContext::MEDIA, true /* sink */,
3943 false /* source */)};
3944
3945 aidl_retval = audio_provider_->getLeAudioAseConfiguration(
3946 sink_capabilities, source_capabilities, combined_requirements,
3947 &configurations);
3948
3949 ASSERT_TRUE(aidl_retval.isOk());
3950 ASSERT_FALSE(configurations.empty());
3951 VerifyIfRequirementsSatisfied(combined_requirements, configurations);
3952}
3953
3954TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
3955 GetQoSConfiguration_InvalidRequirements) {
3956 if (GetProviderFactoryInterfaceVersion() <
3957 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3958 GTEST_SKIP();
3959 }
3960 auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
3961 allocation.bitmask =
3962 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
3963 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
3964
3965 LeAudioAseQosConfigurationRequirement invalid_requirement =
3966 GetQosRequirements(false /* sink */, true /* source */,
3967 false /* valid */);
3968
3969 std::vector<IBluetoothAudioProvider::LeAudioAseQosConfiguration>
3970 QoSConfigurations;
3971 for (auto bitmask : all_context_bitmasks) {
3972 invalid_requirement.audioContext = GetAudioContext(bitmask);
3973 IBluetoothAudioProvider::LeAudioAseQosConfigurationPair result;
3974 auto aidl_retval = audio_provider_->getLeAudioAseQosConfiguration(
3975 invalid_requirement, &result);
3976 ASSERT_FALSE(aidl_retval.isOk());
3977 }
3978}
3979
3980TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl, GetQoSConfiguration) {
3981 if (GetProviderFactoryInterfaceVersion() <
3982 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
3983 GTEST_SKIP();
3984 }
3985 auto allocation = CodecSpecificConfigurationLtv::AudioChannelAllocation();
3986 allocation.bitmask =
3987 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
3988 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
3989
3990 IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement requirement;
3991 requirement = GetQosRequirements(false /* sink */, true /* source */);
3992
3993 std::vector<IBluetoothAudioProvider::LeAudioAseQosConfiguration>
3994 QoSConfigurations;
3995 bool is_supported = false;
3996 for (auto bitmask : all_context_bitmasks) {
3997 requirement.audioContext = GetAudioContext(bitmask);
3998 IBluetoothAudioProvider::LeAudioAseQosConfigurationPair result;
3999 auto aidl_retval =
4000 audio_provider_->getLeAudioAseQosConfiguration(requirement, &result);
4001 if (!aidl_retval.isOk()) {
4002 // If not OK, then it could be not supported, as it is an optional
4003 // feature
4004 ASSERT_EQ(aidl_retval.getExceptionCode(), EX_UNSUPPORTED_OPERATION);
4005 } else {
4006 is_supported = true;
4007 if (result.sourceQosConfiguration.has_value()) {
4008 QoSConfigurations.push_back(result.sourceQosConfiguration.value());
4009 }
4010 }
4011 }
4012
4013 if (is_supported) {
4014 // QoS Configurations should not be empty, as we searched for all contexts
4015 ASSERT_FALSE(QoSConfigurations.empty());
4016 }
4017}
Josh Wu049e2cd2022-01-12 05:42:58 -08004018/**
4019 * openProvider LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH
4020 */
4021class BluetoothAudioProviderLeAudioBroadcastSoftwareAidl
4022 : public BluetoothAudioProviderFactoryAidl {
4023 public:
4024 virtual void SetUp() override {
4025 BluetoothAudioProviderFactoryAidl::SetUp();
4026 GetProviderCapabilitiesHelper(
4027 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
4028 OpenProviderHelper(
4029 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
4030 ASSERT_NE(audio_provider_, nullptr);
4031 }
4032
4033 virtual void TearDown() override {
4034 audio_port_ = nullptr;
4035 audio_provider_ = nullptr;
4036 BluetoothAudioProviderFactoryAidl::TearDown();
4037 }
4038
4039 static constexpr int32_t le_audio_output_sample_rates_[] = {
4040 0, 8000, 16000, 24000, 32000, 44100, 48000,
4041 };
4042 static constexpr int8_t le_audio_output_bits_per_samples_[] = {0, 16, 24};
4043 static constexpr ChannelMode le_audio_output_channel_modes_[] = {
4044 ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
4045 static constexpr int32_t le_audio_output_data_interval_us_[] = {
4046 0 /* Invalid */, 10000 /* Valid 10ms */};
4047};
4048
4049/**
4050 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08004051 * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started
4052 * and stopped
Josh Wu049e2cd2022-01-12 05:42:58 -08004053 */
4054TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
Josh Wu3202eab2022-02-17 18:09:05 -08004055 OpenLeAudioOutputSoftwareProvider) {}
Josh Wu049e2cd2022-01-12 05:42:58 -08004056
4057/**
4058 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08004059 * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started
4060 * and stopped with different PCM config
Josh Wu049e2cd2022-01-12 05:42:58 -08004061 */
4062TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
Josh Wu3202eab2022-02-17 18:09:05 -08004063 StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
Josh Wu049e2cd2022-01-12 05:42:58 -08004064 for (auto sample_rate : le_audio_output_sample_rates_) {
4065 for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
4066 for (auto channel_mode : le_audio_output_channel_modes_) {
4067 for (auto data_interval_us : le_audio_output_data_interval_us_) {
4068 PcmConfiguration pcm_config{
4069 .sampleRateHz = sample_rate,
Josh Wu049e2cd2022-01-12 05:42:58 -08004070 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00004071 .bitsPerSample = bits_per_sample,
Josh Wu049e2cd2022-01-12 05:42:58 -08004072 .dataIntervalUs = data_interval_us,
4073 };
Josh Wu8a1be762022-02-15 09:37:29 -08004074 bool is_codec_config_valid =
4075 IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
Josh Wu049e2cd2022-01-12 05:42:58 -08004076 DataMQDesc mq_desc;
4077 auto aidl_retval = audio_provider_->startSession(
Chen Chenc92270e2022-02-14 18:29:52 -08004078 audio_port_, AudioConfiguration(pcm_config), latency_modes,
4079 &mq_desc);
Josh Wu049e2cd2022-01-12 05:42:58 -08004080 DataMQ data_mq(mq_desc);
4081
4082 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
4083 if (is_codec_config_valid) {
4084 EXPECT_TRUE(data_mq.isValid());
4085 }
4086 EXPECT_TRUE(audio_provider_->endSession().isOk());
4087 }
4088 }
4089 }
4090 }
4091}
4092
Alice Kuo336d90c2022-02-16 09:09:59 +08004093/**
4094 * openProvider LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH
4095 */
4096class BluetoothAudioProviderLeAudioBroadcastHardwareAidl
4097 : public BluetoothAudioProviderFactoryAidl {
4098 public:
4099 virtual void SetUp() override {
4100 BluetoothAudioProviderFactoryAidl::SetUp();
4101 GetProviderCapabilitiesHelper(
4102 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
Bao Doc36897d2023-12-06 01:27:54 +00004103 GetProviderInfoHelper(
4104 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
Alice Kuo336d90c2022-02-16 09:09:59 +08004105 OpenProviderHelper(
4106 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
4107 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
4108 audio_provider_ != nullptr);
4109 }
4110
4111 virtual void TearDown() override {
4112 audio_port_ = nullptr;
4113 audio_provider_ = nullptr;
4114 BluetoothAudioProviderFactoryAidl::TearDown();
4115 }
4116
4117 bool IsBroadcastOffloadSupported() {
4118 for (auto& capability : temp_provider_capabilities_) {
4119 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
4120 continue;
4121 }
4122 auto& le_audio_capability =
4123 capability.get<AudioCapabilities::leAudioCapabilities>();
4124 if (le_audio_capability.broadcastCapability.codecType !=
4125 CodecType::UNKNOWN)
4126 return true;
4127 }
4128 return false;
4129 }
4130
Bao Doc36897d2023-12-06 01:27:54 +00004131 bool IsBroadcastOffloadProviderInfoSupported() {
4132 if (!temp_provider_info_.has_value()) return false;
4133 if (temp_provider_info_.value().codecInfos.empty()) return false;
4134 // Check if all codec info is of LeAudio type
4135 for (auto& codec_info : temp_provider_info_.value().codecInfos) {
4136 if (codec_info.transport.getTag() != CodecInfo::Transport::leAudio)
4137 return false;
4138 }
4139 return true;
4140 }
4141
4142 std::vector<Lc3Configuration> GetBroadcastLc3SupportedListFromProviderInfo() {
4143 std::vector<Lc3Configuration> le_audio_codec_configs;
4144 for (auto& codec_info : temp_provider_info_.value().codecInfos) {
4145 // Only gets LC3 codec information
4146 if (codec_info.id != CodecId::Core::LC3) continue;
4147 // Combine those parameters into one list of Lc3Configuration
4148 auto& transport =
4149 codec_info.transport.get<CodecInfo::Transport::Tag::leAudio>();
4150 for (int32_t samplingFrequencyHz : transport.samplingFrequencyHz) {
4151 for (int32_t frameDurationUs : transport.frameDurationUs) {
4152 for (int32_t octetsPerFrame : transport.bitdepth) {
4153 Lc3Configuration lc3_config = {
4154 .samplingFrequencyHz = samplingFrequencyHz,
4155 .frameDurationUs = frameDurationUs,
4156 .octetsPerFrame = octetsPerFrame,
4157 };
4158 le_audio_codec_configs.push_back(lc3_config);
4159 }
4160 }
4161 }
4162 }
4163
4164 return le_audio_codec_configs;
4165 }
4166
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00004167 AudioContext GetAudioContext(int32_t bitmask) {
4168 AudioContext media_audio_context;
4169 media_audio_context.bitmask = bitmask;
4170 return media_audio_context;
4171 }
4172
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00004173 std::optional<CodecSpecificConfigurationLtv::SamplingFrequency>
4174 GetBisSampleFreq(const LeAudioBisConfiguration& bis_conf) {
4175 auto sample_freq_ltv = GetConfigurationLtv(
4176 bis_conf.codecConfiguration,
4177 CodecSpecificConfigurationLtv::Tag::samplingFrequency);
4178 if (!sample_freq_ltv) {
4179 return std::nullopt;
4180 }
4181 return (*sample_freq_ltv)
4182 .get<CodecSpecificConfigurationLtv::samplingFrequency>();
4183 }
4184
4185 std::vector<CodecSpecificConfigurationLtv::SamplingFrequency>
4186 GetSubgroupSampleFreqs(
4187 const LeAudioBroadcastSubgroupConfiguration& subgroup_conf) {
4188 std::vector<CodecSpecificConfigurationLtv::SamplingFrequency> result = {};
4189
4190 for (const auto& bis_conf : subgroup_conf.bisConfigurations) {
4191 auto sample_freq = GetBisSampleFreq(bis_conf.bisConfiguration);
4192 if (sample_freq) {
4193 result.push_back(*sample_freq);
4194 }
4195 }
4196 return result;
4197 }
4198
4199 void VerifyBroadcastConfiguration(
4200 const LeAudioBroadcastConfigurationRequirement& requirements,
4201 const LeAudioBroadcastConfigurationSetting& configuration,
4202 std::vector<CodecSpecificConfigurationLtv::SamplingFrequency>
4203 expectedSampleFreqs = {}) {
4204 std::vector<CodecSpecificConfigurationLtv::SamplingFrequency> sampleFreqs =
4205 {};
4206
4207 int number_of_requested_bises = 0;
4208 for (const auto& subgroup_req :
4209 requirements.subgroupConfigurationRequirements) {
4210 number_of_requested_bises += subgroup_req.bisNumPerSubgroup;
4211 }
4212
4213 if (!expectedSampleFreqs.empty()) {
4214 for (const auto& subgroup_conf : configuration.subgroupsConfigurations) {
4215 auto result = GetSubgroupSampleFreqs(subgroup_conf);
4216 sampleFreqs.insert(sampleFreqs.end(), result.begin(), result.end());
4217 }
4218 }
4219
4220 ASSERT_EQ(number_of_requested_bises, configuration.numBis);
4221 ASSERT_EQ(requirements.subgroupConfigurationRequirements.size(),
4222 configuration.subgroupsConfigurations.size());
4223
4224 if (expectedSampleFreqs.empty()) {
4225 return;
4226 }
4227
4228 std::sort(sampleFreqs.begin(), sampleFreqs.end());
4229 std::sort(expectedSampleFreqs.begin(), expectedSampleFreqs.end());
4230
4231 ASSERT_EQ(sampleFreqs, expectedSampleFreqs);
4232 }
4233
4234 LeAudioDeviceCapabilities GetDefaultBroadcastSinkCapability() {
4235 // Create a capability
4236 LeAudioDeviceCapabilities capability;
4237
4238 capability.codecId = CodecId::Core::LC3;
4239
4240 auto pref_context_metadata = MetadataLtv::PreferredAudioContexts();
4241 pref_context_metadata.values =
4242 GetAudioContext(AudioContext::MEDIA | AudioContext::CONVERSATIONAL |
4243 AudioContext::GAME);
4244 capability.metadata = {pref_context_metadata};
4245
4246 auto sampling_rate =
4247 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies();
4248 sampling_rate.bitmask =
4249 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ48000 |
Bao Do57861bd2024-05-23 17:02:54 +08004250 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ24000 |
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00004251 CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ16000;
4252 auto frame_duration =
4253 CodecSpecificCapabilitiesLtv::SupportedFrameDurations();
4254 frame_duration.bitmask =
4255 CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US7500 |
4256 CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US10000;
4257 auto octets = CodecSpecificCapabilitiesLtv::SupportedOctetsPerCodecFrame();
4258 octets.min = 0;
4259 octets.max = 120;
4260 auto frames = CodecSpecificCapabilitiesLtv::SupportedMaxCodecFramesPerSDU();
4261 frames.value = 2;
4262 capability.codecSpecificCapabilities = {sampling_rate, frame_duration,
4263 octets, frames};
4264 return capability;
4265 }
4266
4267 LeAudioBroadcastConfigurationRequirement GetBroadcastRequirement(
4268 bool standard_quality, bool high_quality) {
4269 LeAudioBroadcastConfigurationRequirement requirement;
4270
4271 AudioContext media_audio_context;
4272 media_audio_context.bitmask = AudioContext::MEDIA;
4273
4274 LeAudioBroadcastSubgroupConfigurationRequirement
4275 standard_quality_requirement = {
4276 .audioContext = media_audio_context,
4277 .quality = IBluetoothAudioProvider::BroadcastQuality::STANDARD,
4278 .bisNumPerSubgroup = 2};
4279
4280 LeAudioBroadcastSubgroupConfigurationRequirement high_quality_requirement =
4281 {.audioContext = media_audio_context,
4282 .quality = IBluetoothAudioProvider::BroadcastQuality::HIGH,
4283 .bisNumPerSubgroup = 2};
4284
4285 if (standard_quality) {
4286 requirement.subgroupConfigurationRequirements.push_back(
4287 standard_quality_requirement);
4288 }
4289
4290 if (high_quality) {
4291 requirement.subgroupConfigurationRequirements.push_back(
4292 high_quality_requirement);
4293 }
4294 return requirement;
4295 }
4296
Alice Kuo336d90c2022-02-16 09:09:59 +08004297 std::vector<Lc3Configuration> GetBroadcastLc3SupportedList(bool supported) {
4298 std::vector<Lc3Configuration> le_audio_codec_configs;
4299 if (!supported) {
shihchienc3ab9f5e2022-09-23 08:18:05 +00004300 Lc3Configuration lc3_config{.pcmBitDepth = 0, .samplingFrequencyHz = 0};
Alice Kuo336d90c2022-02-16 09:09:59 +08004301 le_audio_codec_configs.push_back(lc3_config);
4302 return le_audio_codec_configs;
4303 }
4304
4305 // There might be more than one LeAudioCodecCapabilitiesSetting
4306 std::vector<Lc3Capabilities> lc3_capabilities;
4307 for (auto& capability : temp_provider_capabilities_) {
4308 if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
4309 continue;
4310 }
4311 auto& le_audio_capability =
4312 capability.get<AudioCapabilities::leAudioCapabilities>();
4313 auto& broadcast_capability = le_audio_capability.broadcastCapability;
4314 if (broadcast_capability.codecType != CodecType::LC3) {
4315 continue;
4316 }
4317 auto& lc3_capability = broadcast_capability.leAudioCodecCapabilities.get<
4318 BroadcastCapability::LeAudioCodecCapabilities::lc3Capabilities>();
4319 for (int idx = 0; idx < lc3_capability->size(); idx++)
4320 lc3_capabilities.push_back(*lc3_capability->at(idx));
4321 }
4322
4323 // Combine those parameters into one list of LeAudioCodecConfiguration
4324 // This seems horrible, but usually each Lc3Capability only contains a
4325 // single Lc3Configuration, which means every array has a length of 1.
4326 for (auto& lc3_capability : lc3_capabilities) {
4327 for (int32_t samplingFrequencyHz : lc3_capability.samplingFrequencyHz) {
4328 for (int32_t frameDurationUs : lc3_capability.frameDurationUs) {
4329 for (int32_t octetsPerFrame : lc3_capability.octetsPerFrame) {
4330 Lc3Configuration lc3_config = {
4331 .samplingFrequencyHz = samplingFrequencyHz,
4332 .frameDurationUs = frameDurationUs,
4333 .octetsPerFrame = octetsPerFrame,
4334 };
4335 le_audio_codec_configs.push_back(lc3_config);
4336 }
4337 }
4338 }
4339 }
4340
4341 return le_audio_codec_configs;
4342 }
4343
4344 LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
4345};
4346
4347/**
4348 * Test whether each provider of type
4349 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
4350 * started and stopped
4351 */
4352TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
4353 OpenLeAudioOutputHardwareProvider) {}
4354
4355/**
4356 * Test whether each provider of type
4357 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
Bao Doc36897d2023-12-06 01:27:54 +00004358 * started and stopped with broadcast hardware encoding config taken from
4359 * provider info
4360 */
4361TEST_P(
4362 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
4363 StartAndEndLeAudioBroadcastSessionWithPossibleUnicastConfigFromProviderInfo) {
Bao Dob487a852023-12-25 10:12:09 +08004364 if (GetProviderFactoryInterfaceVersion() <
4365 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
4366 GTEST_SKIP();
4367 }
Bao Doc36897d2023-12-06 01:27:54 +00004368 if (!IsBroadcastOffloadProviderInfoSupported()) {
4369 return;
4370 }
4371
4372 auto lc3_codec_configs = GetBroadcastLc3SupportedListFromProviderInfo();
4373 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
4374 .codecType = CodecType::LC3,
4375 .streamMap = {},
4376 };
4377
4378 for (auto& lc3_config : lc3_codec_configs) {
4379 le_audio_broadcast_config.streamMap.resize(1);
4380 le_audio_broadcast_config.streamMap[0]
4381 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
4382 lc3_config);
4383 le_audio_broadcast_config.streamMap[0].streamHandle = 0x0;
4384 le_audio_broadcast_config.streamMap[0].pcmStreamId = 0x0;
4385 le_audio_broadcast_config.streamMap[0].audioChannelAllocation = 0x1 << 0;
4386
4387 DataMQDesc mq_desc;
4388 auto aidl_retval = audio_provider_->startSession(
4389 audio_port_, AudioConfiguration(le_audio_broadcast_config),
4390 latency_modes, &mq_desc);
4391
4392 ASSERT_TRUE(aidl_retval.isOk());
4393 EXPECT_TRUE(audio_provider_->endSession().isOk());
4394 }
4395}
4396
Bao Do5b2fdab2023-11-20 08:02:55 +00004397TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
4398 GetEmptyBroadcastConfigurationEmptyCapability) {
Bao Dob487a852023-12-25 10:12:09 +08004399 if (GetProviderFactoryInterfaceVersion() <
4400 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
4401 GTEST_SKIP();
4402 }
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00004403
4404 if (!IsBroadcastOffloadSupported()) {
4405 GTEST_SKIP();
4406 }
4407
Bao Do5b2fdab2023-11-20 08:02:55 +00004408 std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
4409 IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement
4410 empty_requirement;
4411
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00004412 IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting configuration;
Bao Do5b2fdab2023-11-20 08:02:55 +00004413
4414 // Check empty capability for source direction
4415 auto aidl_retval = audio_provider_->getLeAudioBroadcastConfiguration(
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00004416 empty_capability, empty_requirement, &configuration);
4417
4418 ASSERT_FALSE(aidl_retval.isOk());
4419}
4420
4421TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
4422 GetBroadcastConfigurationEmptyCapability) {
4423 if (GetProviderFactoryInterfaceVersion() <
4424 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
4425 GTEST_SKIP();
4426 }
4427
4428 if (!IsBroadcastOffloadSupported()) {
4429 GTEST_SKIP();
4430 }
4431
4432 std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
4433 IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting configuration;
4434
4435 IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement
4436 one_subgroup_requirement =
4437 GetBroadcastRequirement(true /* standard*/, false /* high */);
4438
4439 // Check empty capability for source direction
4440 auto aidl_retval = audio_provider_->getLeAudioBroadcastConfiguration(
4441 empty_capability, one_subgroup_requirement, &configuration);
Bao Do5b2fdab2023-11-20 08:02:55 +00004442
4443 ASSERT_TRUE(aidl_retval.isOk());
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00004444 ASSERT_NE(configuration.numBis, 0);
4445 ASSERT_FALSE(configuration.subgroupsConfigurations.empty());
4446 VerifyBroadcastConfiguration(one_subgroup_requirement, configuration);
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00004447}
4448
4449TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
4450 GetBroadcastConfigurationNonEmptyCapability) {
4451 if (GetProviderFactoryInterfaceVersion() <
4452 BluetoothAudioHalVersion::VERSION_AIDL_V4) {
4453 GTEST_SKIP();
4454 }
4455
4456 if (!IsBroadcastOffloadSupported()) {
4457 GTEST_SKIP();
4458 }
4459
4460 std::vector<std::optional<LeAudioDeviceCapabilities>> capability = {
4461 GetDefaultBroadcastSinkCapability()};
4462
4463 IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement
4464 requirement =
Bao Do7f89d612024-06-07 16:59:52 +08004465 GetBroadcastRequirement(true /* standard*/, false /* high */);
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00004466
4467 IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting configuration;
4468
4469 // Check empty capability for source direction
4470 auto aidl_retval = audio_provider_->getLeAudioBroadcastConfiguration(
4471 capability, requirement, &configuration);
4472
4473 ASSERT_TRUE(aidl_retval.isOk());
4474 ASSERT_NE(configuration.numBis, 0);
4475 ASSERT_FALSE(configuration.subgroupsConfigurations.empty());
4476 VerifyBroadcastConfiguration(requirement, configuration);
Bao Do5b2fdab2023-11-20 08:02:55 +00004477}
4478
Bao Doc36897d2023-12-06 01:27:54 +00004479/**
4480 * Test whether each provider of type
4481 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
Alice Kuo336d90c2022-02-16 09:09:59 +08004482 * started and stopped with broadcast hardware encoding config
4483 */
4484TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
4485 StartAndEndLeAudioBroadcastSessionWithPossibleBroadcastConfig) {
4486 if (!IsBroadcastOffloadSupported()) {
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00004487 GTEST_SKIP();
Alice Kuo336d90c2022-02-16 09:09:59 +08004488 }
4489
4490 auto lc3_codec_configs = GetBroadcastLc3SupportedList(true /* supported */);
4491 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
4492 .codecType = CodecType::LC3,
4493 .streamMap = {},
4494 };
4495
4496 for (auto& lc3_config : lc3_codec_configs) {
Patty Huangac077ef2022-11-23 14:45:15 +08004497 le_audio_broadcast_config.streamMap.resize(1);
Alice Kuo336d90c2022-02-16 09:09:59 +08004498 le_audio_broadcast_config.streamMap[0]
4499 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
4500 lc3_config);
Rongxuan Liuc1aea322023-01-26 17:14:54 +00004501 le_audio_broadcast_config.streamMap[0].streamHandle = 0x0;
4502 le_audio_broadcast_config.streamMap[0].pcmStreamId = 0x0;
4503 le_audio_broadcast_config.streamMap[0].audioChannelAllocation = 0x1 << 0;
4504
Alice Kuo336d90c2022-02-16 09:09:59 +08004505 DataMQDesc mq_desc;
4506 auto aidl_retval = audio_provider_->startSession(
Chen Chen60d52e42022-02-16 12:19:12 -08004507 audio_port_, AudioConfiguration(le_audio_broadcast_config),
4508 latency_modes, &mq_desc);
Alice Kuo336d90c2022-02-16 09:09:59 +08004509
4510 ASSERT_TRUE(aidl_retval.isOk());
4511 EXPECT_TRUE(audio_provider_->endSession().isOk());
4512 }
4513}
4514
4515/**
4516 * Test whether each provider of type
4517 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
4518 * started and stopped with Broadcast hardware encoding config
4519 *
4520 * Disabled since offload codec checking is not ready
4521 */
4522TEST_P(
4523 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
4524 DISABLED_StartAndEndLeAudioBroadcastSessionWithInvalidAudioConfiguration) {
4525 if (!IsBroadcastOffloadSupported()) {
Łukasz Rymanowski5a43cb92024-01-17 21:35:44 +00004526 GTEST_SKIP();
Alice Kuo336d90c2022-02-16 09:09:59 +08004527 }
4528
4529 auto lc3_codec_configs = GetBroadcastLc3SupportedList(false /* supported */);
4530 LeAudioBroadcastConfiguration le_audio_broadcast_config = {
4531 .codecType = CodecType::LC3,
4532 .streamMap = {},
4533 };
4534
4535 for (auto& lc3_config : lc3_codec_configs) {
4536 le_audio_broadcast_config.streamMap[0]
4537 .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
4538 lc3_config);
4539 DataMQDesc mq_desc;
4540 auto aidl_retval = audio_provider_->startSession(
Chen Chen60d52e42022-02-16 12:19:12 -08004541 audio_port_, AudioConfiguration(le_audio_broadcast_config),
4542 latency_modes, &mq_desc);
Alice Kuo336d90c2022-02-16 09:09:59 +08004543
4544 // AIDL call should fail on invalid codec
4545 ASSERT_FALSE(aidl_retval.isOk());
4546 EXPECT_TRUE(audio_provider_->endSession().isOk());
4547 }
4548}
4549
Alice Kuoadcceec2022-03-28 13:28:43 +08004550/**
4551 * openProvider A2DP_SOFTWARE_DECODING_DATAPATH
4552 */
4553class BluetoothAudioProviderA2dpDecodingSoftwareAidl
4554 : public BluetoothAudioProviderFactoryAidl {
4555 public:
4556 virtual void SetUp() override {
4557 BluetoothAudioProviderFactoryAidl::SetUp();
4558 GetProviderCapabilitiesHelper(SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
4559 OpenProviderHelper(SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
4560 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
4561 audio_provider_ != nullptr);
4562 }
4563
4564 virtual void TearDown() override {
4565 audio_port_ = nullptr;
4566 audio_provider_ = nullptr;
4567 BluetoothAudioProviderFactoryAidl::TearDown();
4568 }
4569};
4570
4571/**
4572 * Test whether we can open a provider of type
4573 */
4574TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,
4575 OpenA2dpDecodingSoftwareProvider) {}
4576
4577/**
4578 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08004579 * SessionType::A2DP_SOFTWARE_DECODING_DATAPATH can be started and stopped
4580 * with different PCM config
Alice Kuoadcceec2022-03-28 13:28:43 +08004581 */
4582TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,
4583 StartAndEndA2dpDecodingSoftwareSessionWithPossiblePcmConfig) {
4584 for (auto sample_rate : a2dp_sample_rates) {
4585 for (auto bits_per_sample : a2dp_bits_per_samples) {
4586 for (auto channel_mode : a2dp_channel_modes) {
4587 PcmConfiguration pcm_config{
4588 .sampleRateHz = sample_rate,
Alice Kuoadcceec2022-03-28 13:28:43 +08004589 .channelMode = channel_mode,
shihchienc3ab9f5e2022-09-23 08:18:05 +00004590 .bitsPerSample = bits_per_sample,
Alice Kuoadcceec2022-03-28 13:28:43 +08004591 };
4592 bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
4593 DataMQDesc mq_desc;
4594 auto aidl_retval = audio_provider_->startSession(
4595 audio_port_, AudioConfiguration(pcm_config), latency_modes,
4596 &mq_desc);
4597 DataMQ data_mq(mq_desc);
4598
4599 EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
4600 if (is_codec_config_valid) {
4601 EXPECT_TRUE(data_mq.isValid());
4602 }
4603 EXPECT_TRUE(audio_provider_->endSession().isOk());
4604 }
4605 }
4606 }
4607}
4608
4609/**
4610 * openProvider A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH
4611 */
4612class BluetoothAudioProviderA2dpDecodingHardwareAidl
4613 : public BluetoothAudioProviderFactoryAidl {
4614 public:
4615 virtual void SetUp() override {
4616 BluetoothAudioProviderFactoryAidl::SetUp();
4617 GetProviderCapabilitiesHelper(
4618 SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
4619 OpenProviderHelper(SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
4620 ASSERT_TRUE(temp_provider_capabilities_.empty() ||
4621 audio_provider_ != nullptr);
4622 }
4623
4624 virtual void TearDown() override {
4625 audio_port_ = nullptr;
4626 audio_provider_ = nullptr;
4627 BluetoothAudioProviderFactoryAidl::TearDown();
4628 }
4629
4630 bool IsOffloadSupported() { return (temp_provider_capabilities_.size() > 0); }
4631};
4632
4633/**
4634 * Test whether we can open a provider of type
4635 */
4636TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
4637 OpenA2dpDecodingHardwareProvider) {}
4638
4639/**
4640 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08004641 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
4642 * with SBC hardware encoding config
Alice Kuoadcceec2022-03-28 13:28:43 +08004643 */
4644TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
4645 StartAndEndA2dpSbcDecodingHardwareSession) {
4646 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00004647 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08004648 }
4649
4650 CodecConfiguration codec_config = {
4651 .codecType = CodecType::SBC,
4652 .encodedAudioBitrate = 328000,
4653 .peerMtu = 1005,
4654 .isScmstEnabled = false,
4655 };
4656 auto sbc_codec_specifics = GetSbcCodecSpecificSupportedList(true);
4657
4658 for (auto& codec_specific : sbc_codec_specifics) {
4659 copy_codec_specific(codec_config.config, codec_specific);
4660 DataMQDesc mq_desc;
4661 auto aidl_retval = audio_provider_->startSession(
4662 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
4663
4664 ASSERT_TRUE(aidl_retval.isOk());
4665 EXPECT_TRUE(audio_provider_->endSession().isOk());
4666 }
4667}
4668
4669/**
4670 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08004671 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
4672 * with AAC hardware encoding config
Alice Kuoadcceec2022-03-28 13:28:43 +08004673 */
4674TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
4675 StartAndEndA2dpAacDecodingHardwareSession) {
4676 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00004677 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08004678 }
4679
4680 CodecConfiguration codec_config = {
4681 .codecType = CodecType::AAC,
4682 .encodedAudioBitrate = 320000,
4683 .peerMtu = 1005,
4684 .isScmstEnabled = false,
4685 };
4686 auto aac_codec_specifics = GetAacCodecSpecificSupportedList(true);
4687
4688 for (auto& codec_specific : aac_codec_specifics) {
4689 copy_codec_specific(codec_config.config, codec_specific);
4690 DataMQDesc mq_desc;
4691 auto aidl_retval = audio_provider_->startSession(
4692 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
4693
4694 ASSERT_TRUE(aidl_retval.isOk());
4695 EXPECT_TRUE(audio_provider_->endSession().isOk());
4696 }
4697}
4698
4699/**
4700 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08004701 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
4702 * with LDAC hardware encoding config
Alice Kuoadcceec2022-03-28 13:28:43 +08004703 */
4704TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
4705 StartAndEndA2dpLdacDecodingHardwareSession) {
4706 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00004707 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08004708 }
4709
4710 CodecConfiguration codec_config = {
4711 .codecType = CodecType::LDAC,
4712 .encodedAudioBitrate = 990000,
4713 .peerMtu = 1005,
4714 .isScmstEnabled = false,
4715 };
4716 auto ldac_codec_specifics = GetLdacCodecSpecificSupportedList(true);
4717
4718 for (auto& codec_specific : ldac_codec_specifics) {
4719 copy_codec_specific(codec_config.config, codec_specific);
4720 DataMQDesc mq_desc;
4721 auto aidl_retval = audio_provider_->startSession(
4722 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
4723
4724 ASSERT_TRUE(aidl_retval.isOk());
4725 EXPECT_TRUE(audio_provider_->endSession().isOk());
4726 }
4727}
4728
4729/**
4730 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08004731 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
4732 * with Opus hardware encoding config
Alice Kuoadcceec2022-03-28 13:28:43 +08004733 */
4734TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
Omer Osmana2587da2022-05-01 03:54:11 +00004735 StartAndEndA2dpOpusDecodingHardwareSession) {
Alice Kuoadcceec2022-03-28 13:28:43 +08004736 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00004737 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08004738 }
4739
4740 CodecConfiguration codec_config = {
Omer Osmana2587da2022-05-01 03:54:11 +00004741 .codecType = CodecType::OPUS,
Alice Kuoadcceec2022-03-28 13:28:43 +08004742 .encodedAudioBitrate = 990000,
4743 .peerMtu = 1005,
4744 .isScmstEnabled = false,
4745 };
Omer Osmana2587da2022-05-01 03:54:11 +00004746 auto opus_codec_specifics = GetOpusCodecSpecificSupportedList(true);
Alice Kuoadcceec2022-03-28 13:28:43 +08004747
Omer Osmana2587da2022-05-01 03:54:11 +00004748 for (auto& codec_specific : opus_codec_specifics) {
Alice Kuoadcceec2022-03-28 13:28:43 +08004749 copy_codec_specific(codec_config.config, codec_specific);
4750 DataMQDesc mq_desc;
4751 auto aidl_retval = audio_provider_->startSession(
4752 audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
4753
4754 ASSERT_TRUE(aidl_retval.isOk());
4755 EXPECT_TRUE(audio_provider_->endSession().isOk());
4756 }
4757}
4758
4759/**
4760 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08004761 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
4762 * with AptX hardware encoding config
Alice Kuoadcceec2022-03-28 13:28:43 +08004763 */
4764TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
4765 StartAndEndA2dpAptxDecodingHardwareSession) {
4766 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00004767 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08004768 }
4769
4770 for (auto codec_type : {CodecType::APTX, CodecType::APTX_HD}) {
4771 CodecConfiguration codec_config = {
4772 .codecType = codec_type,
4773 .encodedAudioBitrate =
4774 (codec_type == CodecType::APTX ? 352000 : 576000),
4775 .peerMtu = 1005,
4776 .isScmstEnabled = false,
4777 };
4778
4779 auto aptx_codec_specifics = GetAptxCodecSpecificSupportedList(
4780 (codec_type == CodecType::APTX_HD ? true : false), true);
4781
4782 for (auto& codec_specific : aptx_codec_specifics) {
4783 copy_codec_specific(codec_config.config, codec_specific);
4784 DataMQDesc mq_desc;
4785 auto aidl_retval = audio_provider_->startSession(
4786 audio_port_, AudioConfiguration(codec_config), latency_modes,
4787 &mq_desc);
4788
4789 ASSERT_TRUE(aidl_retval.isOk());
4790 EXPECT_TRUE(audio_provider_->endSession().isOk());
4791 }
4792 }
4793}
4794
4795/**
4796 * Test whether each provider of type
Bao Dob487a852023-12-25 10:12:09 +08004797 * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
4798 * with an invalid codec config
Alice Kuoadcceec2022-03-28 13:28:43 +08004799 */
4800TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
4801 StartAndEndA2dpDecodingHardwareSessionInvalidCodecConfig) {
4802 if (!IsOffloadSupported()) {
Jakub Tyszkowski334bf182024-01-08 13:43:27 +00004803 GTEST_SKIP();
Alice Kuoadcceec2022-03-28 13:28:43 +08004804 }
4805 ASSERT_NE(audio_provider_, nullptr);
4806
4807 std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
Sagar Verma62df9102022-12-07 17:56:04 +05304808 for (auto codec_type : ndk::enum_range<CodecType>()) {
Alice Kuoadcceec2022-03-28 13:28:43 +08004809 switch (codec_type) {
4810 case CodecType::SBC:
4811 codec_specifics = GetSbcCodecSpecificSupportedList(false);
4812 break;
4813 case CodecType::AAC:
4814 codec_specifics = GetAacCodecSpecificSupportedList(false);
4815 break;
4816 case CodecType::LDAC:
4817 codec_specifics = GetLdacCodecSpecificSupportedList(false);
4818 break;
4819 case CodecType::APTX:
4820 codec_specifics = GetAptxCodecSpecificSupportedList(false, false);
4821 break;
4822 case CodecType::APTX_HD:
4823 codec_specifics = GetAptxCodecSpecificSupportedList(true, false);
4824 break;
Omer Osmana2587da2022-05-01 03:54:11 +00004825 case CodecType::OPUS:
4826 codec_specifics = GetOpusCodecSpecificSupportedList(false);
Alice Kuoadcceec2022-03-28 13:28:43 +08004827 continue;
4828 case CodecType::APTX_ADAPTIVE:
Sagar Verma62df9102022-12-07 17:56:04 +05304829 case CodecType::APTX_ADAPTIVE_LE:
4830 case CodecType::APTX_ADAPTIVE_LEX:
Omer Osmana2587da2022-05-01 03:54:11 +00004831 case CodecType::LC3:
Alice Kuoadcceec2022-03-28 13:28:43 +08004832 case CodecType::VENDOR:
4833 case CodecType::UNKNOWN:
4834 codec_specifics.clear();
4835 break;
4836 }
4837 if (codec_specifics.empty()) {
4838 continue;
4839 }
4840
4841 CodecConfiguration codec_config = {
4842 .codecType = codec_type,
4843 .encodedAudioBitrate = 328000,
4844 .peerMtu = 1005,
4845 .isScmstEnabled = false,
4846 };
4847 for (auto codec_specific : codec_specifics) {
4848 copy_codec_specific(codec_config.config, codec_specific);
4849 DataMQDesc mq_desc;
4850 auto aidl_retval = audio_provider_->startSession(
4851 audio_port_, AudioConfiguration(codec_config), latency_modes,
4852 &mq_desc);
4853
4854 // AIDL call should fail on invalid codec
4855 ASSERT_FALSE(aidl_retval.isOk());
4856 EXPECT_TRUE(audio_provider_->endSession().isOk());
4857 }
4858 }
4859}
4860
Josh Wu049e2cd2022-01-12 05:42:58 -08004861GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
4862 BluetoothAudioProviderFactoryAidl);
4863INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderFactoryAidl,
4864 testing::ValuesIn(android::getAidlHalInstanceNames(
4865 IBluetoothAudioProviderFactory::descriptor)),
4866 android::PrintInstanceNameToString);
4867
Antoine SOULIER33c4e5a2023-09-28 21:59:19 +00004868GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothAudioProviderAidl);
4869INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderAidl,
4870 testing::ValuesIn(android::getAidlHalInstanceNames(
4871 IBluetoothAudioProviderFactory::descriptor)),
4872 android::PrintInstanceNameToString);
4873
Josh Wu049e2cd2022-01-12 05:42:58 -08004874GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
Alice Kuoadcceec2022-03-28 13:28:43 +08004875 BluetoothAudioProviderA2dpEncodingSoftwareAidl);
4876INSTANTIATE_TEST_SUITE_P(PerInstance,
4877 BluetoothAudioProviderA2dpEncodingSoftwareAidl,
Josh Wu049e2cd2022-01-12 05:42:58 -08004878 testing::ValuesIn(android::getAidlHalInstanceNames(
4879 IBluetoothAudioProviderFactory::descriptor)),
4880 android::PrintInstanceNameToString);
4881
4882GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
Alice Kuoadcceec2022-03-28 13:28:43 +08004883 BluetoothAudioProviderA2dpEncodingHardwareAidl);
4884INSTANTIATE_TEST_SUITE_P(PerInstance,
4885 BluetoothAudioProviderA2dpEncodingHardwareAidl,
Josh Wu049e2cd2022-01-12 05:42:58 -08004886 testing::ValuesIn(android::getAidlHalInstanceNames(
4887 IBluetoothAudioProviderFactory::descriptor)),
4888 android::PrintInstanceNameToString);
4889
4890GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
4891 BluetoothAudioProviderHearingAidSoftwareAidl);
4892INSTANTIATE_TEST_SUITE_P(PerInstance,
4893 BluetoothAudioProviderHearingAidSoftwareAidl,
4894 testing::ValuesIn(android::getAidlHalInstanceNames(
4895 IBluetoothAudioProviderFactory::descriptor)),
4896 android::PrintInstanceNameToString);
4897
4898GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
4899 BluetoothAudioProviderLeAudioOutputSoftwareAidl);
4900INSTANTIATE_TEST_SUITE_P(PerInstance,
4901 BluetoothAudioProviderLeAudioOutputSoftwareAidl,
4902 testing::ValuesIn(android::getAidlHalInstanceNames(
4903 IBluetoothAudioProviderFactory::descriptor)),
4904 android::PrintInstanceNameToString);
4905
4906GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
4907 BluetoothAudioProviderLeAudioInputSoftwareAidl);
4908INSTANTIATE_TEST_SUITE_P(PerInstance,
4909 BluetoothAudioProviderLeAudioInputSoftwareAidl,
4910 testing::ValuesIn(android::getAidlHalInstanceNames(
4911 IBluetoothAudioProviderFactory::descriptor)),
4912 android::PrintInstanceNameToString);
4913
4914GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
4915 BluetoothAudioProviderLeAudioOutputHardwareAidl);
4916INSTANTIATE_TEST_SUITE_P(PerInstance,
4917 BluetoothAudioProviderLeAudioOutputHardwareAidl,
4918 testing::ValuesIn(android::getAidlHalInstanceNames(
4919 IBluetoothAudioProviderFactory::descriptor)),
4920 android::PrintInstanceNameToString);
4921
4922GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
4923 BluetoothAudioProviderLeAudioInputHardwareAidl);
4924INSTANTIATE_TEST_SUITE_P(PerInstance,
4925 BluetoothAudioProviderLeAudioInputHardwareAidl,
4926 testing::ValuesIn(android::getAidlHalInstanceNames(
4927 IBluetoothAudioProviderFactory::descriptor)),
4928 android::PrintInstanceNameToString);
4929
4930GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
4931 BluetoothAudioProviderLeAudioBroadcastSoftwareAidl);
4932INSTANTIATE_TEST_SUITE_P(PerInstance,
4933 BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
4934 testing::ValuesIn(android::getAidlHalInstanceNames(
4935 IBluetoothAudioProviderFactory::descriptor)),
4936 android::PrintInstanceNameToString);
4937
Alice Kuo336d90c2022-02-16 09:09:59 +08004938GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
4939 BluetoothAudioProviderLeAudioBroadcastHardwareAidl);
4940INSTANTIATE_TEST_SUITE_P(PerInstance,
4941 BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
4942 testing::ValuesIn(android::getAidlHalInstanceNames(
4943 IBluetoothAudioProviderFactory::descriptor)),
4944 android::PrintInstanceNameToString);
Josh Wu049e2cd2022-01-12 05:42:58 -08004945
Alice Kuoadcceec2022-03-28 13:28:43 +08004946GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
4947 BluetoothAudioProviderA2dpDecodingSoftwareAidl);
4948INSTANTIATE_TEST_SUITE_P(PerInstance,
4949 BluetoothAudioProviderA2dpDecodingSoftwareAidl,
4950 testing::ValuesIn(android::getAidlHalInstanceNames(
4951 IBluetoothAudioProviderFactory::descriptor)),
4952 android::PrintInstanceNameToString);
4953
4954GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
4955 BluetoothAudioProviderA2dpDecodingHardwareAidl);
4956INSTANTIATE_TEST_SUITE_P(PerInstance,
4957 BluetoothAudioProviderA2dpDecodingHardwareAidl,
4958 testing::ValuesIn(android::getAidlHalInstanceNames(
4959 IBluetoothAudioProviderFactory::descriptor)),
4960 android::PrintInstanceNameToString);
4961
Bao Do72399432023-11-09 08:13:05 +00004962GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
4963 BluetoothAudioProviderHfpHardwareAidl);
4964INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderHfpHardwareAidl,
4965 testing::ValuesIn(android::getAidlHalInstanceNames(
4966 IBluetoothAudioProviderFactory::descriptor)),
4967 android::PrintInstanceNameToString);
4968
4969GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
4970 BluetoothAudioProviderHfpSoftwareDecodingAidl);
4971INSTANTIATE_TEST_SUITE_P(PerInstance,
4972 BluetoothAudioProviderHfpSoftwareDecodingAidl,
4973 testing::ValuesIn(android::getAidlHalInstanceNames(
4974 IBluetoothAudioProviderFactory::descriptor)),
4975 android::PrintInstanceNameToString);
4976
4977GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
4978 BluetoothAudioProviderHfpSoftwareEncodingAidl);
4979INSTANTIATE_TEST_SUITE_P(PerInstance,
4980 BluetoothAudioProviderHfpSoftwareEncodingAidl,
4981 testing::ValuesIn(android::getAidlHalInstanceNames(
4982 IBluetoothAudioProviderFactory::descriptor)),
4983 android::PrintInstanceNameToString);
4984
Josh Wu049e2cd2022-01-12 05:42:58 -08004985int main(int argc, char** argv) {
4986 ::testing::InitGoogleTest(&argc, argv);
4987 ABinderProcess_setThreadPoolMaxThreadCount(1);
4988 ABinderProcess_startThreadPool();
4989 return RUN_ALL_TESTS();
4990}