OSDN Git Service

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