1 /*
2  * Copyright 2019 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 "BTAudioCodecStatusHIDL"
18 
19 #include "codec_status_hidl.h"
20 
21 #include <bluetooth/log.h>
22 
23 #include <vector>
24 
25 #include "a2dp_aac_constants.h"
26 #include "a2dp_sbc_constants.h"
27 #include "a2dp_vendor_aptx_constants.h"
28 #include "a2dp_vendor_aptx_hd_constants.h"
29 #include "a2dp_vendor_ldac_constants.h"
30 #include "bta/av/bta_av_int.h"
31 #include "client_interface_hidl.h"
32 
33 namespace {
34 
35 using ::android::hardware::bluetooth::audio::V2_0::AacObjectType;
36 using ::android::hardware::bluetooth::audio::V2_0::AacParameters;
37 using ::android::hardware::bluetooth::audio::V2_0::AacVariableBitRate;
38 using ::android::hardware::bluetooth::audio::V2_0::AptxParameters;
39 using ::android::hardware::bluetooth::audio::V2_0::AudioCapabilities;
40 using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
41 using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
42 using ::android::hardware::bluetooth::audio::V2_0::CodecType;
43 using ::android::hardware::bluetooth::audio::V2_0::LdacChannelMode;
44 using ::android::hardware::bluetooth::audio::V2_0::LdacParameters;
45 using ::android::hardware::bluetooth::audio::V2_0::LdacQualityIndex;
46 using ::android::hardware::bluetooth::audio::V2_0::SampleRate;
47 using ::android::hardware::bluetooth::audio::V2_0::SbcAllocMethod;
48 using ::android::hardware::bluetooth::audio::V2_0::SbcBlockLength;
49 using ::android::hardware::bluetooth::audio::V2_0::SbcChannelMode;
50 using ::android::hardware::bluetooth::audio::V2_0::SbcNumSubbands;
51 using ::android::hardware::bluetooth::audio::V2_0::SbcParameters;
52 
53 using namespace bluetooth;
54 
55 // capabilities from BluetoothAudioSinkClientInterface::GetAudioCapabilities()
56 std::vector<AudioCapabilities> audio_hal_capabilities(0);
57 // capabilities that audio HAL supports and frameworks / Bluetooth SoC / runtime
58 // preference would like to use.
59 std::vector<AudioCapabilities> offloading_preference(0);
60 
sbc_offloading_capability_match(const SbcParameters & sbc_capability,const SbcParameters & sbc_config)61 bool sbc_offloading_capability_match(const SbcParameters& sbc_capability,
62                                      const SbcParameters& sbc_config) {
63   if ((static_cast<SampleRate>(sbc_capability.sampleRate &
64                                sbc_config.sampleRate) ==
65        SampleRate::RATE_UNKNOWN) ||
66       (static_cast<SbcChannelMode>(sbc_capability.channelMode &
67                                    sbc_config.channelMode) ==
68        SbcChannelMode::UNKNOWN) ||
69       (static_cast<SbcBlockLength>(sbc_capability.blockLength &
70                                    sbc_config.blockLength) ==
71        static_cast<SbcBlockLength>(0)) ||
72       (static_cast<SbcNumSubbands>(sbc_capability.numSubbands &
73                                    sbc_config.numSubbands) ==
74        static_cast<SbcNumSubbands>(0)) ||
75       (static_cast<SbcAllocMethod>(sbc_capability.allocMethod &
76                                    sbc_config.allocMethod) ==
77        static_cast<SbcAllocMethod>(0)) ||
78       (static_cast<BitsPerSample>(sbc_capability.bitsPerSample &
79                                   sbc_config.bitsPerSample) ==
80        BitsPerSample::BITS_UNKNOWN) ||
81       (sbc_config.minBitpool < sbc_capability.minBitpool ||
82        sbc_config.maxBitpool < sbc_config.minBitpool ||
83        sbc_capability.maxBitpool < sbc_config.maxBitpool)) {
84     log::warn("software codec={} capability={}", toString(sbc_config),
85               toString(sbc_capability));
86     return false;
87   }
88   log::verbose("offloading codec={} capability={}", toString(sbc_config),
89                toString(sbc_capability));
90   return true;
91 }
92 
aac_offloading_capability_match(const AacParameters & aac_capability,const AacParameters & aac_config)93 bool aac_offloading_capability_match(const AacParameters& aac_capability,
94                                      const AacParameters& aac_config) {
95   if ((static_cast<AacObjectType>(aac_capability.objectType &
96                                   aac_config.objectType) ==
97        static_cast<AacObjectType>(0)) ||
98       (static_cast<SampleRate>(aac_capability.sampleRate &
99                                aac_config.sampleRate) ==
100        SampleRate::RATE_UNKNOWN) ||
101       (static_cast<ChannelMode>(aac_capability.channelMode &
102                                 aac_config.channelMode) ==
103        ChannelMode::UNKNOWN) ||
104       (aac_capability.variableBitRateEnabled != AacVariableBitRate::ENABLED &&
105        aac_config.variableBitRateEnabled != AacVariableBitRate::DISABLED) ||
106       (static_cast<BitsPerSample>(aac_capability.bitsPerSample &
107                                   aac_config.bitsPerSample) ==
108        BitsPerSample::BITS_UNKNOWN)) {
109     log::warn("software codec={} capability={}", toString(aac_config),
110               toString(aac_capability));
111     return false;
112   }
113   log::verbose("offloading codec={} capability={}", toString(aac_config),
114                toString(aac_capability));
115   return true;
116 }
117 
aptx_offloading_capability_match(const AptxParameters & aptx_capability,const AptxParameters & aptx_config)118 bool aptx_offloading_capability_match(const AptxParameters& aptx_capability,
119                                       const AptxParameters& aptx_config) {
120   if ((static_cast<SampleRate>(aptx_capability.sampleRate &
121                                aptx_config.sampleRate) ==
122        SampleRate::RATE_UNKNOWN) ||
123       (static_cast<ChannelMode>(aptx_capability.channelMode &
124                                 aptx_config.channelMode) ==
125        ChannelMode::UNKNOWN) ||
126       (static_cast<BitsPerSample>(aptx_capability.bitsPerSample &
127                                   aptx_config.bitsPerSample) ==
128        BitsPerSample::BITS_UNKNOWN)) {
129     log::warn("software codec={} capability={}", toString(aptx_config),
130               toString(aptx_capability));
131     return false;
132   }
133   log::verbose("offloading codec={} capability={}", toString(aptx_config),
134                toString(aptx_capability));
135   return true;
136 }
137 
ldac_offloading_capability_match(const LdacParameters & ldac_capability,const LdacParameters & ldac_config)138 bool ldac_offloading_capability_match(const LdacParameters& ldac_capability,
139                                       const LdacParameters& ldac_config) {
140   if ((static_cast<SampleRate>(ldac_capability.sampleRate &
141                                ldac_config.sampleRate) ==
142        SampleRate::RATE_UNKNOWN) ||
143       (static_cast<LdacChannelMode>(ldac_capability.channelMode &
144                                     ldac_config.channelMode) ==
145        LdacChannelMode::UNKNOWN) ||
146       (static_cast<BitsPerSample>(ldac_capability.bitsPerSample &
147                                   ldac_config.bitsPerSample) ==
148        BitsPerSample::BITS_UNKNOWN)) {
149     log::warn("software codec={} capability={}", toString(ldac_config),
150               toString(ldac_capability));
151     return false;
152   }
153   log::verbose("offloading codec={} capability={}", toString(ldac_config),
154                toString(ldac_capability));
155   return true;
156 }
157 }  // namespace
158 
159 namespace bluetooth {
160 namespace audio {
161 namespace hidl {
162 namespace codec {
163 
164 const CodecConfiguration kInvalidCodecConfiguration = {
165     .codecType = CodecType::UNKNOWN,
166     .encodedAudioBitrate = 0x00000000,
167     .peerMtu = 0xffff,
168     .isScmstEnabled = false,
169     .config = {}};
170 
A2dpCodecToHalSampleRate(const btav_a2dp_codec_config_t & a2dp_codec_config)171 SampleRate A2dpCodecToHalSampleRate(
172     const btav_a2dp_codec_config_t& a2dp_codec_config) {
173   switch (a2dp_codec_config.sample_rate) {
174     case BTAV_A2DP_CODEC_SAMPLE_RATE_44100:
175       return SampleRate::RATE_44100;
176     case BTAV_A2DP_CODEC_SAMPLE_RATE_48000:
177       return SampleRate::RATE_48000;
178     case BTAV_A2DP_CODEC_SAMPLE_RATE_88200:
179       return SampleRate::RATE_88200;
180     case BTAV_A2DP_CODEC_SAMPLE_RATE_96000:
181       return SampleRate::RATE_96000;
182     case BTAV_A2DP_CODEC_SAMPLE_RATE_176400:
183       return SampleRate::RATE_176400;
184     case BTAV_A2DP_CODEC_SAMPLE_RATE_192000:
185       return SampleRate::RATE_192000;
186     case BTAV_A2DP_CODEC_SAMPLE_RATE_16000:
187       return SampleRate::RATE_16000;
188     case BTAV_A2DP_CODEC_SAMPLE_RATE_24000:
189       return SampleRate::RATE_24000;
190     default:
191       return SampleRate::RATE_UNKNOWN;
192   }
193 }
194 
A2dpCodecToHalBitsPerSample(const btav_a2dp_codec_config_t & a2dp_codec_config)195 BitsPerSample A2dpCodecToHalBitsPerSample(
196     const btav_a2dp_codec_config_t& a2dp_codec_config) {
197   switch (a2dp_codec_config.bits_per_sample) {
198     case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16:
199       return BitsPerSample::BITS_16;
200     case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24:
201       return BitsPerSample::BITS_24;
202     case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32:
203       return BitsPerSample::BITS_32;
204     default:
205       return BitsPerSample::BITS_UNKNOWN;
206   }
207 }
208 
A2dpCodecToHalChannelMode(const btav_a2dp_codec_config_t & a2dp_codec_config)209 ChannelMode A2dpCodecToHalChannelMode(
210     const btav_a2dp_codec_config_t& a2dp_codec_config) {
211   switch (a2dp_codec_config.channel_mode) {
212     case BTAV_A2DP_CODEC_CHANNEL_MODE_MONO:
213       return ChannelMode::MONO;
214     case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO:
215       return ChannelMode::STEREO;
216     default:
217       return ChannelMode::UNKNOWN;
218   }
219 }
220 
A2dpSbcToHalConfig(CodecConfiguration * codec_config,A2dpCodecConfig * a2dp_config)221 bool A2dpSbcToHalConfig(CodecConfiguration* codec_config,
222                         A2dpCodecConfig* a2dp_config) {
223   btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
224   if (current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_SBC &&
225       current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SINK_SBC) {
226     *codec_config = {};
227     return false;
228   }
229   tBT_A2DP_OFFLOAD a2dp_offload;
230   a2dp_config->getCodecSpecificConfig(&a2dp_offload);
231   codec_config->codecType = CodecType::SBC;
232   codec_config->config.sbcConfig({});
233   auto sbc_config = codec_config->config.sbcConfig();
234   sbc_config.sampleRate = A2dpCodecToHalSampleRate(current_codec);
235   if (sbc_config.sampleRate == SampleRate::RATE_UNKNOWN) {
236     log::error("Unknown SBC sample_rate={}", current_codec.sample_rate);
237     return false;
238   }
239   uint8_t channel_mode = a2dp_offload.codec_info[3] & A2DP_SBC_IE_CH_MD_MSK;
240   switch (channel_mode) {
241     case A2DP_SBC_IE_CH_MD_JOINT:
242       sbc_config.channelMode = SbcChannelMode::JOINT_STEREO;
243       break;
244     case A2DP_SBC_IE_CH_MD_STEREO:
245       sbc_config.channelMode = SbcChannelMode::STEREO;
246       break;
247     case A2DP_SBC_IE_CH_MD_DUAL:
248       sbc_config.channelMode = SbcChannelMode::DUAL;
249       break;
250     case A2DP_SBC_IE_CH_MD_MONO:
251       sbc_config.channelMode = SbcChannelMode::MONO;
252       break;
253     default:
254       log::error("Unknown SBC channel_mode={}", channel_mode);
255       sbc_config.channelMode = SbcChannelMode::UNKNOWN;
256       return false;
257   }
258   uint8_t block_length = a2dp_offload.codec_info[0] & A2DP_SBC_IE_BLOCKS_MSK;
259   switch (block_length) {
260     case A2DP_SBC_IE_BLOCKS_4:
261       sbc_config.blockLength = SbcBlockLength::BLOCKS_4;
262       break;
263     case A2DP_SBC_IE_BLOCKS_8:
264       sbc_config.blockLength = SbcBlockLength::BLOCKS_8;
265       break;
266     case A2DP_SBC_IE_BLOCKS_12:
267       sbc_config.blockLength = SbcBlockLength::BLOCKS_12;
268       break;
269     case A2DP_SBC_IE_BLOCKS_16:
270       sbc_config.blockLength = SbcBlockLength::BLOCKS_16;
271       break;
272     default:
273       log::error("Unknown SBC block_length={}", block_length);
274       return false;
275   }
276   uint8_t sub_bands = a2dp_offload.codec_info[0] & A2DP_SBC_IE_SUBBAND_MSK;
277   switch (sub_bands) {
278     case A2DP_SBC_IE_SUBBAND_4:
279       sbc_config.numSubbands = SbcNumSubbands::SUBBAND_4;
280       break;
281     case A2DP_SBC_IE_SUBBAND_8:
282       sbc_config.numSubbands = SbcNumSubbands::SUBBAND_8;
283       break;
284     default:
285       log::error("Unknown SBC Subbands={}", sub_bands);
286       return false;
287   }
288   uint8_t alloc_method = a2dp_offload.codec_info[0] & A2DP_SBC_IE_ALLOC_MD_MSK;
289   switch (alloc_method) {
290     case A2DP_SBC_IE_ALLOC_MD_S:
291       sbc_config.allocMethod = SbcAllocMethod::ALLOC_MD_S;
292       break;
293     case A2DP_SBC_IE_ALLOC_MD_L:
294       sbc_config.allocMethod = SbcAllocMethod::ALLOC_MD_L;
295       break;
296     default:
297       log::error("Unknown SBC alloc_method={}", alloc_method);
298       return false;
299   }
300   sbc_config.minBitpool = a2dp_offload.codec_info[1];
301   sbc_config.maxBitpool = a2dp_offload.codec_info[2];
302   sbc_config.bitsPerSample = A2dpCodecToHalBitsPerSample(current_codec);
303   if (sbc_config.bitsPerSample == BitsPerSample::BITS_UNKNOWN) {
304     log::error("Unknown SBC bits_per_sample={}", current_codec.bits_per_sample);
305     return false;
306   }
307   codec_config->config.sbcConfig(sbc_config);
308   return true;
309 }
310 
A2dpAacToHalConfig(CodecConfiguration * codec_config,A2dpCodecConfig * a2dp_config)311 bool A2dpAacToHalConfig(CodecConfiguration* codec_config,
312                         A2dpCodecConfig* a2dp_config) {
313   btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
314   if (current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_AAC &&
315       current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SINK_AAC) {
316     *codec_config = {};
317     return false;
318   }
319   tBT_A2DP_OFFLOAD a2dp_offload;
320   a2dp_config->getCodecSpecificConfig(&a2dp_offload);
321   codec_config->codecType = CodecType::AAC;
322   codec_config->config.aacConfig({});
323   auto aac_config = codec_config->config.aacConfig();
324   uint8_t object_type = a2dp_offload.codec_info[0];
325   switch (object_type) {
326     case A2DP_AAC_OBJECT_TYPE_MPEG2_LC:
327       aac_config.objectType = AacObjectType::MPEG2_LC;
328       break;
329     case A2DP_AAC_OBJECT_TYPE_MPEG4_LC:
330       aac_config.objectType = AacObjectType::MPEG4_LC;
331       break;
332     case A2DP_AAC_OBJECT_TYPE_MPEG4_LTP:
333       aac_config.objectType = AacObjectType::MPEG4_LTP;
334       break;
335     case A2DP_AAC_OBJECT_TYPE_MPEG4_SCALABLE:
336       aac_config.objectType = AacObjectType::MPEG4_SCALABLE;
337       break;
338     default:
339       log::error("Unknown AAC object_type={}", object_type);
340       return false;
341   }
342   aac_config.sampleRate = A2dpCodecToHalSampleRate(current_codec);
343   if (aac_config.sampleRate == SampleRate::RATE_UNKNOWN) {
344     log::error("Unknown AAC sample_rate={}", current_codec.sample_rate);
345     return false;
346   }
347   aac_config.channelMode = A2dpCodecToHalChannelMode(current_codec);
348   if (aac_config.channelMode == ChannelMode::UNKNOWN) {
349     log::error("Unknown AAC channel_mode={}", current_codec.channel_mode);
350     return false;
351   }
352   uint8_t vbr_enabled =
353       a2dp_offload.codec_info[1] & A2DP_AAC_VARIABLE_BIT_RATE_MASK;
354   switch (vbr_enabled) {
355     case A2DP_AAC_VARIABLE_BIT_RATE_ENABLED:
356       aac_config.variableBitRateEnabled = AacVariableBitRate::ENABLED;
357       break;
358     case A2DP_AAC_VARIABLE_BIT_RATE_DISABLED:
359       aac_config.variableBitRateEnabled = AacVariableBitRate::DISABLED;
360       break;
361     default:
362       log::error("Unknown AAC VBR={}", vbr_enabled);
363       return false;
364   }
365   aac_config.bitsPerSample = A2dpCodecToHalBitsPerSample(current_codec);
366   if (aac_config.bitsPerSample == BitsPerSample::BITS_UNKNOWN) {
367     log::error("Unknown AAC bits_per_sample={}", current_codec.bits_per_sample);
368     return false;
369   }
370   codec_config->config.aacConfig(aac_config);
371   return true;
372 }
373 
A2dpAptxToHalConfig(CodecConfiguration * codec_config,A2dpCodecConfig * a2dp_config)374 bool A2dpAptxToHalConfig(CodecConfiguration* codec_config,
375                          A2dpCodecConfig* a2dp_config) {
376   btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
377   if (current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_APTX &&
378       current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD) {
379     *codec_config = {};
380     return false;
381   }
382   tBT_A2DP_OFFLOAD a2dp_offload;
383   a2dp_config->getCodecSpecificConfig(&a2dp_offload);
384   if (current_codec.codec_type == BTAV_A2DP_CODEC_INDEX_SOURCE_APTX) {
385     codec_config->codecType = CodecType::APTX;
386   } else {
387     codec_config->codecType = CodecType::APTX_HD;
388   }
389   codec_config->config.aptxConfig({});
390   auto aptx_config = codec_config->config.aptxConfig();
391   aptx_config.sampleRate = A2dpCodecToHalSampleRate(current_codec);
392   if (aptx_config.sampleRate == SampleRate::RATE_UNKNOWN) {
393     log::error("Unknown aptX sample_rate={}", current_codec.sample_rate);
394     return false;
395   }
396   aptx_config.channelMode = A2dpCodecToHalChannelMode(current_codec);
397   if (aptx_config.channelMode == ChannelMode::UNKNOWN) {
398     log::error("Unknown aptX channel_mode={}", current_codec.channel_mode);
399     return false;
400   }
401   aptx_config.bitsPerSample = A2dpCodecToHalBitsPerSample(current_codec);
402   if (aptx_config.bitsPerSample == BitsPerSample::BITS_UNKNOWN) {
403     log::error("Unknown aptX bits_per_sample={}",
404                current_codec.bits_per_sample);
405     return false;
406   }
407   codec_config->config.aptxConfig(aptx_config);
408   return true;
409 }
410 
A2dpLdacToHalConfig(CodecConfiguration * codec_config,A2dpCodecConfig * a2dp_config)411 bool A2dpLdacToHalConfig(CodecConfiguration* codec_config,
412                          A2dpCodecConfig* a2dp_config) {
413   btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
414   if (current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC) {
415     codec_config = {};
416     return false;
417   }
418   tBT_A2DP_OFFLOAD a2dp_offload;
419   a2dp_config->getCodecSpecificConfig(&a2dp_offload);
420   codec_config->codecType = CodecType::LDAC;
421   codec_config->config.ldacConfig({});
422   auto ldac_config = codec_config->config.ldacConfig();
423   ldac_config.sampleRate = A2dpCodecToHalSampleRate(current_codec);
424   if (ldac_config.sampleRate == SampleRate::RATE_UNKNOWN) {
425     log::error("Unknown LDAC sample_rate={}", current_codec.sample_rate);
426     return false;
427   }
428   switch (a2dp_offload.codec_info[7]) {
429     case A2DP_LDAC_CHANNEL_MODE_STEREO:
430       ldac_config.channelMode = LdacChannelMode::STEREO;
431       break;
432     case A2DP_LDAC_CHANNEL_MODE_DUAL:
433       ldac_config.channelMode = LdacChannelMode::DUAL;
434       break;
435     case A2DP_LDAC_CHANNEL_MODE_MONO:
436       ldac_config.channelMode = LdacChannelMode::MONO;
437       break;
438     default:
439       log::error("Unknown LDAC channel_mode={}", a2dp_offload.codec_info[7]);
440       ldac_config.channelMode = LdacChannelMode::UNKNOWN;
441       return false;
442   }
443   switch (a2dp_offload.codec_info[6]) {
444     case A2DP_LDAC_QUALITY_HIGH:
445       ldac_config.qualityIndex = LdacQualityIndex::QUALITY_HIGH;
446       break;
447     case A2DP_LDAC_QUALITY_MID:
448       ldac_config.qualityIndex = LdacQualityIndex::QUALITY_MID;
449       break;
450     case A2DP_LDAC_QUALITY_LOW:
451       ldac_config.qualityIndex = LdacQualityIndex::QUALITY_LOW;
452       break;
453     case A2DP_LDAC_QUALITY_ABR_OFFLOAD:
454       ldac_config.qualityIndex = LdacQualityIndex::QUALITY_ABR;
455       break;
456     default:
457       log::error("Unknown LDAC QualityIndex={}", a2dp_offload.codec_info[6]);
458       return false;
459   }
460   ldac_config.bitsPerSample = A2dpCodecToHalBitsPerSample(current_codec);
461   if (ldac_config.bitsPerSample == BitsPerSample::BITS_UNKNOWN) {
462     log::error("Unknown LDAC bits_per_sample={}",
463                current_codec.bits_per_sample);
464     return false;
465   }
466   codec_config->config.ldacConfig(ldac_config);
467   return true;
468 }
469 
UpdateOffloadingCapabilities(const std::vector<btav_a2dp_codec_config_t> & framework_preference)470 bool UpdateOffloadingCapabilities(
471     const std::vector<btav_a2dp_codec_config_t>& framework_preference) {
472   audio_hal_capabilities =
473       BluetoothAudioSinkClientInterface::GetAudioCapabilities(
474           SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
475   uint32_t codec_type_masks = static_cast<uint32_t>(CodecType::UNKNOWN);
476   for (auto preference : framework_preference) {
477     switch (preference.codec_type) {
478       case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
479         codec_type_masks |= CodecType::SBC;
480         break;
481       case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
482         codec_type_masks |= CodecType::AAC;
483         break;
484       case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX:
485         codec_type_masks |= CodecType::APTX;
486         break;
487       case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD:
488         codec_type_masks |= CodecType::APTX_HD;
489         break;
490       case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC:
491         codec_type_masks |= CodecType::LDAC;
492         break;
493       case BTAV_A2DP_CODEC_INDEX_SOURCE_LC3:
494         log::warn("Ignore source codec_type={}, not supported",
495                   preference.codec_type);
496         break;
497       case BTAV_A2DP_CODEC_INDEX_SOURCE_OPUS:
498         log::warn("Ignore source codec_type={}, not supported on HIDL",
499                   preference.codec_type);
500         break;
501       case BTAV_A2DP_CODEC_INDEX_SINK_SBC:
502         [[fallthrough]];
503       case BTAV_A2DP_CODEC_INDEX_SINK_AAC:
504         [[fallthrough]];
505       case BTAV_A2DP_CODEC_INDEX_SINK_LDAC:
506         [[fallthrough]];
507       case BTAV_A2DP_CODEC_INDEX_SINK_OPUS:
508         log::warn("Ignore sink codec_type={}", preference.codec_type);
509         break;
510       case BTAV_A2DP_CODEC_INDEX_MAX:
511         [[fallthrough]];
512       default:
513         log::error("Unknown codec_type={}", preference.codec_type);
514         return false;
515     }
516   }
517   offloading_preference.clear();
518   for (auto capability : audio_hal_capabilities) {
519     if (static_cast<CodecType>(capability.codecCapabilities().codecType &
520                                codec_type_masks) != CodecType::UNKNOWN) {
521       log::info("enabled offloading capability={}", toString(capability));
522       offloading_preference.push_back(capability);
523     } else {
524       log::info("disabled offloading capability={}", toString(capability));
525     }
526   }
527   // TODO: Bluetooth SoC and runtime property
528   return true;
529 }
530 
531 // Check whether this codec is supported by the audio HAL and is allowed to use
532 // by prefernece of framework / Bluetooth SoC / runtime property.
IsCodecOffloadingEnabled(const CodecConfiguration & codec_config)533 bool IsCodecOffloadingEnabled(const CodecConfiguration& codec_config) {
534   for (auto preference : offloading_preference) {
535     if (codec_config.codecType != preference.codecCapabilities().codecType)
536       continue;
537     auto codec_capability = preference.codecCapabilities();
538     switch (codec_capability.codecType) {
539       case CodecType::SBC: {
540         auto sbc_capability = codec_capability.capabilities.sbcCapabilities();
541         auto sbc_config = codec_config.config.sbcConfig();
542         return sbc_offloading_capability_match(sbc_capability, sbc_config);
543       }
544       case CodecType::AAC: {
545         auto aac_capability = codec_capability.capabilities.aacCapabilities();
546         auto aac_config = codec_config.config.aacConfig();
547         return aac_offloading_capability_match(aac_capability, aac_config);
548       }
549       case CodecType::APTX:
550         [[fallthrough]];
551       case CodecType::APTX_HD: {
552         auto aptx_capability = codec_capability.capabilities.aptxCapabilities();
553         auto aptx_config = codec_config.config.aptxConfig();
554         return aptx_offloading_capability_match(aptx_capability, aptx_config);
555       }
556       case CodecType::LDAC: {
557         auto ldac_capability = codec_capability.capabilities.ldacCapabilities();
558         auto ldac_config = codec_config.config.ldacConfig();
559         return ldac_offloading_capability_match(ldac_capability, ldac_config);
560       }
561       case CodecType::UNKNOWN:
562         [[fallthrough]];
563       default:
564         log::error("Unknown codecType={}",
565                    toString(codec_capability.codecType));
566         return false;
567     }
568   }
569   log::info("software codec={}", toString(codec_config));
570   return false;
571 }
572 
573 }  // namespace codec
574 }  // namespace hidl
575 }  // namespace audio
576 }  // namespace bluetooth
577