1 /*
2 * Copyright 2024 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
17 #include "le_audio_utils.h"
18
19 #include <bluetooth/log.h>
20 #include <gtest/gtest.h>
21
22 #include <cstdint>
23 #include <optional>
24 #include <tuple>
25 #include <vector>
26
27 #include "bta/le_audio/broadcaster/broadcaster_types.h"
28 #include "bta/le_audio/le_audio_types.h"
29 #include "btm_iso_api_types.h"
30
31 namespace server_configurable_flags {
GetServerConfigurableFlag(const std::string &,const std::string &,const std::string &)32 std::string GetServerConfigurableFlag(
33 const std::string& /* experiment_category_name */,
34 const std::string& /* experiment_flag_name */,
35 const std::string& /* default_value */) {
36 return "";
37 }
38 } // namespace server_configurable_flags
39
40 namespace bluetooth {
41 namespace {
42
43 using ::bluetooth::audio::aidl::GetAidlCodecIdFromStackFormat;
44 using ::bluetooth::audio::aidl::
45 GetAidlLeAudioBroadcastConfigurationRequirementFromStackFormat;
46 using ::bluetooth::audio::aidl::GetAidlLeAudioDeviceCapabilitiesFromStackFormat;
47 using ::bluetooth::audio::aidl::
48 GetAidlLeAudioUnicastConfigurationRequirementsFromStackFormat;
49 using ::bluetooth::audio::aidl::GetAidlMetadataFromStackFormat;
50 using ::bluetooth::audio::aidl::GetStackBisConfigFromAidlFormat;
51 using ::bluetooth::audio::aidl::GetStackBroadcastConfigurationFromAidlFormat;
52 using ::bluetooth::audio::aidl::GetStackCodecIdFromAidlFormat;
53 using ::bluetooth::audio::aidl::GetStackLeAudioLtvMapFromAidlFormat;
54 using ::bluetooth::audio::aidl::GetStackSubgroupsFromAidlFormat;
55 using ::bluetooth::audio::aidl::GetStackUnicastConfigurationFromAidlFormat;
56
57 /* LC3 Core Codec: BT Stack and matching AIDL types */
58 static const ::bluetooth::le_audio::types::LeAudioCodecId kStackCodecLc3 = {
59 .coding_format = ::bluetooth::le_audio::types::kLeAudioCodingFormatLC3,
60 .vendor_company_id =
61 ::bluetooth::le_audio::types::kLeAudioVendorCompanyIdUndefined,
62 .vendor_codec_id =
63 ::bluetooth::le_audio::types::kLeAudioVendorCodecIdUndefined};
64 aidl::android::hardware::bluetooth::audio::CodecId::Core kAidlCodecLc3 =
65 aidl::android::hardware::bluetooth::audio::CodecId::Core::LC3;
66
67 /* Vendor Codec: BT Stack and matching AIDL types */
68 static const ::bluetooth::le_audio::types::LeAudioCodecId kStackCodecVendor1 = {
69 .coding_format =
70 ::bluetooth::le_audio::types::kLeAudioCodingFormatVendorSpecific,
71 .vendor_company_id = 0xC0DE,
72 .vendor_codec_id = 0xF00D};
73 aidl::android::hardware::bluetooth::audio::CodecId::Vendor kAidlCodecVendor1{
74 .id = 0xC0DE, .codecId = 0xF00D};
75
76 static const ::bluetooth::le_audio::types::LeAudioCodecId
77 kStackCodecTransparent = {
78 .coding_format = ::bluetooth::hci::kIsoCodingFormatTransparent,
79 .vendor_company_id =
80 ::bluetooth::le_audio::types::kLeAudioVendorCompanyIdUndefined,
81 .vendor_codec_id =
82 ::bluetooth::le_audio::types::kLeAudioVendorCodecIdUndefined};
83
84 namespace test_utils {
85
PrepareStackMetadataLtv()86 static auto PrepareStackMetadataLtv() {
87 ::bluetooth::le_audio::types::LeAudioLtvMap metadata_ltvs;
88 // Prepare the metadata LTVs
89 metadata_ltvs
90 .Add(::bluetooth::le_audio::types::
91 kLeAudioMetadataTypePreferredAudioContext,
92 (uint16_t)10)
93 .Add(::bluetooth::le_audio::types::
94 kLeAudioMetadataTypeStreamingAudioContext,
95 (uint16_t)8)
96 .Add(::bluetooth::le_audio::types::kLeAudioMetadataTypeProgramInfo,
97 std::string{"ProgramInfo"})
98 .Add(::bluetooth::le_audio::types::kLeAudioMetadataTypeLanguage,
99 std::string{"ice"})
100 .Add(::bluetooth::le_audio::types::kLeAudioMetadataTypeCcidList,
101 std::vector<uint8_t>{1, 2, 3})
102 .Add(::bluetooth::le_audio::types::kLeAudioMetadataTypeparentalRating,
103 (uint8_t)0x01)
104 .Add(::bluetooth::le_audio::types::kLeAudioMetadataTypeProgramInfoUri,
105 std::string{"ProgramInfoUri"})
106 .Add(::bluetooth::le_audio::types::kLeAudioMetadataTypeAudioActiveState,
107 false)
108 .Add(::bluetooth::le_audio::types::
109 kLeAudioMetadataTypeBroadcastAudioImmediateRenderingFlag,
110 true)
111 .Add(::bluetooth::le_audio::types::kLeAudioMetadataTypeExtendedMetadata,
112 std::vector<uint8_t>{1, 2, 3})
113 .Add(::bluetooth::le_audio::types::kLeAudioMetadataTypeVendorSpecific,
114 std::vector<uint8_t>{1, 2, 3});
115 return metadata_ltvs;
116 }
117
118 static std::pair<std::vector<std::optional<
119 ::aidl::android::hardware::bluetooth::audio::MetadataLtv>>,
120 bluetooth::le_audio::types::LeAudioLtvMap>
PrepareReferenceMetadata()121 PrepareReferenceMetadata() {
122 std::vector<
123 std::optional<::aidl::android::hardware::bluetooth::audio::MetadataLtv>>
124 aidl_metadata;
125 bluetooth::le_audio::types::LeAudioLtvMap stack_metadata;
126
127 aidl_metadata.push_back(
128 ::aidl::android::hardware::bluetooth::audio::MetadataLtv::
129 PreferredAudioContexts{.values.bitmask =
130 ::aidl::android::hardware::bluetooth::
131 audio::AudioContext::GAME |
132 ::aidl::android::hardware::bluetooth::
133 audio::AudioContext::CONVERSATIONAL});
134 stack_metadata.Add(
135 bluetooth::le_audio::types::kLeAudioMetadataTypePreferredAudioContext,
136 (uint16_t)((bluetooth::le_audio::types::LeAudioContextType::GAME |
137 bluetooth::le_audio::types::LeAudioContextType::
138 CONVERSATIONAL)
139 .value()));
140
141 aidl_metadata.push_back(
142 ::aidl::android::hardware::bluetooth::audio::MetadataLtv::
143 StreamingAudioContexts{.values.bitmask = ::aidl::android::hardware::
144 bluetooth::audio::AudioContext::GAME});
145 stack_metadata.Add(
146 bluetooth::le_audio::types::kLeAudioMetadataTypeStreamingAudioContext,
147 (uint16_t)(bluetooth::le_audio::types::LeAudioContextType::GAME));
148
149 aidl_metadata.push_back(
150 ::aidl::android::hardware::bluetooth::audio::MetadataLtv::VendorSpecific{
151 .companyId = 0x0201, .opaqueValue = {0x03}});
152 stack_metadata.Add(
153 bluetooth::le_audio::types::kLeAudioMetadataTypeVendorSpecific, 0x0201,
154 {0x03});
155
156 return {aidl_metadata, stack_metadata};
157 }
158
PrepareStackCapability(uint16_t capa_sampling_frequency,uint8_t capa_frame_duration,uint8_t audio_channel_counts,uint16_t octets_per_frame_min,uint16_t ocets_per_frame_max,uint8_t codec_frames_per_sdu)159 static auto PrepareStackCapability(uint16_t capa_sampling_frequency,
160 uint8_t capa_frame_duration,
161 uint8_t audio_channel_counts,
162 uint16_t octets_per_frame_min,
163 uint16_t ocets_per_frame_max,
164 uint8_t codec_frames_per_sdu) {
165 uint32_t octets_per_frame_range =
166 octets_per_frame_min | (ocets_per_frame_max << 16);
167
168 return ::bluetooth::le_audio::types::LeAudioLtvMap({
169 {::bluetooth::le_audio::codec_spec_caps::
170 kLeAudioLtvTypeSupportedSamplingFrequencies,
171 UINT16_TO_VEC_UINT8(capa_sampling_frequency)},
172 {::bluetooth::le_audio::codec_spec_caps::
173 kLeAudioLtvTypeSupportedFrameDurations,
174 UINT8_TO_VEC_UINT8(capa_frame_duration)},
175 {::bluetooth::le_audio::codec_spec_caps::
176 kLeAudioLtvTypeSupportedAudioChannelCounts,
177 UINT8_TO_VEC_UINT8(audio_channel_counts)},
178 {::bluetooth::le_audio::codec_spec_caps::
179 kLeAudioLtvTypeSupportedOctetsPerCodecFrame,
180 UINT32_TO_VEC_UINT8(octets_per_frame_range)},
181 {::bluetooth::le_audio::codec_spec_caps::
182 kLeAudioLtvTypeSupportedMaxCodecFramesPerSdu,
183 UINT8_TO_VEC_UINT8(codec_frames_per_sdu)},
184 });
185 }
186
PrepareStackPacRecord(::bluetooth::le_audio::types::LeAudioCodecId codec_id,uint16_t capa_sampling_frequency,uint8_t capa_frame_duration,uint8_t audio_channel_counts,uint16_t octets_per_frame_min,uint16_t octets_per_frame_max,uint8_t codec_frames_per_sdu=1)187 static auto PrepareStackPacRecord(
188 ::bluetooth::le_audio::types::LeAudioCodecId codec_id,
189 uint16_t capa_sampling_frequency, uint8_t capa_frame_duration,
190 uint8_t audio_channel_counts, uint16_t octets_per_frame_min,
191 uint16_t octets_per_frame_max, uint8_t codec_frames_per_sdu = 1) {
192 auto ltv_map = PrepareStackCapability(
193 capa_sampling_frequency, capa_frame_duration, audio_channel_counts,
194 octets_per_frame_min, octets_per_frame_max, codec_frames_per_sdu);
195 return ::bluetooth::le_audio::types::acs_ac_record(
196 {.codec_id = codec_id,
197 .codec_spec_caps = ltv_map,
198 .codec_spec_caps_raw = ltv_map.RawPacket(),
199 .metadata = PrepareStackMetadataLtv().RawPacket()});
200 }
201
202 std::pair<aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
203 LeAudioDataPathConfiguration,
204 ::bluetooth::le_audio::types::DataPathConfiguration>
PrepareReferenceLeAudioDataPathConfigurationVendor()205 PrepareReferenceLeAudioDataPathConfigurationVendor() {
206 aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
207 LeAudioDataPathConfiguration config;
208 config.dataPathId = 0xC0DEC0DE;
209 config.dataPathConfiguration.configuration = std::vector<uint8_t>{0, 1, 2, 3};
210
211 config.isoDataPathConfiguration.codecId = kAidlCodecVendor1;
212 config.isoDataPathConfiguration.isTransparent = false;
213 config.isoDataPathConfiguration.controllerDelayUs = 128;
214 config.isoDataPathConfiguration.configuration = std::vector<uint8_t>();
215
216 ::bluetooth::le_audio::types::DataPathConfiguration stack_config;
217 stack_config.dataPathId = config.dataPathId;
218 stack_config.dataPathConfig = *config.dataPathConfiguration.configuration;
219 stack_config.isoDataPathConfig.codecId =
220 config.isoDataPathConfiguration.isTransparent ? kStackCodecTransparent
221 : kStackCodecVendor1;
222 stack_config.isoDataPathConfig.isTransparent =
223 config.isoDataPathConfiguration.isTransparent;
224 stack_config.isoDataPathConfig.controllerDelayUs =
225 config.isoDataPathConfiguration.controllerDelayUs;
226 stack_config.isoDataPathConfig.configuration =
227 *config.isoDataPathConfiguration.configuration;
228
229 return {config, stack_config};
230 }
231
232 std::pair<aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
233 LeAudioDataPathConfiguration,
234 ::bluetooth::le_audio::types::DataPathConfiguration>
PrepareReferenceLeAudioDataPathConfigurationLc3()235 PrepareReferenceLeAudioDataPathConfigurationLc3() {
236 auto config = ::aidl::android::hardware::bluetooth::audio::
237 IBluetoothAudioProvider::LeAudioDataPathConfiguration{
238 .dataPathId = 0x01, // kIsoDataPathPlatformDefault
239 // Empty vector
240 .dataPathConfiguration = {.configuration = {}},
241 .isoDataPathConfiguration =
242 {
243 .codecId = kAidlCodecLc3,
244 // Transparent - the controller does not encode/decode
245 .isTransparent = true,
246 // Irrelevant for the transparent ISO data path
247 .controllerDelayUs = 0,
248 // Empty for LC3 codec
249 .configuration = std::nullopt,
250 },
251 };
252
253 ::bluetooth::le_audio::types::DataPathConfiguration stack_config;
254 stack_config.dataPathId = config.dataPathId;
255 stack_config.dataPathConfig = *config.dataPathConfiguration.configuration;
256 stack_config.isoDataPathConfig.codecId =
257 config.isoDataPathConfiguration.isTransparent ? kStackCodecTransparent
258 : kStackCodecLc3;
259 stack_config.isoDataPathConfig.isTransparent =
260 config.isoDataPathConfiguration.isTransparent;
261 stack_config.isoDataPathConfig.controllerDelayUs =
262 config.isoDataPathConfiguration.controllerDelayUs;
263 stack_config.isoDataPathConfig.configuration =
264 *config.isoDataPathConfiguration.configuration;
265
266 return {config, stack_config};
267 }
268
269 std::pair<::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
270 LeAudioAseQosConfiguration,
271 bluetooth::le_audio::set_configurations::QosConfigSetting>
PrepareReferenceQosConfiguration(bool is_low_latency)272 PrepareReferenceQosConfiguration(bool is_low_latency) {
273 ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
274 LeAudioAseQosConfiguration aidl_ase_config = ::aidl::android::hardware::
275 bluetooth::audio::IBluetoothAudioProvider::LeAudioAseQosConfiguration{
276 .sduIntervalUs = 10000,
277 .framing = ::aidl::android::hardware::bluetooth::audio::
278 IBluetoothAudioProvider::Framing::UNFRAMED,
279 .phy = {::aidl::android::hardware::bluetooth::audio::Phy::TWO_M},
280 .maxTransportLatencyMs = 10, // Preferred max transport latency
281 .maxSdu = 120,
282 .retransmissionNum = 2,
283 };
284 bluetooth::le_audio::set_configurations::QosConfigSetting stack_ase_config = {
285 .target_latency = is_low_latency
286 ? bluetooth::le_audio::types::kTargetLatencyLower
287 : bluetooth::le_audio::types::
288 kTargetLatencyBalancedLatencyReliability,
289 .retransmission_number = 2,
290 .max_transport_latency = 10,
291 .sduIntervalUs = 10000,
292 .maxSdu = 120,
293 };
294
295 return {aidl_ase_config, stack_ase_config};
296 }
297
298 std::pair<std::vector<::aidl::android::hardware::bluetooth::audio::
299 CodecSpecificConfigurationLtv>,
300 ::bluetooth::le_audio::types::LeAudioLtvMap>
PrepareReferenceCodecSpecificConfigurationLc3(bool is_low_latency,bool is_left,bool is_right)301 PrepareReferenceCodecSpecificConfigurationLc3(bool is_low_latency, bool is_left,
302 bool is_right) {
303 ::bluetooth::le_audio::types::LeAudioLtvMap stack_params;
304 std::vector<::aidl::android::hardware::bluetooth::audio::
305 CodecSpecificConfigurationLtv>
306 aidl_params;
307
308 aidl_params.push_back(
309 is_low_latency
310 ? ::aidl::android::hardware::bluetooth::audio::
311 CodecSpecificConfigurationLtv::SamplingFrequency::HZ24000
312 : ::aidl::android::hardware::bluetooth::audio::
313 CodecSpecificConfigurationLtv::SamplingFrequency::HZ48000);
314 stack_params.Add(
315 le_audio::codec_spec_conf::kLeAudioLtvTypeSamplingFreq,
316 (uint8_t)(is_low_latency
317 ? le_audio::codec_spec_conf::kLeAudioSamplingFreq24000Hz
318 : le_audio::codec_spec_conf::kLeAudioSamplingFreq48000Hz));
319
320 aidl_params.push_back(
321 ::aidl::android::hardware::bluetooth::audio::
322 CodecSpecificConfigurationLtv::AudioChannelAllocation{
323 .bitmask = (is_left ? ::aidl::android::hardware::bluetooth::
324 audio::CodecSpecificConfigurationLtv::
325 AudioChannelAllocation::FRONT_LEFT
326 : 0) |
327 (is_right ? ::aidl::android::hardware::bluetooth::
328 audio::CodecSpecificConfigurationLtv::
329 AudioChannelAllocation::FRONT_RIGHT
330 : 0)});
331 stack_params.Add(
332 le_audio::codec_spec_conf::kLeAudioLtvTypeAudioChannelAllocation,
333 (uint32_t)((is_left ? le_audio::codec_spec_conf::kLeAudioLocationFrontLeft
334 : 0) |
335 (is_right
336 ? le_audio::codec_spec_conf::kLeAudioLocationFrontRight
337 : 0)));
338
339 aidl_params.push_back(
340 ::aidl::android::hardware::bluetooth::audio::
341 CodecSpecificConfigurationLtv::FrameDuration::US7500);
342 stack_params.Add(
343 le_audio::codec_spec_conf::kLeAudioLtvTypeFrameDuration,
344 (uint8_t)le_audio::codec_spec_conf::kLeAudioCodecFrameDur7500us);
345
346 aidl_params.push_back(
347 ::aidl::android::hardware::bluetooth::audio::
348 CodecSpecificConfigurationLtv::CodecFrameBlocksPerSDU{.value = 1});
349 stack_params.Add(
350 le_audio::codec_spec_conf::kLeAudioLtvTypeCodecFrameBlocksPerSdu,
351 (uint8_t)1);
352
353 // TODO: Verify these values with the standard 48kHz and 24kHz configs sets
354 aidl_params.push_back(::aidl::android::hardware::bluetooth::audio::
355 CodecSpecificConfigurationLtv::OctetsPerCodecFrame{
356 .value = is_low_latency ? 80 : 120});
357 stack_params.Add(
358 le_audio::codec_spec_conf::kLeAudioLtvTypeOctetsPerCodecFrame,
359 (uint16_t)(is_low_latency ? 80 : 120));
360
361 return {aidl_params, stack_params};
362 }
363
364 std::pair<::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
365 LeAudioAseConfigurationSetting::AseDirectionConfiguration,
366 ::bluetooth::le_audio::set_configurations::AseConfiguration>
PrepareReferenceAseDirectionConfigLc3(bool is_left,bool is_right,bool is_low_latency,bool has_qos=true,bool has_datapath=true)367 PrepareReferenceAseDirectionConfigLc3(bool is_left, bool is_right,
368 bool is_low_latency, bool has_qos = true,
369 bool has_datapath = true) {
370 ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
371 LeAudioAseConfigurationSetting::AseDirectionConfiguration aidl_ase_config;
372
373 ::bluetooth::le_audio::set_configurations::CodecConfigSetting stack_codec;
374 ::bluetooth::le_audio::set_configurations::AseConfiguration stack_ase_config(
375 stack_codec);
376
377 aidl_ase_config.aseConfiguration.targetLatency =
378 is_low_latency ? ::aidl::android::hardware::bluetooth::audio::
379 LeAudioAseConfiguration::TargetLatency::LOWER
380 : ::aidl::android::hardware::bluetooth::audio::
381 LeAudioAseConfiguration::TargetLatency::
382 BALANCED_LATENCY_RELIABILITY;
383
384 /* Default Phy */
385 aidl_ase_config.aseConfiguration.targetPhy =
386 ::aidl::android::hardware::bluetooth::audio::Phy::TWO_M;
387 // Note: Phy parameter is selected by the BT stack based on the remote support
388 // Phy parameter from the AIDL is considered as a suggestion
389
390 /* Default Codec */
391 aidl_ase_config.aseConfiguration.codecId = kAidlCodecLc3;
392 stack_ase_config.codec.id = kStackCodecLc3;
393
394 /* Default Codec Parameters */
395 auto [aidl_params, stack_params] =
396 PrepareReferenceCodecSpecificConfigurationLc3(is_low_latency, is_left,
397 is_right);
398 aidl_ase_config.aseConfiguration.codecConfiguration = aidl_params;
399 stack_ase_config.codec.params = stack_params;
400
401 /* No vendor codec parameters */
402 aidl_ase_config.aseConfiguration.vendorCodecConfiguration = std::nullopt;
403 stack_ase_config.codec.vendor_params = {};
404
405 /* Default metadata */
406 auto [aidl_metadata, _] = PrepareReferenceMetadata();
407 aidl_ase_config.aseConfiguration.metadata = aidl_metadata;
408
409 auto stack_codec_params = stack_params.GetAsCoreCodecConfig();
410 stack_ase_config.codec.channel_count_per_iso_stream =
411 std::bitset<32>(stack_codec_params.audio_channel_allocation.value_or(1))
412 .count();
413
414 /* QoS configuration */
415 if (has_qos) {
416 auto [aidl_qos_config, stack_qos_config] =
417 PrepareReferenceQosConfiguration(is_low_latency);
418 aidl_ase_config.qosConfiguration = aidl_qos_config;
419 stack_ase_config.qos = stack_qos_config;
420 }
421
422 /* Data path configuration */
423 if (has_datapath) {
424 auto [aidl_datapath_config, stack_datapath_config] =
425 PrepareReferenceLeAudioDataPathConfigurationLc3();
426 aidl_ase_config.dataPathConfiguration = aidl_datapath_config;
427 stack_ase_config.data_path_configuration = stack_datapath_config;
428 }
429
430 return {aidl_ase_config, stack_ase_config};
431 }
432
433 std::pair<::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
434 LeAudioAseConfigurationSetting,
435 ::bluetooth::le_audio::set_configurations::AudioSetConfiguration>
PrepareReferenceAseConfigurationSetting(::bluetooth::le_audio::types::LeAudioContextType ctx_type,bool has_source=false)436 PrepareReferenceAseConfigurationSetting(
437 ::bluetooth::le_audio::types::LeAudioContextType ctx_type,
438 bool has_source = false) {
439 // Prepare the AIDL format config
440 ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
441 LeAudioAseConfigurationSetting aidl_audio_set_config;
442 ::bluetooth::le_audio::set_configurations::AudioSetConfiguration
443 stack_audio_set_config;
444
445 aidl_audio_set_config.audioContext.bitmask = (uint16_t)ctx_type;
446
447 // Packing
448 // AIDL:
449 aidl_audio_set_config.packing = ::aidl::android::hardware::bluetooth::audio::
450 IBluetoothAudioProvider::Packing::SEQUENTIAL;
451 // STACK:
452 stack_audio_set_config.packing = bluetooth::hci::kIsoCigPackingSequential;
453
454 /* Stereo playback - Two sink ASES */
455 if (!aidl_audio_set_config.sinkAseConfiguration) {
456 log::error("Has no sink container");
457 aidl_audio_set_config.sinkAseConfiguration = std::vector<std::optional<
458 ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
459 LeAudioAseConfigurationSetting::AseDirectionConfiguration>>();
460 }
461
462 // Left ASE config
463 auto [aidl_ase_config_left, stack_ase_config_left] =
464 PrepareReferenceAseDirectionConfigLc3(true, false, false);
465 // AIDL:
466 aidl_audio_set_config.sinkAseConfiguration->push_back(aidl_ase_config_left);
467 // STACK:
468 stack_audio_set_config.confs.sink.push_back(stack_ase_config_left);
469
470 // Right ASE config
471 auto [aidl_ase_config_right, stack_ase_config_right] =
472 PrepareReferenceAseDirectionConfigLc3(false, true, false);
473 // AIDL:
474 aidl_audio_set_config.sinkAseConfiguration->push_back(aidl_ase_config_right);
475 // STACK:
476 stack_audio_set_config.confs.sink.push_back(stack_ase_config_right);
477
478 // Config Flags
479 // AIDL:
480 aidl_audio_set_config.flags->bitmask =
481 ::aidl::android::hardware::bluetooth::audio::ConfigurationFlags::
482 SPATIAL_AUDIO |
483 ::aidl::android::hardware::bluetooth::audio::ConfigurationFlags::
484 LOW_LATENCY |
485 ::aidl::android::hardware::bluetooth::audio::ConfigurationFlags::
486 ALLOW_ASYMMETRIC_CONFIGURATIONS |
487 ::aidl::android::hardware::bluetooth::audio::ConfigurationFlags::
488 MONO_MIC_CONFIGURATION;
489
490 /* Low latency, mono microphone - Single source ASE */
491 if (has_source) {
492 if (!aidl_audio_set_config.sourceAseConfiguration) {
493 log::error("Has no source container");
494 aidl_audio_set_config.sourceAseConfiguration = std::vector<std::optional<
495 ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
496 LeAudioAseConfigurationSetting::AseDirectionConfiguration>>();
497 }
498
499 auto [aidl_ase_config_source, stack_ase_config_source] =
500 PrepareReferenceAseDirectionConfigLc3(true, true, true);
501 // AIDL:
502 aidl_audio_set_config.sourceAseConfiguration->push_back(
503 aidl_ase_config_source);
504 // STACK:
505 stack_audio_set_config.confs.source.push_back(stack_ase_config_source);
506 }
507
508 return {aidl_audio_set_config, stack_audio_set_config};
509 }
510
511 std::pair<::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
512 LeAudioSubgroupBisConfiguration,
513 ::bluetooth::le_audio::broadcaster::BroadcastSubgroupBisCodecConfig>
PrepareReferenceBisConfiguration()514 PrepareReferenceBisConfiguration() {
515 ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
516 LeAudioSubgroupBisConfiguration aidl_cfg;
517
518 auto [aidl_codec_spec, stack_codec_spec] =
519 test_utils::PrepareReferenceCodecSpecificConfigurationLc3(true, true,
520 true);
521
522 auto [aidl_metadata, stack_metadata] = test_utils::PrepareReferenceMetadata();
523
524 aidl_cfg.numBis = 2;
525 aidl_cfg.bisConfiguration.codecId = kAidlCodecLc3;
526 aidl_cfg.bisConfiguration.codecConfiguration = aidl_codec_spec;
527 aidl_cfg.bisConfiguration.vendorCodecConfiguration = {0x02, 0x03};
528 aidl_cfg.bisConfiguration.metadata = aidl_metadata;
529
530 // TODO: Add metadata support at the BIS level
531 ::bluetooth::le_audio::broadcaster::BroadcastSubgroupBisCodecConfig stack_cfg(
532 aidl_cfg.numBis, 1, stack_codec_spec, std::vector<uint8_t>{0x02, 0x03});
533
534 return {aidl_cfg, stack_cfg};
535 }
536
537 std::pair<
538 std::vector<
539 ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
540 LeAudioBroadcastSubgroupConfiguration>,
541 std::vector<
542 ::bluetooth::le_audio::broadcaster::BroadcastSubgroupCodecConfig>>
PrepareReferenceBroadcastSubgroups()543 PrepareReferenceBroadcastSubgroups() {
544 std::vector<
545 ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
546 LeAudioBroadcastSubgroupConfiguration>
547 aidl_subgroups;
548 std::vector<::bluetooth::le_audio::broadcaster::BroadcastSubgroupCodecConfig>
549 stack_subgroups;
550
551 auto [aidl_left_params, stack_left_params] =
552 PrepareReferenceCodecSpecificConfigurationLc3(false, true, false);
553
554 auto [aidl_right_params, stack_right_params] =
555 PrepareReferenceCodecSpecificConfigurationLc3(false, false, true);
556
557 ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
558 LeAudioBroadcastSubgroupConfiguration aidl_subgroup{
559 .bisConfigurations =
560 {::aidl::android::hardware::bluetooth::audio::
561 IBluetoothAudioProvider::LeAudioSubgroupBisConfiguration{
562 .numBis = 1,
563 .bisConfiguration =
564 {
565 .codecId = kAidlCodecLc3,
566 .codecConfiguration = aidl_left_params,
567 .vendorCodecConfiguration =
568 {}, // no vendor codec config
569 // The stack does not yet support
570 // metadata at BIS config level
571 .metadata = std::nullopt,
572 },
573 },
574 ::aidl::android::hardware::bluetooth::audio::
575 IBluetoothAudioProvider::LeAudioSubgroupBisConfiguration{
576 .numBis = 1,
577 .bisConfiguration =
578 {
579 .codecId = kAidlCodecLc3,
580 .codecConfiguration = aidl_right_params,
581 .vendorCodecConfiguration =
582 {}, // no vendor codec config
583 // The stack does not yet support
584 // metadata at BIS config level
585 .metadata = std::nullopt,
586 },
587 }},
588 .vendorCodecConfiguration = std::nullopt,
589 };
590 aidl_subgroups.push_back(aidl_subgroup);
591
592 ::bluetooth::le_audio::broadcaster::BroadcastSubgroupCodecConfig
593 stack_subgroup(kStackCodecLc3,
594 {le_audio::broadcaster::BroadcastSubgroupBisCodecConfig(
595 1, 1, stack_left_params, std::nullopt),
596 le_audio::broadcaster::BroadcastSubgroupBisCodecConfig(
597 1, 1, stack_right_params, std::nullopt)},
598 16, std::nullopt);
599 stack_subgroups.push_back(stack_subgroup);
600
601 return {aidl_subgroups, stack_subgroups};
602 }
603
604 ::bluetooth::le_audio::broadcaster::BroadcastQosConfig
PrepareStackBroadcastQosConfig(uint8_t rtn=2,uint16_t max_transport_latency=50)605 PrepareStackBroadcastQosConfig(uint8_t rtn = 2,
606 uint16_t max_transport_latency = 50) {
607 ::bluetooth::le_audio::broadcaster::BroadcastQosConfig qos(
608 rtn, max_transport_latency);
609 return qos;
610 }
611
612 std::pair<::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
613 LeAudioBroadcastConfigurationSetting,
614 ::bluetooth::le_audio::broadcaster::BroadcastConfiguration>
PrepareReferenceBroadcastConfigurationLc3()615 PrepareReferenceBroadcastConfigurationLc3() {
616 ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
617 LeAudioBroadcastConfigurationSetting aidl_config;
618
619 auto [aidl_datapath_config, stack_datapath_config] =
620 PrepareReferenceLeAudioDataPathConfigurationLc3();
621
622 auto [aidl_bis_subgroups, stack_bis_subgroups] =
623 test_utils::PrepareReferenceBroadcastSubgroups();
624
625 aidl_config.dataPathConfiguration = aidl_datapath_config;
626 aidl_config.sduIntervalUs = 10000;
627 aidl_config.numBis = 2;
628 aidl_config.maxSduOctets = 120;
629 aidl_config.maxTransportLatencyMs = 100;
630 aidl_config.retransmitionNum = 4;
631 aidl_config.phy = {::aidl::android::hardware::bluetooth::audio::Phy::TWO_M};
632 aidl_config.packing = ::aidl::android::hardware::bluetooth::audio::
633 IBluetoothAudioProvider::Packing::SEQUENTIAL;
634 aidl_config.framing = ::aidl::android::hardware::bluetooth::audio::
635 IBluetoothAudioProvider::Framing::UNFRAMED;
636 aidl_config.subgroupsConfigurations = aidl_bis_subgroups;
637
638 ::bluetooth::le_audio::broadcaster::BroadcastConfiguration stack_config = {
639 .subgroups = stack_bis_subgroups,
640 .qos = PrepareStackBroadcastQosConfig(aidl_config.retransmitionNum,
641 aidl_config.maxTransportLatencyMs),
642 .data_path = stack_datapath_config,
643 .sduIntervalUs = 10000,
644 .maxSduOctets = 120,
645 .phy = hci::kIsoCigPhy2M,
646 .packing = bluetooth::hci::kIsoCigPackingSequential,
647 .framing = hci::kIsoCigFramingUnframed,
648 };
649
650 return {aidl_config, stack_config};
651 }
652
653 std::pair<::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
654 LeAudioBroadcastConfigurationRequirement,
655 const std::vector<std::pair<
656 ::bluetooth::le_audio::types::LeAudioContextType, uint8_t>>>
PrepareReferenceBroadcastRequirements()657 PrepareReferenceBroadcastRequirements() {
658 ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
659 LeAudioBroadcastConfigurationRequirement aidl_requirements;
660 std::vector<
661 std::pair<::bluetooth::le_audio::types::LeAudioContextType, uint8_t>>
662 stack_requirements;
663
664 std::pair<::bluetooth::le_audio::types::LeAudioContextType, uint8_t>
665 stack_req = std::make_pair(le_audio::types::LeAudioContextType::MEDIA,
666 le_audio::QUALITY_HIGH);
667 ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
668 LeAudioBroadcastSubgroupConfigurationRequirement aidl_req = {
669 .audioContext.bitmask =
670 (int)le_audio::types::LeAudioContextType::MEDIA,
671 .quality = ::aidl::android::hardware::bluetooth::audio::
672 IBluetoothAudioProvider::BroadcastQuality::HIGH,
673 // TODO: Currently there is no equivalent of this in the stack data
674 // format
675 .bisNumPerSubgroup = 2,
676 };
677
678 aidl_requirements.subgroupConfigurationRequirements.push_back(aidl_req);
679 stack_requirements.push_back(stack_req);
680 return {aidl_requirements, stack_requirements};
681 }
682
683 static std::pair<
684 ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
685 LeAudioConfigurationRequirement::AseDirectionRequirement,
686 ::bluetooth::le_audio::CodecManager::UnicastConfigurationRequirements::
687 DeviceDirectionRequirements>
PrepareReferenceDirectionRequirements(int32_t aidl_location,uint32_t stack_location)688 PrepareReferenceDirectionRequirements(int32_t aidl_location,
689 uint32_t stack_location) {
690 ::bluetooth::le_audio::CodecManager::UnicastConfigurationRequirements::
691 DeviceDirectionRequirements stack_req;
692 ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
693 LeAudioConfigurationRequirement::AseDirectionRequirement aidl_req;
694
695 // Target latency
696 stack_req.target_latency =
697 ::bluetooth::le_audio::types::kTargetLatencyBalancedLatencyReliability;
698 aidl_req.aseConfiguration.targetLatency =
699 aidl::android::hardware::bluetooth::audio::LeAudioAseConfiguration::
700 TargetLatency::BALANCED_LATENCY_RELIABILITY;
701
702 // PHY
703 stack_req.target_Phy = ::bluetooth::le_audio::types::kTargetPhy2M;
704 aidl_req.aseConfiguration.targetPhy =
705 aidl::android::hardware::bluetooth::audio::Phy::TWO_M;
706
707 // Sampling frequency
708 stack_req.params.Add(le_audio::codec_spec_conf::kLeAudioLtvTypeSamplingFreq,
709 (uint8_t)::bluetooth::le_audio::codec_spec_conf::
710 kLeAudioSamplingFreq32000Hz);
711 aidl_req.aseConfiguration.codecConfiguration.push_back(
712 ::aidl::android::hardware::bluetooth::audio::
713 CodecSpecificConfigurationLtv::SamplingFrequency::HZ32000);
714
715 // Frame duration
716 stack_req.params.Add(
717 ::bluetooth::le_audio::codec_spec_conf::kLeAudioLtvTypeFrameDuration,
718 (uint8_t)::bluetooth::le_audio::codec_spec_conf::
719 kLeAudioCodecFrameDur10000us);
720 aidl_req.aseConfiguration.codecConfiguration.push_back(
721 ::aidl::android::hardware::bluetooth::audio::
722 CodecSpecificConfigurationLtv::FrameDuration::US10000);
723
724 // Codec frame Blocks per SDU
725 stack_req.params.Add(::bluetooth::le_audio::codec_spec_conf::
726 kLeAudioLtvTypeCodecFrameBlocksPerSdu,
727 (uint8_t)1);
728 aidl_req.aseConfiguration.codecConfiguration.push_back(
729 ::aidl::android::hardware::bluetooth::audio::
730 CodecSpecificConfigurationLtv::CodecFrameBlocksPerSDU{.value = 1});
731
732 // Audio channel allocation
733 stack_req.params.Add(::bluetooth::le_audio::codec_spec_conf::
734 kLeAudioLtvTypeAudioChannelAllocation,
735 (uint32_t)stack_location);
736 aidl_req.aseConfiguration.codecConfiguration.push_back(
737 ::aidl::android::hardware::bluetooth::audio::
738 CodecSpecificConfigurationLtv::AudioChannelAllocation{
739 .bitmask = aidl_location});
740
741 return {aidl_req, stack_req};
742 }
743
744 } // namespace test_utils
745
TEST(BluetoothAudioClientInterfaceAidlTest,testGetAidlCodecIdFromStackFormatLc3)746 TEST(BluetoothAudioClientInterfaceAidlTest,
747 testGetAidlCodecIdFromStackFormatLc3) {
748 /* Verify LC3 core codec */
749 auto aidl_codec = GetAidlCodecIdFromStackFormat(kStackCodecLc3);
750 ASSERT_EQ(aidl_codec.getTag(),
751 aidl::android::hardware::bluetooth::audio::CodecId::core);
752 ASSERT_EQ(
753 aidl_codec
754 .get<aidl::android::hardware::bluetooth::audio::CodecId::core>(),
755 kAidlCodecLc3);
756 }
757
TEST(BluetoothAudioClientInterfaceAidlTest,testGetAidlCodecIdFromStackFormatVendor1)758 TEST(BluetoothAudioClientInterfaceAidlTest,
759 testGetAidlCodecIdFromStackFormatVendor1) {
760 /* Verify vendor codec */
761 auto aidl_codec = GetAidlCodecIdFromStackFormat(kStackCodecVendor1);
762 ASSERT_EQ(aidl_codec.getTag(),
763 aidl::android::hardware::bluetooth::audio::CodecId::vendor);
764 ASSERT_EQ(
765 aidl_codec
766 .get<aidl::android::hardware::bluetooth::audio::CodecId::vendor>(),
767 kAidlCodecVendor1);
768 }
769
TEST(BluetoothAudioClientInterfaceAidlTest,testGetStackCodecIdFromAidlFormatLc3)770 TEST(BluetoothAudioClientInterfaceAidlTest,
771 testGetStackCodecIdFromAidlFormatLc3) {
772 /* Verify LC3 core codec */
773 auto stack_codec = GetStackCodecIdFromAidlFormat(kAidlCodecLc3);
774 ASSERT_EQ(stack_codec, kStackCodecLc3);
775 }
776
TEST(BluetoothAudioClientInterfaceAidlTest,testGetStackCodecIdFromAidlFormatVendor1)777 TEST(BluetoothAudioClientInterfaceAidlTest,
778 testGetStackCodecIdFromAidlFormatVendor1) {
779 /* Verify vendor codec */
780 auto stack_codec = GetStackCodecIdFromAidlFormat(kAidlCodecVendor1);
781 ASSERT_EQ(stack_codec, kStackCodecVendor1);
782 }
783
verifyMetadata(const std::optional<::aidl::android::hardware::bluetooth::audio::MetadataLtv> & aidl_meta,const::bluetooth::le_audio::types::LeAudioMetadata & stack_meta,bool & matched_preferredAudioContexts,bool & matched_streamingAudioContexts,bool & matched_vendorSpecific)784 static void verifyMetadata(
785 const std::optional<
786 ::aidl::android::hardware::bluetooth::audio::MetadataLtv>& aidl_meta,
787 const ::bluetooth::le_audio::types::LeAudioMetadata& stack_meta,
788 bool& matched_preferredAudioContexts, bool& matched_streamingAudioContexts,
789 bool& matched_vendorSpecific) {
790 if (aidl_meta->getTag() == ::aidl::android::hardware::bluetooth::audio::
791 MetadataLtv::preferredAudioContexts) {
792 ASSERT_EQ(aidl_meta
793 ->get<::aidl::android::hardware::bluetooth::audio::
794 MetadataLtv::preferredAudioContexts>()
795 .values.bitmask,
796 stack_meta.preferred_audio_context.value());
797 matched_preferredAudioContexts = true;
798
799 } else if (aidl_meta->getTag() ==
800 ::aidl::android::hardware::bluetooth::audio::MetadataLtv::
801 streamingAudioContexts) {
802 ASSERT_EQ(aidl_meta
803 ->get<::aidl::android::hardware::bluetooth::audio::
804 MetadataLtv::streamingAudioContexts>()
805 .values.bitmask,
806 stack_meta.streaming_audio_context.value());
807 matched_streamingAudioContexts = true;
808
809 } else if (aidl_meta->getTag() == ::aidl::android::hardware::bluetooth::
810 audio::MetadataLtv::vendorSpecific) {
811 auto vendor_spec = aidl_meta->get<::aidl::android::hardware::bluetooth::
812 audio::MetadataLtv::vendorSpecific>();
813
814 /* Company ID is a 2 octet value */
815 ASSERT_EQ(vendor_spec.companyId,
816 stack_meta.vendor_specific->at(0) |
817 (stack_meta.vendor_specific->at(1) << 8));
818 auto expected_payload_size = stack_meta.vendor_specific->size() - 2;
819 ASSERT_EQ(vendor_spec.opaqueValue.size(), expected_payload_size);
820 ASSERT_EQ(0, memcmp(vendor_spec.opaqueValue.data(),
821 stack_meta.vendor_specific->data() + 2,
822 expected_payload_size));
823 matched_vendorSpecific = true;
824 } else {
825 GTEST_FAIL();
826 }
827 }
828
TEST(BluetoothAudioClientInterfaceAidlTest,testGetAidlMetadataFromStackFormat)829 TEST(BluetoothAudioClientInterfaceAidlTest,
830 testGetAidlMetadataFromStackFormat) {
831 ::bluetooth::le_audio::types::LeAudioLtvMap metadata_ltvs =
832 test_utils::PrepareStackMetadataLtv();
833 auto aidl_metadata =
834 GetAidlMetadataFromStackFormat(metadata_ltvs.RawPacket());
835 ASSERT_TRUE(aidl_metadata.has_value());
836
837 /* Only kLeAudioMetadataTypePreferredAudioContext,
838 * kLeAudioMetadataTypeStreamingAudioContext,
839 * kLeAudioMetadataVendorSpecific types are supported on the AIDL
840 */
841 const size_t maxAidlSupportedMetadataTypes = 3;
842 ASSERT_EQ(aidl_metadata->size(), maxAidlSupportedMetadataTypes);
843
844 bool matched_preferredAudioContexts = false;
845 bool matched_streamingAudioContexts = false;
846 bool matched_vendorSpecific = false;
847
848 for (const auto& meta : *aidl_metadata) {
849 ASSERT_TRUE(meta.has_value());
850 verifyMetadata(meta, metadata_ltvs.GetAsLeAudioMetadata(),
851 matched_preferredAudioContexts,
852 matched_streamingAudioContexts, matched_vendorSpecific);
853 }
854
855 ASSERT_TRUE(matched_preferredAudioContexts);
856 ASSERT_TRUE(matched_streamingAudioContexts);
857 ASSERT_TRUE(matched_vendorSpecific);
858 }
859
TEST(BluetoothAudioClientInterfaceAidlTest,testGetAidlLeAudioDeviceCapabilitiesFromStackFormat)860 TEST(BluetoothAudioClientInterfaceAidlTest,
861 testGetAidlLeAudioDeviceCapabilitiesFromStackFormat) {
862 std::vector<bluetooth::le_audio::types::acs_ac_record> pac_records;
863
864 // Add some records
865 auto stack_record = test_utils::PrepareStackPacRecord(
866 kStackCodecLc3,
867 ::bluetooth::le_audio::codec_spec_caps::kLeAudioSamplingFreq16000Hz,
868 ::bluetooth::le_audio::codec_spec_caps::kLeAudioCodecFrameDurPrefer7500us,
869 ::bluetooth::le_audio::codec_spec_caps::
870 kLeAudioCodecChannelCountTwoChannel,
871 80, 120);
872 pac_records.push_back(stack_record);
873
874 auto aidl_pacs = GetAidlLeAudioDeviceCapabilitiesFromStackFormat(pac_records);
875 ASSERT_TRUE(aidl_pacs.has_value());
876
877 bool matched_supportedSamplingFrequencies = false;
878 bool matched_supportedFrameDurations = false;
879 bool matched_supportedAudioChannelCounts = false;
880 bool matched_supportedOctetsPerCodecFrame = false;
881 bool matched_supportedMaxCodecFramesPerSDU = false;
882
883 for (auto const& aidl_pac : *aidl_pacs) {
884 ASSERT_TRUE(aidl_pac.has_value());
885 ASSERT_EQ(aidl::android::hardware::bluetooth::audio::CodecId::core,
886 aidl_pac->codecId.getTag());
887 ASSERT_EQ(
888 kAidlCodecLc3,
889 aidl_pac->codecId
890 .get<aidl::android::hardware::bluetooth::audio::CodecId::core>());
891 for (auto const& cap : aidl_pac->codecSpecificCapabilities) {
892 if (cap.getTag() ==
893 ::aidl::android::hardware::bluetooth::audio::
894 CodecSpecificCapabilitiesLtv::supportedSamplingFrequencies) {
895 ASSERT_EQ(::aidl::android::hardware::bluetooth::audio::
896 CodecSpecificCapabilitiesLtv::
897 SupportedSamplingFrequencies::HZ16000,
898 cap.get<::aidl::android::hardware::bluetooth::audio::
899 CodecSpecificCapabilitiesLtv::
900 supportedSamplingFrequencies>()
901 .bitmask);
902 matched_supportedSamplingFrequencies = true;
903
904 } else if (cap.getTag() ==
905 ::aidl::android::hardware::bluetooth::audio::
906 CodecSpecificCapabilitiesLtv::supportedFrameDurations) {
907 ASSERT_EQ(
908 ::aidl::android::hardware::bluetooth::audio::
909 CodecSpecificCapabilitiesLtv::SupportedFrameDurations::
910 US7500PREFERRED,
911 cap.get<::aidl::android::hardware::bluetooth::audio::
912 CodecSpecificCapabilitiesLtv::supportedFrameDurations>()
913 .bitmask);
914 matched_supportedFrameDurations = true;
915
916 } else if (cap.getTag() == ::aidl::android::hardware::bluetooth::audio::
917 CodecSpecificCapabilitiesLtv::
918 supportedAudioChannelCounts) {
919 ASSERT_EQ(
920 ::aidl::android::hardware::bluetooth::audio::
921 CodecSpecificCapabilitiesLtv::SupportedAudioChannelCounts::TWO,
922 cap.get<::aidl::android::hardware::bluetooth::audio::
923 CodecSpecificCapabilitiesLtv::
924 supportedAudioChannelCounts>()
925 .bitmask);
926 matched_supportedAudioChannelCounts = true;
927
928 } else if (cap.getTag() == ::aidl::android::hardware::bluetooth::audio::
929 CodecSpecificCapabilitiesLtv::
930 supportedOctetsPerCodecFrame) {
931 ASSERT_EQ(80, cap.get<::aidl::android::hardware::bluetooth::audio::
932 CodecSpecificCapabilitiesLtv::
933 supportedOctetsPerCodecFrame>()
934 .min);
935 ASSERT_EQ(120, cap.get<::aidl::android::hardware::bluetooth::audio::
936 CodecSpecificCapabilitiesLtv::
937 supportedOctetsPerCodecFrame>()
938 .max);
939 matched_supportedOctetsPerCodecFrame = true;
940
941 } else if (cap.getTag() == ::aidl::android::hardware::bluetooth::audio::
942 CodecSpecificCapabilitiesLtv::
943 supportedMaxCodecFramesPerSDU) {
944 ASSERT_EQ(1, cap.get<::aidl::android::hardware::bluetooth::audio::
945 CodecSpecificCapabilitiesLtv::
946 supportedMaxCodecFramesPerSDU>()
947 .value);
948 matched_supportedMaxCodecFramesPerSDU = true;
949
950 } else {
951 GTEST_FAIL();
952 }
953 }
954
955 ASSERT_TRUE(aidl_pac->vendorCodecSpecificCapabilities.has_value());
956 ASSERT_EQ(stack_record.codec_spec_caps_raw.size(),
957 aidl_pac->vendorCodecSpecificCapabilities->size());
958 ASSERT_EQ(0, memcmp(stack_record.codec_spec_caps_raw.data(),
959 aidl_pac->vendorCodecSpecificCapabilities->data(),
960 aidl_pac->vendorCodecSpecificCapabilities->size()));
961
962 ASSERT_TRUE(aidl_pac->metadata.has_value());
963 bool matched_preferredAudioContexts = false;
964 bool matched_streamingAudioContexts = false;
965 bool matched_vendorSpecific = false;
966 for (auto const& meta : *aidl_pac->metadata) {
967 ::bluetooth::le_audio::types::LeAudioLtvMap stack_meta;
968 ASSERT_TRUE(stack_meta.Parse(stack_record.metadata.data(),
969 stack_record.metadata.size()));
970 verifyMetadata(meta, stack_meta.GetAsLeAudioMetadata(),
971 matched_preferredAudioContexts,
972 matched_streamingAudioContexts, matched_vendorSpecific);
973 }
974
975 ASSERT_TRUE(matched_preferredAudioContexts);
976 ASSERT_TRUE(matched_streamingAudioContexts);
977 ASSERT_TRUE(matched_vendorSpecific);
978 }
979
980 ASSERT_TRUE(matched_supportedSamplingFrequencies);
981 ASSERT_TRUE(matched_supportedFrameDurations);
982 ASSERT_TRUE(matched_supportedAudioChannelCounts);
983 ASSERT_TRUE(matched_supportedOctetsPerCodecFrame);
984 ASSERT_TRUE(matched_supportedMaxCodecFramesPerSDU);
985 }
986
TEST(BluetoothAudioClientInterfaceAidlTest,testGetStackLeAudioLtvMapFromAidlFormat)987 TEST(BluetoothAudioClientInterfaceAidlTest,
988 testGetStackLeAudioLtvMapFromAidlFormat) {
989 auto [aidl_codec_spec, matching_stack_codec_spec] =
990 test_utils::PrepareReferenceCodecSpecificConfigurationLc3(true, true,
991 true);
992
993 auto stack_codec_config_ltv =
994 GetStackLeAudioLtvMapFromAidlFormat(aidl_codec_spec);
995 ASSERT_EQ(matching_stack_codec_spec, stack_codec_config_ltv);
996 }
997
TEST(BluetoothAudioClientInterfaceAidlTest,testGetStackDataPathFromAidlFormat)998 TEST(BluetoothAudioClientInterfaceAidlTest,
999 testGetStackDataPathFromAidlFormat) {
1000 auto [aidl_config, reference_stack_config] =
1001 test_utils::PrepareReferenceLeAudioDataPathConfigurationVendor();
1002 auto stack_config =
1003 bluetooth::audio::aidl::GetStackDataPathFromAidlFormat(aidl_config);
1004 ASSERT_EQ(stack_config, reference_stack_config);
1005 }
1006
TEST(BluetoothAudioClientInterfaceAidlTest,testGetStackMetadataFromAidlFormat)1007 TEST(BluetoothAudioClientInterfaceAidlTest,
1008 testGetStackMetadataFromAidlFormat) {
1009 auto [aidl_metadata, reference_stack_metadata] =
1010 test_utils::PrepareReferenceMetadata();
1011 auto stack_metadata =
1012 bluetooth::audio::aidl::GetStackMetadataFromAidlFormat(aidl_metadata);
1013 ASSERT_EQ(stack_metadata, reference_stack_metadata);
1014 }
1015
TEST(BluetoothAudioClientInterfaceAidlTest,testGetStackUnicastConfigurationFromAidlFormat)1016 TEST(BluetoothAudioClientInterfaceAidlTest,
1017 testGetStackUnicastConfigurationFromAidlFormat) {
1018 auto [aidl_config, expected_stack_config] =
1019 test_utils::PrepareReferenceAseConfigurationSetting(
1020 ::bluetooth::le_audio::types::LeAudioContextType::GAME, true);
1021
1022 auto stack_config = GetStackUnicastConfigurationFromAidlFormat(
1023 ::bluetooth::le_audio::types::LeAudioContextType::GAME, aidl_config);
1024 ASSERT_TRUE(stack_config.has_value());
1025 ASSERT_EQ(stack_config->confs.sink.size(), 2ul);
1026 ASSERT_EQ(*stack_config, expected_stack_config);
1027 }
1028
TEST(BluetoothAudioClientInterfaceAidlTest,testGetStackBisConfigFromAidlFormat)1029 TEST(BluetoothAudioClientInterfaceAidlTest,
1030 testGetStackBisConfigFromAidlFormat) {
1031 auto [aidl_config, expected_stack_config] =
1032 test_utils::PrepareReferenceBisConfiguration();
1033 ::bluetooth::le_audio::types::LeAudioCodecId out_stack_codec_id;
1034
1035 auto stack_config =
1036 GetStackBisConfigFromAidlFormat(aidl_config, out_stack_codec_id);
1037 ASSERT_EQ(stack_config, expected_stack_config);
1038 ASSERT_EQ(out_stack_codec_id, kStackCodecLc3);
1039 }
1040
TEST(BluetoothAudioClientInterfaceAidlTest,testGetStackSubgroupsFromAidlFormat)1041 TEST(BluetoothAudioClientInterfaceAidlTest,
1042 testGetStackSubgroupsFromAidlFormat) {
1043 auto [aidl_subgroups, expected_stack_subgroups] =
1044 test_utils::PrepareReferenceBroadcastSubgroups();
1045 auto stack_subgroups = GetStackSubgroupsFromAidlFormat(aidl_subgroups);
1046
1047 ASSERT_FALSE(aidl_subgroups.empty());
1048 ASSERT_FALSE(stack_subgroups.empty());
1049 ASSERT_EQ(stack_subgroups, expected_stack_subgroups);
1050 }
1051
TEST(BluetoothAudioClientInterfaceAidlTest,testGetStackBroadcastConfigurationFromAidlFormat)1052 TEST(BluetoothAudioClientInterfaceAidlTest,
1053 testGetStackBroadcastConfigurationFromAidlFormat) {
1054 auto [aidl_config, expected_stack_config] =
1055 test_utils::PrepareReferenceBroadcastConfigurationLc3();
1056 auto stack_config = GetStackBroadcastConfigurationFromAidlFormat(aidl_config);
1057 ASSERT_TRUE(stack_config.has_value());
1058 ASSERT_EQ(stack_config.value(), expected_stack_config);
1059 }
1060
TEST(BluetoothAudioClientInterfaceAidlTest,testGetAidlLeAudioBroadcastConfigurationRequirementFromStackFormat)1061 TEST(BluetoothAudioClientInterfaceAidlTest,
1062 testGetAidlLeAudioBroadcastConfigurationRequirementFromStackFormat) {
1063 auto [reference_aidl_requirements, stack_requirements] =
1064 test_utils::PrepareReferenceBroadcastRequirements();
1065 auto aidl_requirements =
1066 GetAidlLeAudioBroadcastConfigurationRequirementFromStackFormat(
1067 stack_requirements);
1068 ASSERT_EQ(aidl_requirements, reference_aidl_requirements);
1069 }
1070
TEST(BluetoothAudioClientInterfaceAidlTest,testGetAidlLeAudioUnicastConfigurationRequirementsFromStackFormat)1071 TEST(BluetoothAudioClientInterfaceAidlTest,
1072 testGetAidlLeAudioUnicastConfigurationRequirementsFromStackFormat) {
1073 auto stack_context = le_audio::types::LeAudioContextType::CONVERSATIONAL;
1074 auto aidl_context = ::aidl::android::hardware::bluetooth::audio::AudioContext{
1075 .bitmask = ::aidl::android::hardware::bluetooth::audio::AudioContext::
1076 CONVERSATIONAL,
1077 };
1078
1079 ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
1080 LeAudioConfigurationRequirement reference_aidl_requirements;
1081 reference_aidl_requirements.audioContext = aidl_context;
1082
1083 auto [aidl_req_l, stack_req_l] =
1084 test_utils::PrepareReferenceDirectionRequirements(
1085 ::aidl::android::hardware::bluetooth::audio::
1086 CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT,
1087 le_audio::codec_spec_conf::kLeAudioLocationFrontLeft);
1088
1089 auto [aidl_req_r, stack_req_r] =
1090 test_utils::PrepareReferenceDirectionRequirements(
1091 ::aidl::android::hardware::bluetooth::audio::
1092 CodecSpecificConfigurationLtv::AudioChannelAllocation::
1093 FRONT_RIGHT,
1094 le_audio::codec_spec_conf::kLeAudioLocationFrontRight);
1095
1096 // For this case lets make the sink and source requirements symmetric
1097 std::vector<::bluetooth::le_audio::CodecManager::
1098 UnicastConfigurationRequirements::DeviceDirectionRequirements>
1099 stack_sink_reqs = {stack_req_l, stack_req_r};
1100 auto stack_source_reqs = stack_sink_reqs;
1101 reference_aidl_requirements.sinkAseRequirement = std::vector<std::optional<
1102 ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
1103 LeAudioConfigurationRequirement::AseDirectionRequirement>>{
1104 aidl_req_l, aidl_req_r};
1105 reference_aidl_requirements.sourceAseRequirement =
1106 reference_aidl_requirements.sinkAseRequirement;
1107
1108 auto aidl_requirements =
1109 GetAidlLeAudioUnicastConfigurationRequirementsFromStackFormat(
1110 stack_context, stack_sink_reqs, stack_source_reqs);
1111
1112 ASSERT_EQ(aidl_requirements.audioContext,
1113 reference_aidl_requirements.audioContext);
1114 ASSERT_EQ(aidl_requirements.flags, reference_aidl_requirements.flags);
1115
1116 ASSERT_EQ(aidl_requirements.sinkAseRequirement.has_value(),
1117 reference_aidl_requirements.sinkAseRequirement.has_value());
1118 if (reference_aidl_requirements.sinkAseRequirement.has_value()) {
1119 for (auto const& reference_req :
1120 reference_aidl_requirements.sinkAseRequirement.value()) {
1121 auto iter = std::find_if(
1122 aidl_requirements.sinkAseRequirement->begin(),
1123 aidl_requirements.sinkAseRequirement->end(),
1124 [reference_req](auto const& aidl_req) {
1125 if (reference_req.has_value() != aidl_req.has_value()) {
1126 return false;
1127 }
1128 if (reference_req->aseConfiguration.targetLatency !=
1129 aidl_req->aseConfiguration.targetLatency) {
1130 return false;
1131 }
1132 if (reference_req->aseConfiguration.targetPhy !=
1133 aidl_req->aseConfiguration.targetPhy) {
1134 return false;
1135 }
1136 if (reference_req->aseConfiguration.codecId !=
1137 aidl_req->aseConfiguration.codecId) {
1138 return false;
1139 }
1140 if (reference_req->aseConfiguration.vendorCodecConfiguration !=
1141 aidl_req->aseConfiguration.vendorCodecConfiguration) {
1142 return false;
1143 }
1144 if (reference_req->aseConfiguration.metadata !=
1145 aidl_req->aseConfiguration.metadata) {
1146 return false;
1147 }
1148 for (auto const& ref_el :
1149 reference_req->aseConfiguration.codecConfiguration) {
1150 if (std::find(
1151 aidl_req->aseConfiguration.codecConfiguration.begin(),
1152 aidl_req->aseConfiguration.codecConfiguration.end(),
1153 ref_el) ==
1154 aidl_req->aseConfiguration.codecConfiguration.end()) {
1155 return false;
1156 }
1157 }
1158
1159 return true;
1160 });
1161 ASSERT_NE(iter, aidl_requirements.sinkAseRequirement->end());
1162 }
1163 }
1164
1165 ASSERT_EQ(aidl_requirements.sourceAseRequirement.has_value(),
1166 reference_aidl_requirements.sourceAseRequirement.has_value());
1167 if (reference_aidl_requirements.sourceAseRequirement.has_value()) {
1168 for (auto const& reference_req :
1169 reference_aidl_requirements.sourceAseRequirement.value()) {
1170 auto iter = std::find_if(
1171 aidl_requirements.sourceAseRequirement->begin(),
1172 aidl_requirements.sourceAseRequirement->end(),
1173 [reference_req](auto const& aidl_req) {
1174 if (reference_req.has_value() != aidl_req.has_value()) {
1175 return false;
1176 }
1177 if (reference_req->aseConfiguration.targetLatency !=
1178 aidl_req->aseConfiguration.targetLatency) {
1179 return false;
1180 }
1181 if (reference_req->aseConfiguration.targetPhy !=
1182 aidl_req->aseConfiguration.targetPhy) {
1183 return false;
1184 }
1185 if (reference_req->aseConfiguration.codecId !=
1186 aidl_req->aseConfiguration.codecId) {
1187 return false;
1188 }
1189 if (reference_req->aseConfiguration.vendorCodecConfiguration !=
1190 aidl_req->aseConfiguration.vendorCodecConfiguration) {
1191 return false;
1192 }
1193 if (reference_req->aseConfiguration.metadata !=
1194 aidl_req->aseConfiguration.metadata) {
1195 return false;
1196 }
1197 for (auto const& ref_el :
1198 reference_req->aseConfiguration.codecConfiguration) {
1199 if (std::find(
1200 aidl_req->aseConfiguration.codecConfiguration.begin(),
1201 aidl_req->aseConfiguration.codecConfiguration.end(),
1202 ref_el) ==
1203 aidl_req->aseConfiguration.codecConfiguration.end()) {
1204 return false;
1205 }
1206 }
1207
1208 return true;
1209 });
1210 ASSERT_NE(iter, aidl_requirements.sourceAseRequirement->end());
1211 }
1212 }
1213 }
1214
1215 } // namespace
1216 } // namespace bluetooth
1217