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