1 /*
2  * Copyright (C) 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 "BTAudioCodecsAidl"
18 
19 #include "BluetoothAudioCodecs.h"
20 
21 #include <aidl/android/hardware/bluetooth/audio/AacCapabilities.h>
22 #include <aidl/android/hardware/bluetooth/audio/AacObjectType.h>
23 #include <aidl/android/hardware/bluetooth/audio/AptxCapabilities.h>
24 #include <aidl/android/hardware/bluetooth/audio/ChannelMode.h>
25 #include <aidl/android/hardware/bluetooth/audio/LdacCapabilities.h>
26 #include <aidl/android/hardware/bluetooth/audio/LdacChannelMode.h>
27 #include <aidl/android/hardware/bluetooth/audio/LdacQualityIndex.h>
28 #include <aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.h>
29 #include <aidl/android/hardware/bluetooth/audio/OpusCapabilities.h>
30 #include <aidl/android/hardware/bluetooth/audio/OpusConfiguration.h>
31 #include <aidl/android/hardware/bluetooth/audio/SbcCapabilities.h>
32 #include <aidl/android/hardware/bluetooth/audio/SbcChannelMode.h>
33 #include <android-base/logging.h>
34 
35 #include "BluetoothHfpCodecsProvider.h"
36 #include "BluetoothLeAudioAseConfigurationSettingProvider.h"
37 #include "BluetoothLeAudioCodecsProvider.h"
38 
39 namespace aidl {
40 namespace android {
41 namespace hardware {
42 namespace bluetooth {
43 namespace audio {
44 
45 static const PcmCapabilities kDefaultSoftwarePcmCapabilities = {
46     .sampleRateHz = {8000, 16000, 24000, 32000, 44100, 48000, 88200, 96000},
47     .channelMode = {ChannelMode::MONO, ChannelMode::STEREO},
48     .bitsPerSample = {16, 24, 32},
49     .dataIntervalUs = {},
50 };
51 
52 static const SbcCapabilities kDefaultOffloadSbcCapability = {
53     .sampleRateHz = {44100},
54     .channelMode = {SbcChannelMode::MONO, SbcChannelMode::JOINT_STEREO},
55     .blockLength = {4, 8, 12, 16},
56     .numSubbands = {8},
57     .allocMethod = {SbcAllocMethod::ALLOC_MD_L},
58     .bitsPerSample = {16},
59     .minBitpool = 2,
60     .maxBitpool = 53};
61 
62 static const AacCapabilities kDefaultOffloadAacCapability = {
63     .objectType = {AacObjectType::MPEG2_LC},
64     .sampleRateHz = {44100},
65     .channelMode = {ChannelMode::STEREO},
66     .variableBitRateSupported = true,
67     .bitsPerSample = {16}};
68 
69 static const LdacCapabilities kDefaultOffloadLdacCapability = {
70     .sampleRateHz = {44100, 48000, 88200, 96000},
71     .channelMode = {LdacChannelMode::DUAL, LdacChannelMode::STEREO},
72     .qualityIndex = {LdacQualityIndex::HIGH},
73     .bitsPerSample = {16, 24, 32}};
74 
75 static const AptxCapabilities kDefaultOffloadAptxCapability = {
76     .sampleRateHz = {44100, 48000},
77     .channelMode = {ChannelMode::STEREO},
78     .bitsPerSample = {16},
79 };
80 
81 static const AptxCapabilities kDefaultOffloadAptxHdCapability = {
82     .sampleRateHz = {44100, 48000},
83     .channelMode = {ChannelMode::STEREO},
84     .bitsPerSample = {24},
85 };
86 
87 static const OpusCapabilities kDefaultOffloadOpusCapability = {
88     .samplingFrequencyHz = {48000},
89     .frameDurationUs = {10000, 20000},
90     .channelMode = {ChannelMode::MONO, ChannelMode::STEREO},
91 };
92 
93 const std::vector<CodecCapabilities> kDefaultOffloadA2dpCodecCapabilities = {
94     {.codecType = CodecType::SBC, .capabilities = {}},
95     {.codecType = CodecType::AAC, .capabilities = {}},
96     {.codecType = CodecType::LDAC, .capabilities = {}},
97     {.codecType = CodecType::APTX, .capabilities = {}},
98     {.codecType = CodecType::APTX_HD, .capabilities = {}},
99     {.codecType = CodecType::OPUS, .capabilities = {}}};
100 
101 std::vector<LeAudioCodecCapabilitiesSetting> kDefaultOffloadLeAudioCapabilities;
102 std::unordered_map<SessionType, std::vector<CodecInfo>>
103     kDefaultOffloadLeAudioCodecInfoMap;
104 std::vector<CodecInfo> kDefaultOffloadHfpCodecInfo;
105 
106 template <class T>
ContainedInVector(const std::vector<T> & vector,const typename identity<T>::type & target)107 bool BluetoothAudioCodecs::ContainedInVector(
108     const std::vector<T>& vector, const typename identity<T>::type& target) {
109   return std::find(vector.begin(), vector.end(), target) != vector.end();
110 }
111 
IsOffloadSbcConfigurationValid(const CodecConfiguration::CodecSpecific & codec_specific)112 bool BluetoothAudioCodecs::IsOffloadSbcConfigurationValid(
113     const CodecConfiguration::CodecSpecific& codec_specific) {
114   if (codec_specific.getTag() != CodecConfiguration::CodecSpecific::sbcConfig) {
115     LOG(WARNING) << __func__
116                  << ": Invalid CodecSpecific=" << codec_specific.toString();
117     return false;
118   }
119   const SbcConfiguration sbc_data =
120       codec_specific.get<CodecConfiguration::CodecSpecific::sbcConfig>();
121 
122   if (ContainedInVector(kDefaultOffloadSbcCapability.sampleRateHz,
123                         sbc_data.sampleRateHz) &&
124       ContainedInVector(kDefaultOffloadSbcCapability.blockLength,
125                         sbc_data.blockLength) &&
126       ContainedInVector(kDefaultOffloadSbcCapability.numSubbands,
127                         sbc_data.numSubbands) &&
128       ContainedInVector(kDefaultOffloadSbcCapability.bitsPerSample,
129                         sbc_data.bitsPerSample) &&
130       ContainedInVector(kDefaultOffloadSbcCapability.channelMode,
131                         sbc_data.channelMode) &&
132       ContainedInVector(kDefaultOffloadSbcCapability.allocMethod,
133                         sbc_data.allocMethod) &&
134       sbc_data.minBitpool <= sbc_data.maxBitpool &&
135       kDefaultOffloadSbcCapability.minBitpool <= sbc_data.minBitpool &&
136       kDefaultOffloadSbcCapability.maxBitpool >= sbc_data.maxBitpool) {
137     return true;
138   }
139   LOG(WARNING) << __func__
140                << ": Unsupported CodecSpecific=" << codec_specific.toString();
141   return false;
142 }
143 
IsOffloadAacConfigurationValid(const CodecConfiguration::CodecSpecific & codec_specific)144 bool BluetoothAudioCodecs::IsOffloadAacConfigurationValid(
145     const CodecConfiguration::CodecSpecific& codec_specific) {
146   if (codec_specific.getTag() != CodecConfiguration::CodecSpecific::aacConfig) {
147     LOG(WARNING) << __func__
148                  << ": Invalid CodecSpecific=" << codec_specific.toString();
149     return false;
150   }
151   const AacConfiguration aac_data =
152       codec_specific.get<CodecConfiguration::CodecSpecific::aacConfig>();
153 
154   if (ContainedInVector(kDefaultOffloadAacCapability.sampleRateHz,
155                         aac_data.sampleRateHz) &&
156       ContainedInVector(kDefaultOffloadAacCapability.bitsPerSample,
157                         aac_data.bitsPerSample) &&
158       ContainedInVector(kDefaultOffloadAacCapability.channelMode,
159                         aac_data.channelMode) &&
160       ContainedInVector(kDefaultOffloadAacCapability.objectType,
161                         aac_data.objectType) &&
162       (!aac_data.variableBitRateEnabled ||
163        kDefaultOffloadAacCapability.variableBitRateSupported)) {
164     return true;
165   }
166   LOG(WARNING) << __func__
167                << ": Unsupported CodecSpecific=" << codec_specific.toString();
168   return false;
169 }
170 
IsOffloadLdacConfigurationValid(const CodecConfiguration::CodecSpecific & codec_specific)171 bool BluetoothAudioCodecs::IsOffloadLdacConfigurationValid(
172     const CodecConfiguration::CodecSpecific& codec_specific) {
173   if (codec_specific.getTag() !=
174       CodecConfiguration::CodecSpecific::ldacConfig) {
175     LOG(WARNING) << __func__
176                  << ": Invalid CodecSpecific=" << codec_specific.toString();
177     return false;
178   }
179   const LdacConfiguration ldac_data =
180       codec_specific.get<CodecConfiguration::CodecSpecific::ldacConfig>();
181 
182   if (ContainedInVector(kDefaultOffloadLdacCapability.sampleRateHz,
183                         ldac_data.sampleRateHz) &&
184       ContainedInVector(kDefaultOffloadLdacCapability.bitsPerSample,
185                         ldac_data.bitsPerSample) &&
186       ContainedInVector(kDefaultOffloadLdacCapability.channelMode,
187                         ldac_data.channelMode) &&
188       ContainedInVector(kDefaultOffloadLdacCapability.qualityIndex,
189                         ldac_data.qualityIndex)) {
190     return true;
191   }
192   LOG(WARNING) << __func__
193                << ": Unsupported CodecSpecific=" << codec_specific.toString();
194   return false;
195 }
196 
IsOffloadAptxConfigurationValid(const CodecConfiguration::CodecSpecific & codec_specific)197 bool BluetoothAudioCodecs::IsOffloadAptxConfigurationValid(
198     const CodecConfiguration::CodecSpecific& codec_specific) {
199   if (codec_specific.getTag() !=
200       CodecConfiguration::CodecSpecific::aptxConfig) {
201     LOG(WARNING) << __func__
202                  << ": Invalid CodecSpecific=" << codec_specific.toString();
203     return false;
204   }
205   const AptxConfiguration aptx_data =
206       codec_specific.get<CodecConfiguration::CodecSpecific::aptxConfig>();
207 
208   if (ContainedInVector(kDefaultOffloadAptxCapability.sampleRateHz,
209                         aptx_data.sampleRateHz) &&
210       ContainedInVector(kDefaultOffloadAptxCapability.bitsPerSample,
211                         aptx_data.bitsPerSample) &&
212       ContainedInVector(kDefaultOffloadAptxCapability.channelMode,
213                         aptx_data.channelMode)) {
214     return true;
215   }
216   LOG(WARNING) << __func__
217                << ": Unsupported CodecSpecific=" << codec_specific.toString();
218   return false;
219 }
220 
IsOffloadAptxHdConfigurationValid(const CodecConfiguration::CodecSpecific & codec_specific)221 bool BluetoothAudioCodecs::IsOffloadAptxHdConfigurationValid(
222     const CodecConfiguration::CodecSpecific& codec_specific) {
223   if (codec_specific.getTag() !=
224       CodecConfiguration::CodecSpecific::aptxConfig) {
225     LOG(WARNING) << __func__
226                  << ": Invalid CodecSpecific=" << codec_specific.toString();
227     return false;
228   }
229   const AptxConfiguration aptx_data =
230       codec_specific.get<CodecConfiguration::CodecSpecific::aptxConfig>();
231 
232   if (ContainedInVector(kDefaultOffloadAptxHdCapability.sampleRateHz,
233                         aptx_data.sampleRateHz) &&
234       ContainedInVector(kDefaultOffloadAptxHdCapability.bitsPerSample,
235                         aptx_data.bitsPerSample) &&
236       ContainedInVector(kDefaultOffloadAptxHdCapability.channelMode,
237                         aptx_data.channelMode)) {
238     return true;
239   }
240   LOG(WARNING) << __func__
241                << ": Unsupported CodecSpecific=" << codec_specific.toString();
242   return false;
243 }
244 
IsOffloadOpusConfigurationValid(const CodecConfiguration::CodecSpecific & codec_specific)245 bool BluetoothAudioCodecs::IsOffloadOpusConfigurationValid(
246     const CodecConfiguration::CodecSpecific& codec_specific) {
247   if (codec_specific.getTag() !=
248       CodecConfiguration::CodecSpecific::opusConfig) {
249     LOG(WARNING) << __func__
250                  << ": Invalid CodecSpecific=" << codec_specific.toString();
251     return false;
252   }
253   std::optional<OpusConfiguration> opus_data =
254       codec_specific.get<CodecConfiguration::CodecSpecific::opusConfig>();
255 
256   if (opus_data.has_value() &&
257       ContainedInVector(kDefaultOffloadOpusCapability.samplingFrequencyHz,
258                         opus_data->samplingFrequencyHz) &&
259       ContainedInVector(kDefaultOffloadOpusCapability.frameDurationUs,
260                         opus_data->frameDurationUs) &&
261       ContainedInVector(kDefaultOffloadOpusCapability.channelMode,
262                         opus_data->channelMode)) {
263     return true;
264   }
265   LOG(WARNING) << __func__
266                << ": Unsupported CodecSpecific=" << codec_specific.toString();
267   return false;
268 }
269 
270 std::vector<PcmCapabilities>
GetSoftwarePcmCapabilities()271 BluetoothAudioCodecs::GetSoftwarePcmCapabilities() {
272   return {kDefaultSoftwarePcmCapabilities};
273 }
274 
275 std::vector<CodecCapabilities>
GetA2dpOffloadCodecCapabilities(const SessionType & session_type)276 BluetoothAudioCodecs::GetA2dpOffloadCodecCapabilities(
277     const SessionType& session_type) {
278   if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
279       session_type != SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
280     return {};
281   }
282   std::vector<CodecCapabilities> offload_a2dp_codec_capabilities =
283       kDefaultOffloadA2dpCodecCapabilities;
284   for (auto& codec_capability : offload_a2dp_codec_capabilities) {
285     switch (codec_capability.codecType) {
286       case CodecType::SBC:
287         codec_capability.capabilities
288             .set<CodecCapabilities::Capabilities::sbcCapabilities>(
289                 kDefaultOffloadSbcCapability);
290         break;
291       case CodecType::AAC:
292         codec_capability.capabilities
293             .set<CodecCapabilities::Capabilities::aacCapabilities>(
294                 kDefaultOffloadAacCapability);
295         break;
296       case CodecType::LDAC:
297         codec_capability.capabilities
298             .set<CodecCapabilities::Capabilities::ldacCapabilities>(
299                 kDefaultOffloadLdacCapability);
300         break;
301       case CodecType::APTX:
302         codec_capability.capabilities
303             .set<CodecCapabilities::Capabilities::aptxCapabilities>(
304                 kDefaultOffloadAptxCapability);
305         break;
306       case CodecType::APTX_HD:
307         codec_capability.capabilities
308             .set<CodecCapabilities::Capabilities::aptxCapabilities>(
309                 kDefaultOffloadAptxHdCapability);
310         break;
311       case CodecType::OPUS:
312         codec_capability.capabilities
313             .set<CodecCapabilities::Capabilities::opusCapabilities>(
314                 kDefaultOffloadOpusCapability);
315         break;
316       case CodecType::UNKNOWN:
317       case CodecType::VENDOR:
318       case CodecType::LC3:
319       case CodecType::APTX_ADAPTIVE:
320       case CodecType::APTX_ADAPTIVE_LE:
321       case CodecType::APTX_ADAPTIVE_LEX:
322         break;
323     }
324   }
325   return offload_a2dp_codec_capabilities;
326 }
327 
IsSoftwarePcmConfigurationValid(const PcmConfiguration & pcm_config)328 bool BluetoothAudioCodecs::IsSoftwarePcmConfigurationValid(
329     const PcmConfiguration& pcm_config) {
330   if (ContainedInVector(kDefaultSoftwarePcmCapabilities.sampleRateHz,
331                         pcm_config.sampleRateHz) &&
332       ContainedInVector(kDefaultSoftwarePcmCapabilities.bitsPerSample,
333                         pcm_config.bitsPerSample) &&
334       ContainedInVector(kDefaultSoftwarePcmCapabilities.channelMode,
335                         pcm_config.channelMode)
336       // data interval is not checked for now
337       // && pcm_config.dataIntervalUs != 0
338   ) {
339     return true;
340   }
341   LOG(WARNING) << __func__
342                << ": Unsupported CodecSpecific=" << pcm_config.toString();
343   return false;
344 }
345 
IsOffloadCodecConfigurationValid(const SessionType & session_type,const CodecConfiguration & codec_config)346 bool BluetoothAudioCodecs::IsOffloadCodecConfigurationValid(
347     const SessionType& session_type, const CodecConfiguration& codec_config) {
348   if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
349       session_type != SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
350     LOG(ERROR) << __func__
351                << ": Invalid SessionType=" << toString(session_type);
352     return false;
353   }
354   const CodecConfiguration::CodecSpecific& codec_specific = codec_config.config;
355   switch (codec_config.codecType) {
356     case CodecType::SBC:
357       if (IsOffloadSbcConfigurationValid(codec_specific)) {
358         return true;
359       }
360       break;
361     case CodecType::AAC:
362       if (IsOffloadAacConfigurationValid(codec_specific)) {
363         return true;
364       }
365       break;
366     case CodecType::LDAC:
367       if (IsOffloadLdacConfigurationValid(codec_specific)) {
368         return true;
369       }
370       break;
371     case CodecType::APTX:
372       if (IsOffloadAptxConfigurationValid(codec_specific)) {
373         return true;
374       }
375       break;
376     case CodecType::APTX_HD:
377       if (IsOffloadAptxHdConfigurationValid(codec_specific)) {
378         return true;
379       }
380       break;
381     case CodecType::OPUS:
382       if (IsOffloadOpusConfigurationValid(codec_specific)) {
383         return true;
384       }
385       break;
386     case CodecType::APTX_ADAPTIVE:
387     case CodecType::APTX_ADAPTIVE_LE:
388     case CodecType::APTX_ADAPTIVE_LEX:
389     case CodecType::LC3:
390     case CodecType::UNKNOWN:
391     case CodecType::VENDOR:
392       break;
393   }
394   return false;
395 }
396 
397 std::vector<LeAudioCodecCapabilitiesSetting>
GetLeAudioOffloadCodecCapabilities(const SessionType & session_type)398 BluetoothAudioCodecs::GetLeAudioOffloadCodecCapabilities(
399     const SessionType& session_type) {
400   if (session_type !=
401           SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
402       session_type !=
403           SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH &&
404       session_type !=
405           SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
406     return std::vector<LeAudioCodecCapabilitiesSetting>(0);
407   }
408 
409   if (kDefaultOffloadLeAudioCapabilities.empty()) {
410     auto le_audio_offload_setting =
411         BluetoothLeAudioCodecsProvider::ParseFromLeAudioOffloadSettingFile();
412     kDefaultOffloadLeAudioCapabilities =
413         BluetoothLeAudioCodecsProvider::GetLeAudioCodecCapabilities(
414             le_audio_offload_setting);
415   }
416   return kDefaultOffloadLeAudioCapabilities;
417 }
418 
GetLeAudioOffloadCodecInfo(const SessionType & session_type)419 std::vector<CodecInfo> BluetoothAudioCodecs::GetLeAudioOffloadCodecInfo(
420     const SessionType& session_type) {
421   if (session_type !=
422           SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
423       session_type !=
424           SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH &&
425       session_type !=
426           SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
427     return std::vector<CodecInfo>();
428   }
429 
430   if (kDefaultOffloadLeAudioCodecInfoMap.empty()) {
431     auto le_audio_offload_setting =
432         BluetoothLeAudioCodecsProvider::ParseFromLeAudioOffloadSettingFile();
433     kDefaultOffloadLeAudioCodecInfoMap =
434         BluetoothLeAudioCodecsProvider::GetLeAudioCodecInfo(
435             le_audio_offload_setting);
436   }
437   auto codec_info_map_iter =
438       kDefaultOffloadLeAudioCodecInfoMap.find(session_type);
439   if (codec_info_map_iter == kDefaultOffloadLeAudioCodecInfoMap.end())
440     return std::vector<CodecInfo>();
441   return codec_info_map_iter->second;
442 }
443 
GetHfpOffloadCodecInfo()444 std::vector<CodecInfo> BluetoothAudioCodecs::GetHfpOffloadCodecInfo() {
445   if (kDefaultOffloadHfpCodecInfo.empty()) {
446     auto hfp_offload_setting =
447         BluetoothHfpCodecsProvider::ParseFromHfpOffloadSettingFile();
448     // Load file into list
449     kDefaultOffloadHfpCodecInfo =
450         BluetoothHfpCodecsProvider::GetHfpAudioCodecInfo(hfp_offload_setting);
451   }
452   return kDefaultOffloadHfpCodecInfo;
453 }
454 
455 std::vector<LeAudioAseConfigurationSetting>
GetLeAudioAseConfigurationSettings()456 BluetoothAudioCodecs::GetLeAudioAseConfigurationSettings() {
457   return AudioSetConfigurationProviderJson::
458       GetLeAudioAseConfigurationSettings();
459 }
460 
461 }  // namespace audio
462 }  // namespace bluetooth
463 }  // namespace hardware
464 }  // namespace android
465 }  // namespace aidl
466