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