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