1 /*
2  * Copyright 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "BTAudioCodecStatusAIDL"
18 
19 #include "codec_status_aidl.h"
20 
21 #include <bluetooth/log.h>
22 
23 #include <unordered_set>
24 #include <vector>
25 
26 #include "a2dp_aac_constants.h"
27 #include "a2dp_sbc_constants.h"
28 #include "a2dp_vendor_aptx_constants.h"
29 #include "a2dp_vendor_aptx_hd_constants.h"
30 #include "a2dp_vendor_ldac_constants.h"
31 #include "bta/av/bta_av_int.h"
32 #include "client_interface_aidl.h"
33 
34 namespace bluetooth {
35 namespace audio {
36 namespace aidl {
37 namespace a2dp {
38 namespace codec {
39 
40 using ::aidl::android::hardware::bluetooth::audio::AacCapabilities;
41 using ::aidl::android::hardware::bluetooth::audio::AacConfiguration;
42 using ::aidl::android::hardware::bluetooth::audio::AacObjectType;
43 using ::aidl::android::hardware::bluetooth::audio::AptxCapabilities;
44 using ::aidl::android::hardware::bluetooth::audio::AptxConfiguration;
45 using ::aidl::android::hardware::bluetooth::audio::AudioCapabilities;
46 using ::aidl::android::hardware::bluetooth::audio::ChannelMode;
47 using ::aidl::android::hardware::bluetooth::audio::CodecCapabilities;
48 using ::aidl::android::hardware::bluetooth::audio::CodecType;
49 using ::aidl::android::hardware::bluetooth::audio::LdacCapabilities;
50 using ::aidl::android::hardware::bluetooth::audio::LdacChannelMode;
51 using ::aidl::android::hardware::bluetooth::audio::LdacConfiguration;
52 using ::aidl::android::hardware::bluetooth::audio::LdacQualityIndex;
53 using ::aidl::android::hardware::bluetooth::audio::OpusCapabilities;
54 using ::aidl::android::hardware::bluetooth::audio::OpusConfiguration;
55 using ::aidl::android::hardware::bluetooth::audio::SbcAllocMethod;
56 using ::aidl::android::hardware::bluetooth::audio::SbcCapabilities;
57 using ::aidl::android::hardware::bluetooth::audio::SbcChannelMode;
58 using ::aidl::android::hardware::bluetooth::audio::SbcConfiguration;
59 
60 namespace {
61 
62 // capabilities from BluetoothAudioClientInterface::GetAudioCapabilities()
63 std::vector<AudioCapabilities> audio_hal_capabilities(0);
64 // capabilities that audio HAL supports and frameworks / Bluetooth SoC / runtime
65 // preference would like to use.
66 std::vector<AudioCapabilities> offloading_preference(0);
67 
68 template <typename T>
69 struct identity {
70   typedef T type;
71 };
72 
73 template <class T>
ContainedInVector(const std::vector<T> & vector,const typename identity<T>::type & target)74 bool ContainedInVector(const std::vector<T>& vector, const typename identity<T>::type& target) {
75   return std::find(vector.begin(), vector.end(), target) != vector.end();
76 }
77 
sbc_offloading_capability_match(const SbcCapabilities & sbc_capability,const SbcConfiguration & sbc_config)78 bool sbc_offloading_capability_match(const SbcCapabilities& sbc_capability,
79                                      const SbcConfiguration& sbc_config) {
80   if (!ContainedInVector(sbc_capability.channelMode, sbc_config.channelMode) ||
81       !ContainedInVector(sbc_capability.allocMethod, sbc_config.allocMethod) ||
82       !ContainedInVector(sbc_capability.blockLength, sbc_config.blockLength) ||
83       !ContainedInVector(sbc_capability.numSubbands, sbc_config.numSubbands) ||
84       !ContainedInVector(sbc_capability.bitsPerSample, sbc_config.bitsPerSample) ||
85       !ContainedInVector(sbc_capability.sampleRateHz, sbc_config.sampleRateHz) ||
86       (sbc_config.minBitpool < sbc_capability.minBitpool ||
87        sbc_config.maxBitpool < sbc_config.minBitpool ||
88        sbc_capability.maxBitpool < sbc_config.maxBitpool)) {
89     log::warn("software codec={} capability={}", sbc_config.toString(), sbc_capability.toString());
90     return false;
91   }
92   log::info("offload codec={} capability={}", sbc_config.toString(), sbc_capability.toString());
93   return true;
94 }
95 
aac_offloading_capability_match(const AacCapabilities & aac_capability,const AacConfiguration & aac_config)96 bool aac_offloading_capability_match(const AacCapabilities& aac_capability,
97                                      const AacConfiguration& aac_config) {
98   if (!ContainedInVector(aac_capability.channelMode, aac_config.channelMode) ||
99       !ContainedInVector(aac_capability.objectType, aac_config.objectType) ||
100       !ContainedInVector(aac_capability.bitsPerSample, aac_config.bitsPerSample) ||
101       !ContainedInVector(aac_capability.sampleRateHz, aac_config.sampleRateHz) ||
102       (!aac_capability.variableBitRateSupported && aac_config.variableBitRateEnabled)) {
103     log::warn("software codec={} capability={}", aac_config.toString(), aac_capability.toString());
104     return false;
105   }
106   log::info("offloading codec={} capability={}", aac_config.toString(), aac_capability.toString());
107   return true;
108 }
109 
aptx_offloading_capability_match(const AptxCapabilities & aptx_capability,const AptxConfiguration & aptx_config)110 bool aptx_offloading_capability_match(const AptxCapabilities& aptx_capability,
111                                       const AptxConfiguration& aptx_config) {
112   if (!ContainedInVector(aptx_capability.channelMode, aptx_config.channelMode) ||
113       !ContainedInVector(aptx_capability.bitsPerSample, aptx_config.bitsPerSample) ||
114       !ContainedInVector(aptx_capability.sampleRateHz, aptx_config.sampleRateHz)) {
115     log::warn("software codec={} capability={}", aptx_config.toString(),
116               aptx_capability.toString());
117     return false;
118   }
119   log::info("offloading codec={} capability={}", aptx_config.toString(),
120             aptx_capability.toString());
121   return true;
122 }
123 
ldac_offloading_capability_match(const LdacCapabilities & ldac_capability,const LdacConfiguration & ldac_config)124 bool ldac_offloading_capability_match(const LdacCapabilities& ldac_capability,
125                                       const LdacConfiguration& ldac_config) {
126   if (!ContainedInVector(ldac_capability.channelMode, ldac_config.channelMode) ||
127       !ContainedInVector(ldac_capability.bitsPerSample, ldac_config.bitsPerSample) ||
128       !ContainedInVector(ldac_capability.sampleRateHz, ldac_config.sampleRateHz)) {
129     log::warn("software codec={} capability={}", ldac_config.toString(),
130               ldac_capability.toString());
131     return false;
132   }
133   log::info("offloading codec={} capability={}", ldac_config.toString(),
134             ldac_capability.toString());
135   return true;
136 }
137 
opus_offloading_capability_match(const std::optional<OpusCapabilities> & opus_capability,const std::optional<OpusConfiguration> & opus_config)138 bool opus_offloading_capability_match(const std::optional<OpusCapabilities>& opus_capability,
139                                       const std::optional<OpusConfiguration>& opus_config) {
140   if (!ContainedInVector(opus_capability->channelMode, opus_config->channelMode) ||
141       !ContainedInVector(opus_capability->frameDurationUs, opus_config->frameDurationUs) ||
142       !ContainedInVector(opus_capability->samplingFrequencyHz, opus_config->samplingFrequencyHz)) {
143     log::warn("software codec={} capability={}", opus_config->toString(),
144               opus_capability->toString());
145     return false;
146   }
147   log::info("offloading codec={} capability={}", opus_config->toString(),
148             opus_capability->toString());
149   return true;
150 }
151 
152 }  // namespace
153 
154 const CodecConfiguration kInvalidCodecConfiguration = {};
155 
A2dpCodecToHalSampleRate(const btav_a2dp_codec_config_t & a2dp_codec_config)156 int32_t A2dpCodecToHalSampleRate(const btav_a2dp_codec_config_t& a2dp_codec_config) {
157   switch (a2dp_codec_config.sample_rate) {
158     case BTAV_A2DP_CODEC_SAMPLE_RATE_44100:
159       return 44100;
160     case BTAV_A2DP_CODEC_SAMPLE_RATE_48000:
161       return 48000;
162     case BTAV_A2DP_CODEC_SAMPLE_RATE_88200:
163       return 88200;
164     case BTAV_A2DP_CODEC_SAMPLE_RATE_96000:
165       return 96000;
166     case BTAV_A2DP_CODEC_SAMPLE_RATE_176400:
167       return 176400;
168     case BTAV_A2DP_CODEC_SAMPLE_RATE_192000:
169       return 192000;
170     case BTAV_A2DP_CODEC_SAMPLE_RATE_16000:
171       return 16000;
172     case BTAV_A2DP_CODEC_SAMPLE_RATE_24000:
173       return 24000;
174     default:
175       return 0;
176   }
177 }
178 
A2dpCodecToHalBitsPerSample(const btav_a2dp_codec_config_t & a2dp_codec_config)179 int8_t A2dpCodecToHalBitsPerSample(const btav_a2dp_codec_config_t& a2dp_codec_config) {
180   switch (a2dp_codec_config.bits_per_sample) {
181     case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16:
182       return 16;
183     case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24:
184       return 24;
185     case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32:
186       return 32;
187     default:
188       return 0;
189   }
190 }
191 
A2dpCodecToHalChannelMode(const btav_a2dp_codec_config_t & a2dp_codec_config)192 ChannelMode A2dpCodecToHalChannelMode(const btav_a2dp_codec_config_t& a2dp_codec_config) {
193   switch (a2dp_codec_config.channel_mode) {
194     case BTAV_A2DP_CODEC_CHANNEL_MODE_MONO:
195       return ChannelMode::MONO;
196     case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO:
197       return ChannelMode::STEREO;
198     default:
199       return ChannelMode::UNKNOWN;
200   }
201 }
202 
A2dpSbcToHalConfig(CodecConfiguration * codec_config,A2dpCodecConfig * a2dp_config)203 bool A2dpSbcToHalConfig(CodecConfiguration* codec_config, A2dpCodecConfig* a2dp_config) {
204   btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
205   if (current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_SBC &&
206       current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SINK_SBC) {
207     return false;
208   }
209   tBT_A2DP_OFFLOAD a2dp_offload;
210   a2dp_config->getCodecSpecificConfig(&a2dp_offload);
211   codec_config->codecType = CodecType::SBC;
212   SbcConfiguration sbc_config = {};
213   sbc_config.sampleRateHz = A2dpCodecToHalSampleRate(current_codec);
214   if (sbc_config.sampleRateHz <= 0) {
215     log::error("Unknown SBC sample_rate={}", current_codec.sample_rate);
216     return false;
217   }
218   uint8_t channel_mode = a2dp_offload.codec_info[3] & A2DP_SBC_IE_CH_MD_MSK;
219   switch (channel_mode) {
220     case A2DP_SBC_IE_CH_MD_JOINT:
221       sbc_config.channelMode = SbcChannelMode::JOINT_STEREO;
222       break;
223     case A2DP_SBC_IE_CH_MD_STEREO:
224       sbc_config.channelMode = SbcChannelMode::STEREO;
225       break;
226     case A2DP_SBC_IE_CH_MD_DUAL:
227       sbc_config.channelMode = SbcChannelMode::DUAL;
228       break;
229     case A2DP_SBC_IE_CH_MD_MONO:
230       sbc_config.channelMode = SbcChannelMode::MONO;
231       break;
232     default:
233       log::error("Unknown SBC channel_mode={}", channel_mode);
234       sbc_config.channelMode = SbcChannelMode::UNKNOWN;
235       return false;
236   }
237   uint8_t block_length = a2dp_offload.codec_info[0] & A2DP_SBC_IE_BLOCKS_MSK;
238   switch (block_length) {
239     case A2DP_SBC_IE_BLOCKS_4:
240       sbc_config.blockLength = 4;
241       break;
242     case A2DP_SBC_IE_BLOCKS_8:
243       sbc_config.blockLength = 8;
244       break;
245     case A2DP_SBC_IE_BLOCKS_12:
246       sbc_config.blockLength = 12;
247       break;
248     case A2DP_SBC_IE_BLOCKS_16:
249       sbc_config.blockLength = 16;
250       break;
251     default:
252       log::error("Unknown SBC block_length={}", block_length);
253       return false;
254   }
255   uint8_t sub_bands = a2dp_offload.codec_info[0] & A2DP_SBC_IE_SUBBAND_MSK;
256   switch (sub_bands) {
257     case A2DP_SBC_IE_SUBBAND_4:
258       sbc_config.numSubbands = 4;
259       break;
260     case A2DP_SBC_IE_SUBBAND_8:
261       sbc_config.numSubbands = 8;
262       break;
263     default:
264       log::error("Unknown SBC Subbands={}", sub_bands);
265       return false;
266   }
267   uint8_t alloc_method = a2dp_offload.codec_info[0] & A2DP_SBC_IE_ALLOC_MD_MSK;
268   switch (alloc_method) {
269     case A2DP_SBC_IE_ALLOC_MD_S:
270       sbc_config.allocMethod = SbcAllocMethod::ALLOC_MD_S;
271       break;
272     case A2DP_SBC_IE_ALLOC_MD_L:
273       sbc_config.allocMethod = SbcAllocMethod::ALLOC_MD_L;
274       break;
275     default:
276       log::error("Unknown SBC alloc_method={}", alloc_method);
277       return false;
278   }
279   sbc_config.minBitpool = a2dp_offload.codec_info[1];
280   sbc_config.maxBitpool = a2dp_offload.codec_info[2];
281   sbc_config.bitsPerSample = A2dpCodecToHalBitsPerSample(current_codec);
282   if (sbc_config.bitsPerSample <= 0) {
283     log::error("Unknown SBC bits_per_sample={}", current_codec.bits_per_sample);
284     return false;
285   }
286   codec_config->config.set<CodecConfiguration::CodecSpecific::sbcConfig>(sbc_config);
287   return true;
288 }
289 
A2dpAacToHalConfig(CodecConfiguration * codec_config,A2dpCodecConfig * a2dp_config)290 bool A2dpAacToHalConfig(CodecConfiguration* codec_config, A2dpCodecConfig* a2dp_config) {
291   btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
292   if (current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_AAC &&
293       current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SINK_AAC) {
294     return false;
295   }
296   tBT_A2DP_OFFLOAD a2dp_offload;
297   a2dp_config->getCodecSpecificConfig(&a2dp_offload);
298   codec_config->codecType = CodecType::AAC;
299   AacConfiguration aac_config = {};
300   uint8_t object_type = a2dp_offload.codec_info[0];
301   switch (object_type) {
302     case A2DP_AAC_OBJECT_TYPE_MPEG2_LC:
303       aac_config.objectType = AacObjectType::MPEG2_LC;
304       break;
305     case A2DP_AAC_OBJECT_TYPE_MPEG4_LC:
306       aac_config.objectType = AacObjectType::MPEG4_LC;
307       break;
308     case A2DP_AAC_OBJECT_TYPE_MPEG4_LTP:
309       aac_config.objectType = AacObjectType::MPEG4_LTP;
310       break;
311     case A2DP_AAC_OBJECT_TYPE_MPEG4_SCALABLE:
312       aac_config.objectType = AacObjectType::MPEG4_SCALABLE;
313       break;
314     default:
315       log::error("Unknown AAC object_type={}", object_type);
316       return false;
317   }
318   aac_config.sampleRateHz = A2dpCodecToHalSampleRate(current_codec);
319   if (aac_config.sampleRateHz <= 0) {
320     log::error("Unknown AAC sample_rate={}", current_codec.sample_rate);
321     return false;
322   }
323   aac_config.channelMode = A2dpCodecToHalChannelMode(current_codec);
324   if (aac_config.channelMode == ChannelMode::UNKNOWN) {
325     log::error("Unknown AAC channel_mode={}", current_codec.channel_mode);
326     return false;
327   }
328   uint8_t vbr_enabled = a2dp_offload.codec_info[1] & A2DP_AAC_VARIABLE_BIT_RATE_MASK;
329   switch (vbr_enabled) {
330     case A2DP_AAC_VARIABLE_BIT_RATE_ENABLED:
331       aac_config.variableBitRateEnabled = true;
332       break;
333     case A2DP_AAC_VARIABLE_BIT_RATE_DISABLED:
334       aac_config.variableBitRateEnabled = false;
335       break;
336     default:
337       log::error("Unknown AAC VBR={}", vbr_enabled);
338       return false;
339   }
340   aac_config.bitsPerSample = A2dpCodecToHalBitsPerSample(current_codec);
341   if (aac_config.bitsPerSample <= 0) {
342     log::error("Unknown AAC bits_per_sample={}", current_codec.bits_per_sample);
343     return false;
344   }
345   codec_config->config.set<CodecConfiguration::CodecSpecific::aacConfig>(aac_config);
346   return true;
347 }
348 
A2dpAptxToHalConfig(CodecConfiguration * codec_config,A2dpCodecConfig * a2dp_config)349 bool A2dpAptxToHalConfig(CodecConfiguration* codec_config, A2dpCodecConfig* a2dp_config) {
350   btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
351   if (current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_APTX &&
352       current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD) {
353     return false;
354   }
355   tBT_A2DP_OFFLOAD a2dp_offload;
356   a2dp_config->getCodecSpecificConfig(&a2dp_offload);
357   if (current_codec.codec_type == BTAV_A2DP_CODEC_INDEX_SOURCE_APTX) {
358     codec_config->codecType = CodecType::APTX;
359   } else {
360     codec_config->codecType = CodecType::APTX_HD;
361   }
362   AptxConfiguration aptx_config = {};
363   aptx_config.sampleRateHz = A2dpCodecToHalSampleRate(current_codec);
364   if (aptx_config.sampleRateHz <= 0) {
365     log::error("Unknown aptX sample_rate={}", current_codec.sample_rate);
366     return false;
367   }
368   aptx_config.channelMode = A2dpCodecToHalChannelMode(current_codec);
369   if (aptx_config.channelMode == ChannelMode::UNKNOWN) {
370     log::error("Unknown aptX channel_mode={}", current_codec.channel_mode);
371     return false;
372   }
373   aptx_config.bitsPerSample = A2dpCodecToHalBitsPerSample(current_codec);
374   if (aptx_config.bitsPerSample <= 0) {
375     log::error("Unknown aptX bits_per_sample={}", current_codec.bits_per_sample);
376     return false;
377   }
378   codec_config->config.set<CodecConfiguration::CodecSpecific::aptxConfig>(aptx_config);
379   return true;
380 }
381 
A2dpLdacToHalConfig(CodecConfiguration * codec_config,A2dpCodecConfig * a2dp_config)382 bool A2dpLdacToHalConfig(CodecConfiguration* codec_config, A2dpCodecConfig* a2dp_config) {
383   btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
384   if (current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC) {
385     return false;
386   }
387   tBT_A2DP_OFFLOAD a2dp_offload;
388   a2dp_config->getCodecSpecificConfig(&a2dp_offload);
389   codec_config->codecType = CodecType::LDAC;
390   LdacConfiguration ldac_config = {};
391   ldac_config.sampleRateHz = A2dpCodecToHalSampleRate(current_codec);
392   if (ldac_config.sampleRateHz <= 0) {
393     log::error("Unknown LDAC sample_rate={}", current_codec.sample_rate);
394     return false;
395   }
396   switch (a2dp_offload.codec_info[7]) {
397     case A2DP_LDAC_CHANNEL_MODE_STEREO:
398       ldac_config.channelMode = LdacChannelMode::STEREO;
399       break;
400     case A2DP_LDAC_CHANNEL_MODE_DUAL:
401       ldac_config.channelMode = LdacChannelMode::DUAL;
402       break;
403     case A2DP_LDAC_CHANNEL_MODE_MONO:
404       ldac_config.channelMode = LdacChannelMode::MONO;
405       break;
406     default:
407       log::error("Unknown LDAC channel_mode={}", a2dp_offload.codec_info[7]);
408       ldac_config.channelMode = LdacChannelMode::UNKNOWN;
409       return false;
410   }
411   switch (a2dp_offload.codec_info[6]) {
412     case A2DP_LDAC_QUALITY_HIGH:
413       ldac_config.qualityIndex = LdacQualityIndex::HIGH;
414       break;
415     case A2DP_LDAC_QUALITY_MID:
416       ldac_config.qualityIndex = LdacQualityIndex::MID;
417       break;
418     case A2DP_LDAC_QUALITY_LOW:
419       ldac_config.qualityIndex = LdacQualityIndex::LOW;
420       break;
421     case A2DP_LDAC_QUALITY_ABR_OFFLOAD:
422       ldac_config.qualityIndex = LdacQualityIndex::ABR;
423       break;
424     default:
425       log::error("Unknown LDAC QualityIndex={}", a2dp_offload.codec_info[6]);
426       return false;
427   }
428   ldac_config.bitsPerSample = A2dpCodecToHalBitsPerSample(current_codec);
429   if (ldac_config.bitsPerSample <= 0) {
430     log::error("Unknown LDAC bits_per_sample={}", current_codec.bits_per_sample);
431     return false;
432   }
433   codec_config->config.set<CodecConfiguration::CodecSpecific::ldacConfig>(ldac_config);
434   return true;
435 }
436 
A2dpOpusToHalConfig(CodecConfiguration * codec_config,A2dpCodecConfig * a2dp_config)437 bool A2dpOpusToHalConfig(CodecConfiguration* codec_config, A2dpCodecConfig* a2dp_config) {
438   btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
439   if (current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_OPUS) {
440     codec_config = {};
441     return false;
442   }
443   tBT_A2DP_OFFLOAD a2dp_offload;
444   a2dp_config->getCodecSpecificConfig(&a2dp_offload);
445   codec_config->codecType = CodecType::OPUS;
446   OpusConfiguration opus_config = {};
447 
448   opus_config.pcmBitDepth = A2dpCodecToHalBitsPerSample(current_codec);
449   if (opus_config.pcmBitDepth <= 0) {
450     log::error("Unknown Opus bits_per_sample={}", current_codec.bits_per_sample);
451     return false;
452   }
453   opus_config.samplingFrequencyHz = A2dpCodecToHalSampleRate(current_codec);
454   if (opus_config.samplingFrequencyHz <= 0) {
455     log::error("Unknown Opus sample_rate={}", current_codec.sample_rate);
456     return false;
457   }
458   opus_config.channelMode = A2dpCodecToHalChannelMode(current_codec);
459   if (opus_config.channelMode == ChannelMode::UNKNOWN) {
460     log::error("Unknown Opus channel_mode={}", current_codec.channel_mode);
461     return false;
462   }
463 
464   opus_config.frameDurationUs = 20000;
465 
466   if (opus_config.channelMode == ChannelMode::STEREO) {
467     opus_config.octetsPerFrame = 640;
468   } else {
469     opus_config.octetsPerFrame = 320;
470   }
471 
472   codec_config->config.set<CodecConfiguration::CodecSpecific::opusConfig>(opus_config);
473   return true;
474 }
475 
UpdateOffloadingCapabilities(const std::vector<btav_a2dp_codec_config_t> & framework_preference)476 bool UpdateOffloadingCapabilities(
477         const std::vector<btav_a2dp_codec_config_t>& framework_preference) {
478   audio_hal_capabilities = BluetoothAudioClientInterface::GetAudioCapabilities(
479           SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
480   std::unordered_set<CodecType> codec_type_set;
481   for (auto preference : framework_preference) {
482     switch (preference.codec_type) {
483       case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
484         codec_type_set.insert(CodecType::SBC);
485         break;
486       case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
487         codec_type_set.insert(CodecType::AAC);
488         break;
489       case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX:
490         codec_type_set.insert(CodecType::APTX);
491         break;
492       case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD:
493         codec_type_set.insert(CodecType::APTX_HD);
494         break;
495       case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC:
496         codec_type_set.insert(CodecType::LDAC);
497         break;
498       case BTAV_A2DP_CODEC_INDEX_SOURCE_LC3:
499         log::warn("Ignore source codec_type={}, not implemented", preference.codec_type);
500         break;
501       case BTAV_A2DP_CODEC_INDEX_SOURCE_OPUS:
502         codec_type_set.insert(CodecType::OPUS);
503         break;
504       case BTAV_A2DP_CODEC_INDEX_SINK_SBC:
505         [[fallthrough]];
506       case BTAV_A2DP_CODEC_INDEX_SINK_AAC:
507         [[fallthrough]];
508       case BTAV_A2DP_CODEC_INDEX_SINK_LDAC:
509         [[fallthrough]];
510       case BTAV_A2DP_CODEC_INDEX_SINK_OPUS:
511         log::warn("Ignore sink codec_type={}", preference.codec_type);
512         break;
513       case BTAV_A2DP_CODEC_INDEX_MAX:
514         [[fallthrough]];
515       default:
516         log::error("Unknown codec_type={}", preference.codec_type);
517         return false;
518     }
519   }
520   offloading_preference.clear();
521   for (auto capability : audio_hal_capabilities) {
522     auto codec_type = capability.get<AudioCapabilities::a2dpCapabilities>().codecType;
523     if (codec_type_set.find(codec_type) != codec_type_set.end()) {
524       log::info("enabled offloading capability={}", capability.toString());
525       offloading_preference.push_back(capability);
526     } else {
527       log::info("disabled offloading capability={}", capability.toString());
528     }
529   }
530 
531   // TODO: Bluetooth SoC and runtime property
532   return true;
533 }
534 
535 /***
536  * Check whether this codec is supported by the audio HAL and is allowed to
537  * use by preference of framework / Bluetooth SoC / runtime property.
538  ***/
IsCodecOffloadingEnabled(const CodecConfiguration & codec_config)539 bool IsCodecOffloadingEnabled(const CodecConfiguration& codec_config) {
540   for (auto preference : offloading_preference) {
541     if (codec_config.codecType != preference.get<AudioCapabilities::a2dpCapabilities>().codecType) {
542       continue;
543     }
544     auto codec_capability = preference.get<AudioCapabilities::a2dpCapabilities>();
545     switch (codec_capability.codecType) {
546       case CodecType::SBC: {
547         auto sbc_capability = codec_capability.capabilities
548                                       .get<CodecCapabilities::Capabilities::sbcCapabilities>();
549         auto sbc_config = codec_config.config.get<CodecConfiguration::CodecSpecific::sbcConfig>();
550         return sbc_offloading_capability_match(sbc_capability, sbc_config);
551       }
552       case CodecType::AAC: {
553         auto aac_capability = codec_capability.capabilities
554                                       .get<CodecCapabilities::Capabilities::aacCapabilities>();
555         auto aac_config = codec_config.config.get<CodecConfiguration::CodecSpecific::aacConfig>();
556         return aac_offloading_capability_match(aac_capability, aac_config);
557       }
558       case CodecType::APTX:
559         [[fallthrough]];
560       case CodecType::APTX_HD: {
561         auto aptx_capability = codec_capability.capabilities
562                                        .get<CodecCapabilities::Capabilities::aptxCapabilities>();
563         auto aptx_config = codec_config.config.get<CodecConfiguration::CodecSpecific::aptxConfig>();
564         return aptx_offloading_capability_match(aptx_capability, aptx_config);
565       }
566       case CodecType::LDAC: {
567         auto ldac_capability = codec_capability.capabilities
568                                        .get<CodecCapabilities::Capabilities::ldacCapabilities>();
569         auto ldac_config = codec_config.config.get<CodecConfiguration::CodecSpecific::ldacConfig>();
570         return ldac_offloading_capability_match(ldac_capability, ldac_config);
571       }
572       case CodecType::OPUS: {
573         std::optional<OpusCapabilities> opus_capability =
574                 codec_capability.capabilities
575                         .get<CodecCapabilities::Capabilities::opusCapabilities>();
576         std::optional<OpusConfiguration> opus_config =
577                 codec_config.config.get<CodecConfiguration::CodecSpecific::opusConfig>();
578         return opus_offloading_capability_match(opus_capability, opus_config);
579       }
580       case CodecType::UNKNOWN:
581         [[fallthrough]];
582       default:
583         log::error("Unknown codecType={}", toString(codec_capability.codecType));
584         return false;
585     }
586   }
587   log::info("software codec={}", codec_config.toString());
588   return false;
589 }
590 
591 }  // namespace codec
592 }  // namespace a2dp
593 }  // namespace aidl
594 }  // namespace audio
595 }  // namespace bluetooth
596