blob: b858f504ed2a6bf38ca14a3e59ec08d64a567a77 [file] [log] [blame]
Josh Wu20bac522021-12-29 23:52:39 -08001/*
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>
Omer Osmana2587da2022-05-01 03:54:11 +000029#include <aidl/android/hardware/bluetooth/audio/OpusCapabilities.h>
30#include <aidl/android/hardware/bluetooth/audio/OpusConfiguration.h>
Josh Wu20bac522021-12-29 23:52:39 -080031#include <aidl/android/hardware/bluetooth/audio/SbcCapabilities.h>
32#include <aidl/android/hardware/bluetooth/audio/SbcChannelMode.h>
33#include <android-base/logging.h>
34
35namespace aidl {
36namespace android {
37namespace hardware {
38namespace bluetooth {
39namespace audio {
40
41static const PcmCapabilities kDefaultSoftwarePcmCapabilities = {
Ɓukasz Rymanowski4d14c1e2022-05-06 17:12:50 +000042 .sampleRateHz = {16000, 24000, 32000, 44100, 48000, 88200, 96000},
Josh Wu20bac522021-12-29 23:52:39 -080043 .channelMode = {ChannelMode::MONO, ChannelMode::STEREO},
44 .bitsPerSample = {16, 24, 32},
45 .dataIntervalUs = {},
46};
47
48static const SbcCapabilities kDefaultOffloadSbcCapability = {
49 .sampleRateHz = {44100},
50 .channelMode = {SbcChannelMode::MONO, SbcChannelMode::JOINT_STEREO},
51 .blockLength = {4, 8, 12, 16},
52 .numSubbands = {8},
53 .allocMethod = {SbcAllocMethod::ALLOC_MD_L},
54 .bitsPerSample = {16},
55 .minBitpool = 2,
56 .maxBitpool = 53};
57
58static const AacCapabilities kDefaultOffloadAacCapability = {
59 .objectType = {AacObjectType::MPEG2_LC},
60 .sampleRateHz = {44100},
61 .channelMode = {ChannelMode::STEREO},
62 .variableBitRateSupported = true,
63 .bitsPerSample = {16}};
64
65static const LdacCapabilities kDefaultOffloadLdacCapability = {
66 .sampleRateHz = {44100, 48000, 88200, 96000},
67 .channelMode = {LdacChannelMode::DUAL, LdacChannelMode::STEREO},
68 .qualityIndex = {LdacQualityIndex::HIGH},
69 .bitsPerSample = {16, 24, 32}};
70
71static const AptxCapabilities kDefaultOffloadAptxCapability = {
72 .sampleRateHz = {44100, 48000},
73 .channelMode = {ChannelMode::STEREO},
74 .bitsPerSample = {16},
75};
76
77static const AptxCapabilities kDefaultOffloadAptxHdCapability = {
78 .sampleRateHz = {44100, 48000},
79 .channelMode = {ChannelMode::STEREO},
80 .bitsPerSample = {24},
81};
82
Omer Osmana2587da2022-05-01 03:54:11 +000083static const OpusCapabilities kDefaultOffloadOpusCapability = {
84 .samplingFrequencyHz = {48000},
85 .frameDurationUs = {10000, 20000},
Josh Wu20bac522021-12-29 23:52:39 -080086 .channelMode = {ChannelMode::MONO, ChannelMode::STEREO},
87};
88
89const std::vector<CodecCapabilities> kDefaultOffloadA2dpCodecCapabilities = {
90 {.codecType = CodecType::SBC, .capabilities = {}},
91 {.codecType = CodecType::AAC, .capabilities = {}},
92 {.codecType = CodecType::LDAC, .capabilities = {}},
93 {.codecType = CodecType::APTX, .capabilities = {}},
94 {.codecType = CodecType::APTX_HD, .capabilities = {}},
Omer Osmana2587da2022-05-01 03:54:11 +000095 {.codecType = CodecType::OPUS, .capabilities = {}}};
Josh Wu20bac522021-12-29 23:52:39 -080096
97std::vector<LeAudioCodecCapabilitiesSetting> kDefaultOffloadLeAudioCapabilities;
98
99static const UnicastCapability kInvalidUnicastCapability = {
100 .codecType = CodecType::UNKNOWN};
101
102static const BroadcastCapability kInvalidBroadcastCapability = {
103 .codecType = CodecType::UNKNOWN};
104
105// Default Supported Codecs
106// LC3 16_1: sample rate: 16 kHz, frame duration: 7.5 ms, octets per frame: 30
107static const Lc3Capabilities kLc3Capability_16_1 = {
108 .samplingFrequencyHz = {16000},
109 .frameDurationUs = {7500},
110 .octetsPerFrame = {30}};
111
112// Default Supported Codecs
113// LC3 16_2: sample rate: 16 kHz, frame duration: 10 ms, octets per frame: 40
114static const Lc3Capabilities kLc3Capability_16_2 = {
115 .samplingFrequencyHz = {16000},
116 .frameDurationUs = {10000},
117 .octetsPerFrame = {40}};
118
119// Default Supported Codecs
Patty Huangbdf65ba2022-04-26 20:33:39 +0800120// LC3 24_2: sample rate: 24 kHz, frame duration: 10 ms, octets per frame: 60
121static const Lc3Capabilities kLc3Capability_24_2 = {
122 .samplingFrequencyHz = {24000},
123 .frameDurationUs = {10000},
124 .octetsPerFrame = {60}};
125
126// Default Supported Codecs
127// LC3 32_2: sample rate: 32 kHz, frame duration: 10 ms, octets per frame: 80
128static const Lc3Capabilities kLc3Capability_32_2 = {
129 .samplingFrequencyHz = {32000},
130 .frameDurationUs = {10000},
131 .octetsPerFrame = {80}};
132
133// Default Supported Codecs
Josh Wu20bac522021-12-29 23:52:39 -0800134// LC3 48_4: sample rate: 48 kHz, frame duration: 10 ms, octets per frame: 120
135static const Lc3Capabilities kLc3Capability_48_4 = {
136 .samplingFrequencyHz = {48000},
137 .frameDurationUs = {10000},
138 .octetsPerFrame = {120}};
139
140static const std::vector<Lc3Capabilities> supportedLc3CapabilityList = {
Patty Huangbdf65ba2022-04-26 20:33:39 +0800141 kLc3Capability_48_4, kLc3Capability_32_2, kLc3Capability_24_2,
142 kLc3Capability_16_2, kLc3Capability_16_1};
Josh Wu20bac522021-12-29 23:52:39 -0800143
144static AudioLocation stereoAudio = static_cast<AudioLocation>(
145 static_cast<uint8_t>(AudioLocation::FRONT_LEFT) |
146 static_cast<uint8_t>(AudioLocation::FRONT_RIGHT));
147static AudioLocation monoAudio = AudioLocation::UNKNOWN;
148
149// Stores the supported setting of audio location, connected device, and the
150// channel count for each device
151std::vector<std::tuple<AudioLocation, uint8_t, uint8_t>>
Patty03cbe712022-02-10 10:07:17 +0800152 supportedDeviceSetting = {
153 // Stereo, two connected device, one for L one for R
154 std::make_tuple(stereoAudio, 2, 1),
155 // Stereo, one connected device for both L and R
156 std::make_tuple(stereoAudio, 1, 2),
157 // Mono
158 std::make_tuple(monoAudio, 1, 1)};
Josh Wu20bac522021-12-29 23:52:39 -0800159
160template <class T>
161bool BluetoothAudioCodecs::ContainedInVector(
162 const std::vector<T>& vector, const typename identity<T>::type& target) {
163 return std::find(vector.begin(), vector.end(), target) != vector.end();
164}
165
166bool BluetoothAudioCodecs::IsOffloadSbcConfigurationValid(
167 const CodecConfiguration::CodecSpecific& codec_specific) {
168 if (codec_specific.getTag() != CodecConfiguration::CodecSpecific::sbcConfig) {
169 LOG(WARNING) << __func__
170 << ": Invalid CodecSpecific=" << codec_specific.toString();
171 return false;
172 }
173 const SbcConfiguration sbc_data =
174 codec_specific.get<CodecConfiguration::CodecSpecific::sbcConfig>();
175
176 if (ContainedInVector(kDefaultOffloadSbcCapability.sampleRateHz,
177 sbc_data.sampleRateHz) &&
178 ContainedInVector(kDefaultOffloadSbcCapability.blockLength,
179 sbc_data.blockLength) &&
180 ContainedInVector(kDefaultOffloadSbcCapability.numSubbands,
181 sbc_data.numSubbands) &&
182 ContainedInVector(kDefaultOffloadSbcCapability.bitsPerSample,
183 sbc_data.bitsPerSample) &&
184 ContainedInVector(kDefaultOffloadSbcCapability.channelMode,
185 sbc_data.channelMode) &&
186 ContainedInVector(kDefaultOffloadSbcCapability.allocMethod,
187 sbc_data.allocMethod) &&
188 sbc_data.minBitpool <= sbc_data.maxBitpool &&
189 kDefaultOffloadSbcCapability.minBitpool <= sbc_data.minBitpool &&
190 kDefaultOffloadSbcCapability.maxBitpool >= sbc_data.maxBitpool) {
191 return true;
192 }
193 LOG(WARNING) << __func__
194 << ": Unsupported CodecSpecific=" << codec_specific.toString();
195 return false;
196}
197
198bool BluetoothAudioCodecs::IsOffloadAacConfigurationValid(
199 const CodecConfiguration::CodecSpecific& codec_specific) {
200 if (codec_specific.getTag() != CodecConfiguration::CodecSpecific::aacConfig) {
201 LOG(WARNING) << __func__
202 << ": Invalid CodecSpecific=" << codec_specific.toString();
203 return false;
204 }
205 const AacConfiguration aac_data =
206 codec_specific.get<CodecConfiguration::CodecSpecific::aacConfig>();
207
208 if (ContainedInVector(kDefaultOffloadAacCapability.sampleRateHz,
209 aac_data.sampleRateHz) &&
210 ContainedInVector(kDefaultOffloadAacCapability.bitsPerSample,
211 aac_data.bitsPerSample) &&
212 ContainedInVector(kDefaultOffloadAacCapability.channelMode,
213 aac_data.channelMode) &&
214 ContainedInVector(kDefaultOffloadAacCapability.objectType,
215 aac_data.objectType) &&
216 (!aac_data.variableBitRateEnabled ||
217 kDefaultOffloadAacCapability.variableBitRateSupported)) {
218 return true;
219 }
220 LOG(WARNING) << __func__
221 << ": Unsupported CodecSpecific=" << codec_specific.toString();
222 return false;
223}
224
225bool BluetoothAudioCodecs::IsOffloadLdacConfigurationValid(
226 const CodecConfiguration::CodecSpecific& codec_specific) {
227 if (codec_specific.getTag() !=
228 CodecConfiguration::CodecSpecific::ldacConfig) {
229 LOG(WARNING) << __func__
230 << ": Invalid CodecSpecific=" << codec_specific.toString();
231 return false;
232 }
233 const LdacConfiguration ldac_data =
234 codec_specific.get<CodecConfiguration::CodecSpecific::ldacConfig>();
235
236 if (ContainedInVector(kDefaultOffloadLdacCapability.sampleRateHz,
237 ldac_data.sampleRateHz) &&
238 ContainedInVector(kDefaultOffloadLdacCapability.bitsPerSample,
239 ldac_data.bitsPerSample) &&
240 ContainedInVector(kDefaultOffloadLdacCapability.channelMode,
241 ldac_data.channelMode) &&
242 ContainedInVector(kDefaultOffloadLdacCapability.qualityIndex,
243 ldac_data.qualityIndex)) {
244 return true;
245 }
246 LOG(WARNING) << __func__
247 << ": Unsupported CodecSpecific=" << codec_specific.toString();
248 return false;
249}
250
251bool BluetoothAudioCodecs::IsOffloadAptxConfigurationValid(
252 const CodecConfiguration::CodecSpecific& codec_specific) {
253 if (codec_specific.getTag() !=
254 CodecConfiguration::CodecSpecific::aptxConfig) {
255 LOG(WARNING) << __func__
256 << ": Invalid CodecSpecific=" << codec_specific.toString();
257 return false;
258 }
259 const AptxConfiguration aptx_data =
260 codec_specific.get<CodecConfiguration::CodecSpecific::aptxConfig>();
261
262 if (ContainedInVector(kDefaultOffloadAptxCapability.sampleRateHz,
263 aptx_data.sampleRateHz) &&
264 ContainedInVector(kDefaultOffloadAptxCapability.bitsPerSample,
265 aptx_data.bitsPerSample) &&
266 ContainedInVector(kDefaultOffloadAptxCapability.channelMode,
267 aptx_data.channelMode)) {
268 return true;
269 }
270 LOG(WARNING) << __func__
271 << ": Unsupported CodecSpecific=" << codec_specific.toString();
272 return false;
273}
274
275bool BluetoothAudioCodecs::IsOffloadAptxHdConfigurationValid(
276 const CodecConfiguration::CodecSpecific& codec_specific) {
277 if (codec_specific.getTag() !=
278 CodecConfiguration::CodecSpecific::aptxConfig) {
279 LOG(WARNING) << __func__
280 << ": Invalid CodecSpecific=" << codec_specific.toString();
281 return false;
282 }
283 const AptxConfiguration aptx_data =
284 codec_specific.get<CodecConfiguration::CodecSpecific::aptxConfig>();
285
286 if (ContainedInVector(kDefaultOffloadAptxHdCapability.sampleRateHz,
287 aptx_data.sampleRateHz) &&
288 ContainedInVector(kDefaultOffloadAptxHdCapability.bitsPerSample,
289 aptx_data.bitsPerSample) &&
290 ContainedInVector(kDefaultOffloadAptxHdCapability.channelMode,
291 aptx_data.channelMode)) {
292 return true;
293 }
294 LOG(WARNING) << __func__
295 << ": Unsupported CodecSpecific=" << codec_specific.toString();
296 return false;
297}
298
Omer Osmana2587da2022-05-01 03:54:11 +0000299bool BluetoothAudioCodecs::IsOffloadOpusConfigurationValid(
Josh Wu20bac522021-12-29 23:52:39 -0800300 const CodecConfiguration::CodecSpecific& codec_specific) {
Omer Osmana2587da2022-05-01 03:54:11 +0000301 if (codec_specific.getTag() !=
302 CodecConfiguration::CodecSpecific::opusConfig) {
Josh Wu20bac522021-12-29 23:52:39 -0800303 LOG(WARNING) << __func__
304 << ": Invalid CodecSpecific=" << codec_specific.toString();
305 return false;
306 }
Omer Osmana2587da2022-05-01 03:54:11 +0000307 std::optional<OpusConfiguration> opus_data =
308 codec_specific.get<CodecConfiguration::CodecSpecific::opusConfig>();
Josh Wu20bac522021-12-29 23:52:39 -0800309
Omer Osmana2587da2022-05-01 03:54:11 +0000310 if (opus_data.has_value() &&
311 ContainedInVector(kDefaultOffloadOpusCapability.samplingFrequencyHz,
312 opus_data->samplingFrequencyHz) &&
313 ContainedInVector(kDefaultOffloadOpusCapability.frameDurationUs,
314 opus_data->frameDurationUs) &&
315 ContainedInVector(kDefaultOffloadOpusCapability.channelMode,
316 opus_data->channelMode)) {
Josh Wu20bac522021-12-29 23:52:39 -0800317 return true;
318 }
319 LOG(WARNING) << __func__
320 << ": Unsupported CodecSpecific=" << codec_specific.toString();
321 return false;
322}
323
324bool BluetoothAudioCodecs::IsOffloadLeAudioConfigurationValid(
325 const SessionType& session_type, const LeAudioConfiguration&) {
326 if (session_type !=
327 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
328 session_type !=
Josh Wu5d50dc02022-02-15 08:41:53 -0800329 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH &&
330 session_type !=
331 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
Josh Wu20bac522021-12-29 23:52:39 -0800332 return false;
333 }
334 return true;
335}
336
337std::vector<PcmCapabilities>
338BluetoothAudioCodecs::GetSoftwarePcmCapabilities() {
339 return {kDefaultSoftwarePcmCapabilities};
340}
341
342std::vector<CodecCapabilities>
343BluetoothAudioCodecs::GetA2dpOffloadCodecCapabilities(
344 const SessionType& session_type) {
Alice Kuoadcceec2022-03-28 13:28:43 +0800345 if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
346 session_type != SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
Josh Wu20bac522021-12-29 23:52:39 -0800347 return {};
348 }
349 std::vector<CodecCapabilities> offload_a2dp_codec_capabilities =
350 kDefaultOffloadA2dpCodecCapabilities;
351 for (auto& codec_capability : offload_a2dp_codec_capabilities) {
352 switch (codec_capability.codecType) {
353 case CodecType::SBC:
354 codec_capability.capabilities
355 .set<CodecCapabilities::Capabilities::sbcCapabilities>(
356 kDefaultOffloadSbcCapability);
357 break;
358 case CodecType::AAC:
359 codec_capability.capabilities
360 .set<CodecCapabilities::Capabilities::aacCapabilities>(
361 kDefaultOffloadAacCapability);
362 break;
363 case CodecType::LDAC:
364 codec_capability.capabilities
365 .set<CodecCapabilities::Capabilities::ldacCapabilities>(
366 kDefaultOffloadLdacCapability);
367 break;
368 case CodecType::APTX:
369 codec_capability.capabilities
370 .set<CodecCapabilities::Capabilities::aptxCapabilities>(
371 kDefaultOffloadAptxCapability);
372 break;
373 case CodecType::APTX_HD:
374 codec_capability.capabilities
375 .set<CodecCapabilities::Capabilities::aptxCapabilities>(
376 kDefaultOffloadAptxHdCapability);
377 break;
Omer Osmana2587da2022-05-01 03:54:11 +0000378 case CodecType::OPUS:
Josh Wu20bac522021-12-29 23:52:39 -0800379 codec_capability.capabilities
Omer Osmana2587da2022-05-01 03:54:11 +0000380 .set<CodecCapabilities::Capabilities::opusCapabilities>(
381 kDefaultOffloadOpusCapability);
Josh Wu20bac522021-12-29 23:52:39 -0800382 break;
383 case CodecType::UNKNOWN:
Alice Kuo79c936d2022-01-20 23:10:10 +0800384 case CodecType::VENDOR:
Omer Osmana2587da2022-05-01 03:54:11 +0000385 case CodecType::LC3:
Sagar Vermad13bbb32022-01-08 20:09:04 +0530386 case CodecType::APTX_ADAPTIVE:
Josh Wu20bac522021-12-29 23:52:39 -0800387 break;
388 }
389 }
390 return offload_a2dp_codec_capabilities;
391}
392
393bool BluetoothAudioCodecs::IsSoftwarePcmConfigurationValid(
394 const PcmConfiguration& pcm_config) {
395 if (ContainedInVector(kDefaultSoftwarePcmCapabilities.sampleRateHz,
396 pcm_config.sampleRateHz) &&
397 ContainedInVector(kDefaultSoftwarePcmCapabilities.bitsPerSample,
398 pcm_config.bitsPerSample) &&
399 ContainedInVector(kDefaultSoftwarePcmCapabilities.channelMode,
400 pcm_config.channelMode)
401 // data interval is not checked for now
402 // && pcm_config.dataIntervalUs != 0
403 ) {
404 return true;
405 }
406 LOG(WARNING) << __func__
407 << ": Unsupported CodecSpecific=" << pcm_config.toString();
408 return false;
409}
410
411bool BluetoothAudioCodecs::IsOffloadCodecConfigurationValid(
412 const SessionType& session_type, const CodecConfiguration& codec_config) {
Alice Kuoadcceec2022-03-28 13:28:43 +0800413 if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
414 session_type != SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
Josh Wu20bac522021-12-29 23:52:39 -0800415 LOG(ERROR) << __func__
416 << ": Invalid SessionType=" << toString(session_type);
417 return false;
418 }
419 const CodecConfiguration::CodecSpecific& codec_specific = codec_config.config;
420 switch (codec_config.codecType) {
421 case CodecType::SBC:
422 if (IsOffloadSbcConfigurationValid(codec_specific)) {
423 return true;
424 }
425 break;
426 case CodecType::AAC:
427 if (IsOffloadAacConfigurationValid(codec_specific)) {
428 return true;
429 }
430 break;
431 case CodecType::LDAC:
432 if (IsOffloadLdacConfigurationValid(codec_specific)) {
433 return true;
434 }
435 break;
436 case CodecType::APTX:
437 if (IsOffloadAptxConfigurationValid(codec_specific)) {
438 return true;
439 }
440 break;
441 case CodecType::APTX_HD:
442 if (IsOffloadAptxHdConfigurationValid(codec_specific)) {
443 return true;
444 }
445 break;
Omer Osmana2587da2022-05-01 03:54:11 +0000446 case CodecType::OPUS:
447 if (IsOffloadOpusConfigurationValid(codec_specific)) {
Josh Wu20bac522021-12-29 23:52:39 -0800448 return true;
449 }
450 break;
Sagar Vermad13bbb32022-01-08 20:09:04 +0530451 case CodecType::APTX_ADAPTIVE:
Omer Osmana2587da2022-05-01 03:54:11 +0000452 case CodecType::LC3:
Josh Wu20bac522021-12-29 23:52:39 -0800453 case CodecType::UNKNOWN:
Alice Kuo79c936d2022-01-20 23:10:10 +0800454 case CodecType::VENDOR:
Josh Wu20bac522021-12-29 23:52:39 -0800455 break;
456 }
457 return false;
458}
459
460UnicastCapability composeUnicastLc3Capability(
461 AudioLocation audioLocation, uint8_t deviceCnt, uint8_t channelCount,
462 const Lc3Capabilities& capability) {
463 return {
464 .codecType = CodecType::LC3,
465 .supportedChannel = audioLocation,
466 .deviceCount = deviceCnt,
467 .channelCountPerDevice = channelCount,
468 .leAudioCodecCapabilities =
469 UnicastCapability::LeAudioCodecCapabilities(capability),
470 };
471}
472
473std::vector<LeAudioCodecCapabilitiesSetting>
474BluetoothAudioCodecs::GetLeAudioOffloadCodecCapabilities(
475 const SessionType& session_type) {
476 if (session_type !=
477 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
478 session_type !=
Josh Wu5d50dc02022-02-15 08:41:53 -0800479 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH &&
480 session_type !=
481 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
Josh Wu20bac522021-12-29 23:52:39 -0800482 return std::vector<LeAudioCodecCapabilitiesSetting>(0);
483 }
484
485 if (kDefaultOffloadLeAudioCapabilities.empty()) {
486 for (auto [audioLocation, deviceCnt, channelCount] :
487 supportedDeviceSetting) {
488 for (auto capability : supportedLc3CapabilityList) {
489 UnicastCapability lc3Capability = composeUnicastLc3Capability(
490 audioLocation, deviceCnt, channelCount, capability);
491 UnicastCapability lc3MonoDecodeCapability =
492 composeUnicastLc3Capability(monoAudio, 1, 1, capability);
493
494 // Adds the capability for encode only
495 kDefaultOffloadLeAudioCapabilities.push_back(
496 {.unicastEncodeCapability = lc3Capability,
497 .unicastDecodeCapability = kInvalidUnicastCapability,
498 .broadcastCapability = kInvalidBroadcastCapability});
499
500 // Adds the capability for decode only
501 kDefaultOffloadLeAudioCapabilities.push_back(
502 {.unicastEncodeCapability = kInvalidUnicastCapability,
503 .unicastDecodeCapability = lc3Capability,
504 .broadcastCapability = kInvalidBroadcastCapability});
505
506 // Adds the capability for the case that encode and decode exist at the
507 // same time
508 kDefaultOffloadLeAudioCapabilities.push_back(
509 {.unicastEncodeCapability = lc3Capability,
510 .unicastDecodeCapability = lc3MonoDecodeCapability,
511 .broadcastCapability = kInvalidBroadcastCapability});
512 }
513 }
514 }
515
516 return kDefaultOffloadLeAudioCapabilities;
517}
518
519} // namespace audio
520} // namespace bluetooth
521} // namespace hardware
522} // namespace android
Sagar Vermad13bbb32022-01-08 20:09:04 +0530523} // namespace aidl