Add Bluetooth Audio AIDL utils
Test: manual
Bug: 203490261
Change-Id: Ia299a61e89273ea1c9d132425598975418f57a03
diff --git a/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp
new file mode 100644
index 0000000..91e0238
--- /dev/null
+++ b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp
@@ -0,0 +1,775 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BtAudioNakahara"
+
+#include <aidl/android/hardware/bluetooth/audio/AudioConfiguration.h>
+#include <aidl/android/hardware/bluetooth/audio/BluetoothAudioStatus.h>
+#include <aidl/android/hardware/bluetooth/audio/SessionType.h>
+#include <android-base/logging.h>
+
+#include <functional>
+#include <unordered_map>
+
+#include "../aidl_session/BluetoothAudioSession.h"
+#include "../aidl_session/BluetoothAudioSessionControl.h"
+#include "HidlToAidlMiddleware_2_0.h"
+#include "HidlToAidlMiddleware_2_1.h"
+#include "HidlToAidlMiddleware_2_2.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+using HidlStatus = ::android::hardware::bluetooth::audio::V2_0::Status;
+using PcmConfig_2_0 =
+ ::android::hardware::bluetooth::audio::V2_0::PcmParameters;
+using SampleRate_2_0 = ::android::hardware::bluetooth::audio::V2_0::SampleRate;
+using ChannelMode_2_0 =
+ ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
+using BitsPerSample_2_0 =
+ ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
+using CodecConfig_2_0 =
+ ::android::hardware::bluetooth::audio::V2_0::CodecConfiguration;
+using CodecType_2_0 = ::android::hardware::bluetooth::audio::V2_0::CodecType;
+using SbcConfig_2_0 =
+ ::android::hardware::bluetooth::audio::V2_0::SbcParameters;
+using AacConfig_2_0 =
+ ::android::hardware::bluetooth::audio::V2_0::AacParameters;
+using LdacConfig_2_0 =
+ ::android::hardware::bluetooth::audio::V2_0::LdacParameters;
+using AptxConfig_2_0 =
+ ::android::hardware::bluetooth::audio::V2_0::AptxParameters;
+using SbcAllocMethod_2_0 =
+ ::android::hardware::bluetooth::audio::V2_0::SbcAllocMethod;
+using SbcBlockLength_2_0 =
+ ::android::hardware::bluetooth::audio::V2_0::SbcBlockLength;
+using SbcChannelMode_2_0 =
+ ::android::hardware::bluetooth::audio::V2_0::SbcChannelMode;
+using SbcNumSubbands_2_0 =
+ ::android::hardware::bluetooth::audio::V2_0::SbcNumSubbands;
+using AacObjectType_2_0 =
+ ::android::hardware::bluetooth::audio::V2_0::AacObjectType;
+using AacVarBitRate_2_0 =
+ ::android::hardware::bluetooth::audio::V2_0::AacVariableBitRate;
+using LdacChannelMode_2_0 =
+ ::android::hardware::bluetooth::audio::V2_0::LdacChannelMode;
+using LdacQualityIndex_2_0 =
+ ::android::hardware::bluetooth::audio::V2_0::LdacQualityIndex;
+
+using PcmConfig_2_1 =
+ ::android::hardware::bluetooth::audio::V2_1::PcmParameters;
+using SampleRate_2_1 = ::android::hardware::bluetooth::audio::V2_1::SampleRate;
+using Lc3CodecConfig_2_1 =
+ ::android::hardware::bluetooth::audio::V2_1::Lc3CodecConfiguration;
+using Lc3Config_2_1 =
+ ::android::hardware::bluetooth::audio::V2_1::Lc3Parameters;
+using Lc3FrameDuration_2_1 =
+ ::android::hardware::bluetooth::audio::V2_1::Lc3FrameDuration;
+
+using LeAudioConfig_2_2 =
+ ::android::hardware::bluetooth::audio::V2_2::LeAudioConfiguration;
+using LeAudioMode_2_2 =
+ ::android::hardware::bluetooth::audio::V2_2::LeAudioMode;
+
+std::mutex legacy_callback_lock;
+std::unordered_map<
+ SessionType,
+ std::unordered_map<uint16_t, std::shared_ptr<PortStatusCallbacks_2_2>>>
+ legacy_callback_table;
+
+const static std::unordered_map<SessionType_2_0, SessionType>
+ session_type_2_0_to_aidl_map{
+ {SessionType_2_0::A2DP_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH},
+ {SessionType_2_0::A2DP_HARDWARE_OFFLOAD_DATAPATH,
+ SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH},
+ {SessionType_2_0::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH},
+ };
+
+const static std::unordered_map<SessionType_2_1, SessionType>
+ session_type_2_1_to_aidl_map{
+ {SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH},
+ {SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH,
+ SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH},
+ {SessionType_2_1::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH},
+ {SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH},
+ {SessionType_2_1::LE_AUDIO_SOFTWARE_DECODED_DATAPATH,
+ SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH},
+ {SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH},
+ {SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH},
+ };
+
+const static std::unordered_map<int32_t, SampleRate_2_0>
+ sample_rate_to_hidl_2_0_map{
+ {44100, SampleRate_2_0::RATE_44100},
+ {48000, SampleRate_2_0::RATE_48000},
+ {88200, SampleRate_2_0::RATE_88200},
+ {96000, SampleRate_2_0::RATE_96000},
+ {176400, SampleRate_2_0::RATE_176400},
+ {192000, SampleRate_2_0::RATE_192000},
+ {16000, SampleRate_2_0::RATE_16000},
+ {24000, SampleRate_2_0::RATE_24000},
+ };
+
+const static std::unordered_map<int32_t, SampleRate_2_1>
+ sample_rate_to_hidl_2_1_map{
+ {44100, SampleRate_2_1::RATE_44100},
+ {48000, SampleRate_2_1::RATE_48000},
+ {88200, SampleRate_2_1::RATE_88200},
+ {96000, SampleRate_2_1::RATE_96000},
+ {176400, SampleRate_2_1::RATE_176400},
+ {192000, SampleRate_2_1::RATE_192000},
+ {16000, SampleRate_2_1::RATE_16000},
+ {24000, SampleRate_2_1::RATE_24000},
+ {8000, SampleRate_2_1::RATE_8000},
+ {32000, SampleRate_2_1::RATE_32000},
+ };
+
+const static std::unordered_map<CodecType, CodecType_2_0>
+ codec_type_to_hidl_2_0_map{
+ {CodecType::UNKNOWN, CodecType_2_0::UNKNOWN},
+ {CodecType::SBC, CodecType_2_0::SBC},
+ {CodecType::AAC, CodecType_2_0::AAC},
+ {CodecType::APTX, CodecType_2_0::APTX},
+ {CodecType::APTX_HD, CodecType_2_0::APTX_HD},
+ {CodecType::LDAC, CodecType_2_0::LDAC},
+ {CodecType::LC3, CodecType_2_0::UNKNOWN},
+ };
+
+const static std::unordered_map<SbcChannelMode, SbcChannelMode_2_0>
+ sbc_channel_mode_to_hidl_2_0_map{
+ {SbcChannelMode::UNKNOWN, SbcChannelMode_2_0::UNKNOWN},
+ {SbcChannelMode::JOINT_STEREO, SbcChannelMode_2_0::JOINT_STEREO},
+ {SbcChannelMode::STEREO, SbcChannelMode_2_0::STEREO},
+ {SbcChannelMode::DUAL, SbcChannelMode_2_0::DUAL},
+ {SbcChannelMode::MONO, SbcChannelMode_2_0::MONO},
+ };
+
+const static std::unordered_map<int8_t, SbcBlockLength_2_0>
+ sbc_block_length_to_hidl_map{
+ {4, SbcBlockLength_2_0::BLOCKS_4},
+ {8, SbcBlockLength_2_0::BLOCKS_8},
+ {12, SbcBlockLength_2_0::BLOCKS_12},
+ {16, SbcBlockLength_2_0::BLOCKS_16},
+ };
+
+const static std::unordered_map<int8_t, SbcNumSubbands_2_0>
+ sbc_subbands_to_hidl_map{
+ {4, SbcNumSubbands_2_0::SUBBAND_4},
+ {8, SbcNumSubbands_2_0::SUBBAND_8},
+ };
+
+const static std::unordered_map<SbcAllocMethod, SbcAllocMethod_2_0>
+ sbc_alloc_method_to_hidl_map{
+ {SbcAllocMethod::ALLOC_MD_S, SbcAllocMethod_2_0::ALLOC_MD_S},
+ {SbcAllocMethod::ALLOC_MD_L, SbcAllocMethod_2_0::ALLOC_MD_L},
+ };
+
+const static std::unordered_map<AacObjectType, AacObjectType_2_0>
+ aac_object_type_to_hidl_map{
+ {AacObjectType::MPEG2_LC, AacObjectType_2_0::MPEG2_LC},
+ {AacObjectType::MPEG4_LC, AacObjectType_2_0::MPEG4_LC},
+ {AacObjectType::MPEG4_LTP, AacObjectType_2_0::MPEG4_LTP},
+ {AacObjectType::MPEG4_SCALABLE, AacObjectType_2_0::MPEG4_SCALABLE},
+ };
+
+const static std::unordered_map<LdacChannelMode, LdacChannelMode_2_0>
+ ldac_channel_mode_to_hidl_map{
+ {LdacChannelMode::UNKNOWN, LdacChannelMode_2_0::UNKNOWN},
+ {LdacChannelMode::STEREO, LdacChannelMode_2_0::STEREO},
+ {LdacChannelMode::DUAL, LdacChannelMode_2_0::DUAL},
+ {LdacChannelMode::MONO, LdacChannelMode_2_0::MONO},
+ };
+
+const static std::unordered_map<LdacQualityIndex, LdacQualityIndex_2_0>
+ ldac_qindex_to_hidl_map{
+ {LdacQualityIndex::HIGH, LdacQualityIndex_2_0::QUALITY_HIGH},
+ {LdacQualityIndex::MID, LdacQualityIndex_2_0::QUALITY_MID},
+ {LdacQualityIndex::LOW, LdacQualityIndex_2_0::QUALITY_LOW},
+ {LdacQualityIndex::ABR, LdacQualityIndex_2_0::QUALITY_ABR},
+ };
+
+const static std::unordered_map<LeAudioMode, LeAudioMode_2_2>
+ leaudio_mode_to_hidl_map{
+ {LeAudioMode::UNKNOWN, LeAudioMode_2_2::UNKNOWN},
+ {LeAudioMode::UNICAST, LeAudioMode_2_2::UNICAST},
+ {LeAudioMode::BROADCAST, LeAudioMode_2_2::BROADCAST},
+ };
+
+inline SessionType from_session_type_2_0(
+ const SessionType_2_0& session_type_hidl) {
+ auto it = session_type_2_0_to_aidl_map.find(session_type_hidl);
+ if (it != session_type_2_0_to_aidl_map.end()) return it->second;
+ return SessionType::UNKNOWN;
+}
+
+inline SessionType from_session_type_2_1(
+ const SessionType_2_1& session_type_hidl) {
+ auto it = session_type_2_1_to_aidl_map.find(session_type_hidl);
+ if (it != session_type_2_1_to_aidl_map.end()) return it->second;
+ return SessionType::UNKNOWN;
+}
+
+inline HidlStatus to_hidl_status(const BluetoothAudioStatus& status) {
+ switch (status) {
+ case BluetoothAudioStatus::SUCCESS:
+ return HidlStatus::SUCCESS;
+ case BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION:
+ return HidlStatus::UNSUPPORTED_CODEC_CONFIGURATION;
+ default:
+ return HidlStatus::FAILURE;
+ }
+}
+
+inline SampleRate_2_0 to_hidl_sample_rate_2_0(const int32_t sample_rate_hz) {
+ auto it = sample_rate_to_hidl_2_0_map.find(sample_rate_hz);
+ if (it != sample_rate_to_hidl_2_0_map.end()) return it->second;
+ return SampleRate_2_0::RATE_UNKNOWN;
+}
+
+inline SampleRate_2_1 to_hidl_sample_rate_2_1(const int32_t sample_rate_hz) {
+ auto it = sample_rate_to_hidl_2_1_map.find(sample_rate_hz);
+ if (it != sample_rate_to_hidl_2_1_map.end()) return it->second;
+ return SampleRate_2_1::RATE_UNKNOWN;
+}
+
+inline BitsPerSample_2_0 to_hidl_bits_per_sample(const int8_t bit_per_sample) {
+ switch (bit_per_sample) {
+ case 16:
+ return BitsPerSample_2_0::BITS_16;
+ case 24:
+ return BitsPerSample_2_0::BITS_24;
+ case 32:
+ return BitsPerSample_2_0::BITS_32;
+ default:
+ return BitsPerSample_2_0::BITS_UNKNOWN;
+ }
+}
+
+inline ChannelMode_2_0 to_hidl_channel_mode(const ChannelMode channel_mode) {
+ switch (channel_mode) {
+ case ChannelMode::MONO:
+ return ChannelMode_2_0::MONO;
+ case ChannelMode::STEREO:
+ return ChannelMode_2_0::STEREO;
+ default:
+ return ChannelMode_2_0::UNKNOWN;
+ }
+}
+
+inline PcmConfig_2_0 to_hidl_pcm_config_2_0(
+ const PcmConfiguration& pcm_config) {
+ PcmConfig_2_0 hidl_pcm_config;
+ hidl_pcm_config.sampleRate = to_hidl_sample_rate_2_0(pcm_config.sampleRateHz);
+ hidl_pcm_config.channelMode = to_hidl_channel_mode(pcm_config.channelMode);
+ hidl_pcm_config.bitsPerSample =
+ to_hidl_bits_per_sample(pcm_config.bitsPerSample);
+ return hidl_pcm_config;
+}
+
+inline CodecType_2_0 to_hidl_codec_type_2_0(const CodecType codec_type) {
+ auto it = codec_type_to_hidl_2_0_map.find(codec_type);
+ if (it != codec_type_to_hidl_2_0_map.end()) return it->second;
+ return CodecType_2_0::UNKNOWN;
+}
+
+inline SbcConfig_2_0 to_hidl_sbc_config(const SbcConfiguration sbc_config) {
+ SbcConfig_2_0 hidl_sbc_config;
+ hidl_sbc_config.minBitpool = sbc_config.minBitpool;
+ hidl_sbc_config.maxBitpool = sbc_config.maxBitpool;
+ hidl_sbc_config.sampleRate = to_hidl_sample_rate_2_0(sbc_config.sampleRateHz);
+ hidl_sbc_config.bitsPerSample =
+ to_hidl_bits_per_sample(sbc_config.bitsPerSample);
+ if (sbc_channel_mode_to_hidl_2_0_map.find(sbc_config.channelMode) !=
+ sbc_channel_mode_to_hidl_2_0_map.end()) {
+ hidl_sbc_config.channelMode =
+ sbc_channel_mode_to_hidl_2_0_map.at(sbc_config.channelMode);
+ }
+ if (sbc_block_length_to_hidl_map.find(sbc_config.blockLength) !=
+ sbc_block_length_to_hidl_map.end()) {
+ hidl_sbc_config.blockLength =
+ sbc_block_length_to_hidl_map.at(sbc_config.blockLength);
+ }
+ if (sbc_subbands_to_hidl_map.find(sbc_config.numSubbands) !=
+ sbc_subbands_to_hidl_map.end()) {
+ hidl_sbc_config.numSubbands =
+ sbc_subbands_to_hidl_map.at(sbc_config.numSubbands);
+ }
+ if (sbc_alloc_method_to_hidl_map.find(sbc_config.allocMethod) !=
+ sbc_alloc_method_to_hidl_map.end()) {
+ hidl_sbc_config.allocMethod =
+ sbc_alloc_method_to_hidl_map.at(sbc_config.allocMethod);
+ }
+ return hidl_sbc_config;
+}
+
+inline AacConfig_2_0 to_hidl_aac_config(const AacConfiguration aac_config) {
+ AacConfig_2_0 hidl_aac_config;
+ hidl_aac_config.sampleRate = to_hidl_sample_rate_2_0(aac_config.sampleRateHz);
+ hidl_aac_config.bitsPerSample =
+ to_hidl_bits_per_sample(aac_config.bitsPerSample);
+ hidl_aac_config.channelMode = to_hidl_channel_mode(aac_config.channelMode);
+ if (aac_object_type_to_hidl_map.find(aac_config.objectType) !=
+ aac_object_type_to_hidl_map.end()) {
+ hidl_aac_config.objectType =
+ aac_object_type_to_hidl_map.at(aac_config.objectType);
+ }
+ hidl_aac_config.variableBitRateEnabled = aac_config.variableBitRateEnabled
+ ? AacVarBitRate_2_0::ENABLED
+ : AacVarBitRate_2_0::DISABLED;
+ return hidl_aac_config;
+}
+
+inline LdacConfig_2_0 to_hidl_ldac_config(const LdacConfiguration ldac_config) {
+ LdacConfig_2_0 hidl_ldac_config;
+ hidl_ldac_config.sampleRate =
+ to_hidl_sample_rate_2_0(ldac_config.sampleRateHz);
+ hidl_ldac_config.bitsPerSample =
+ to_hidl_bits_per_sample(ldac_config.bitsPerSample);
+ if (ldac_channel_mode_to_hidl_map.find(ldac_config.channelMode) !=
+ ldac_channel_mode_to_hidl_map.end()) {
+ hidl_ldac_config.channelMode =
+ ldac_channel_mode_to_hidl_map.at(ldac_config.channelMode);
+ }
+ if (ldac_qindex_to_hidl_map.find(ldac_config.qualityIndex) !=
+ ldac_qindex_to_hidl_map.end()) {
+ hidl_ldac_config.qualityIndex =
+ ldac_qindex_to_hidl_map.at(ldac_config.qualityIndex);
+ }
+ return hidl_ldac_config;
+}
+
+inline AptxConfig_2_0 to_hidl_aptx_config(const AptxConfiguration aptx_config) {
+ AptxConfig_2_0 hidl_aptx_config;
+ hidl_aptx_config.sampleRate =
+ to_hidl_sample_rate_2_0(aptx_config.sampleRateHz);
+ hidl_aptx_config.bitsPerSample =
+ to_hidl_bits_per_sample(aptx_config.bitsPerSample);
+ hidl_aptx_config.channelMode = to_hidl_channel_mode(aptx_config.channelMode);
+ return hidl_aptx_config;
+}
+
+inline CodecConfig_2_0 to_hidl_codec_config_2_0(
+ const CodecConfiguration& codec_config) {
+ CodecConfig_2_0 hidl_codec_config;
+ hidl_codec_config.codecType = to_hidl_codec_type_2_0(codec_config.codecType);
+ hidl_codec_config.encodedAudioBitrate =
+ static_cast<uint32_t>(codec_config.encodedAudioBitrate);
+ hidl_codec_config.peerMtu = static_cast<uint32_t>(codec_config.peerMtu);
+ hidl_codec_config.isScmstEnabled = codec_config.isScmstEnabled;
+ switch (codec_config.config.getTag()) {
+ case CodecConfiguration::CodecSpecific::sbcConfig:
+ hidl_codec_config.config.sbcConfig(to_hidl_sbc_config(
+ codec_config.config
+ .get<CodecConfiguration::CodecSpecific::sbcConfig>()));
+ break;
+ case CodecConfiguration::CodecSpecific::aacConfig:
+ hidl_codec_config.config.aacConfig(to_hidl_aac_config(
+ codec_config.config
+ .get<CodecConfiguration::CodecSpecific::aacConfig>()));
+ break;
+ case CodecConfiguration::CodecSpecific::ldacConfig:
+ hidl_codec_config.config.ldacConfig(to_hidl_ldac_config(
+ codec_config.config
+ .get<CodecConfiguration::CodecSpecific::ldacConfig>()));
+ break;
+ case CodecConfiguration::CodecSpecific::aptxConfig:
+ hidl_codec_config.config.aptxConfig(to_hidl_aptx_config(
+ codec_config.config
+ .get<CodecConfiguration::CodecSpecific::aptxConfig>()));
+ break;
+ default:
+ break;
+ }
+ return hidl_codec_config;
+}
+
+inline AudioConfig_2_0 to_hidl_audio_config_2_0(
+ const AudioConfiguration& audio_config) {
+ AudioConfig_2_0 hidl_audio_config;
+ if (audio_config.getTag() == AudioConfiguration::pcmConfig) {
+ hidl_audio_config.pcmConfig(to_hidl_pcm_config_2_0(
+ audio_config.get<AudioConfiguration::pcmConfig>()));
+ } else if (audio_config.getTag() == AudioConfiguration::a2dpConfig) {
+ hidl_audio_config.codecConfig(to_hidl_codec_config_2_0(
+ audio_config.get<AudioConfiguration::a2dpConfig>()));
+ }
+ return hidl_audio_config;
+}
+
+inline PcmConfig_2_1 to_hidl_pcm_config_2_1(
+ const PcmConfiguration& pcm_config) {
+ PcmConfig_2_1 hidl_pcm_config;
+ hidl_pcm_config.sampleRate = to_hidl_sample_rate_2_1(pcm_config.sampleRateHz);
+ hidl_pcm_config.channelMode = to_hidl_channel_mode(pcm_config.channelMode);
+ hidl_pcm_config.bitsPerSample =
+ to_hidl_bits_per_sample(pcm_config.bitsPerSample);
+ hidl_pcm_config.dataIntervalUs =
+ static_cast<uint32_t>(pcm_config.dataIntervalUs);
+ return hidl_pcm_config;
+}
+
+inline Lc3Config_2_1 to_hidl_lc3_config_2_1(
+ const Lc3Configuration& lc3_config) {
+ Lc3Config_2_1 hidl_lc3_config;
+ hidl_lc3_config.pcmBitDepth = to_hidl_bits_per_sample(lc3_config.pcmBitDepth);
+ hidl_lc3_config.samplingFrequency =
+ to_hidl_sample_rate_2_1(lc3_config.samplingFrequencyHz);
+ if (lc3_config.samplingFrequencyHz == 10000)
+ hidl_lc3_config.frameDuration = Lc3FrameDuration_2_1::DURATION_10000US;
+ else if (lc3_config.samplingFrequencyHz == 7500)
+ hidl_lc3_config.frameDuration = Lc3FrameDuration_2_1::DURATION_7500US;
+ hidl_lc3_config.octetsPerFrame =
+ static_cast<uint32_t>(lc3_config.octetsPerFrame);
+ hidl_lc3_config.blocksPerSdu = static_cast<uint32_t>(lc3_config.blocksPerSdu);
+ return hidl_lc3_config;
+}
+
+inline Lc3CodecConfig_2_1 to_hidl_leaudio_config_2_1(
+ const LeAudioConfiguration& leaudio_config) {
+ auto& unicast_config =
+ leaudio_config.modeConfig
+ .get<LeAudioConfiguration::LeAudioModeConfig::unicastConfig>();
+
+ auto& le_codec_config = unicast_config.leAudioCodecConfig
+ .get<LeAudioCodecConfiguration::lc3Config>();
+
+ Lc3CodecConfig_2_1 hidl_lc3_codec_config;
+ hidl_lc3_codec_config.lc3Config = to_hidl_lc3_config_2_1(le_codec_config);
+
+ hidl_lc3_codec_config.audioChannelAllocation =
+ unicast_config.streamMap.size();
+
+ return hidl_lc3_codec_config;
+}
+
+inline LeAudioConfig_2_2 to_hidl_leaudio_config_2_2(
+ const LeAudioConfiguration& leaudio_config) {
+ LeAudioConfig_2_2 hidl_leaudio_config;
+ if (leaudio_mode_to_hidl_map.find(leaudio_config.mode) !=
+ leaudio_mode_to_hidl_map.end()) {
+ hidl_leaudio_config.mode = leaudio_mode_to_hidl_map.at(leaudio_config.mode);
+ }
+
+ if (leaudio_config.modeConfig.getTag() ==
+ LeAudioConfiguration::LeAudioModeConfig::unicastConfig) {
+ auto& unicast_config =
+ leaudio_config.modeConfig
+ .get<LeAudioConfiguration::LeAudioModeConfig::unicastConfig>();
+ ::android::hardware::bluetooth::audio::V2_2::UnicastConfig
+ hidl_unicast_config;
+ hidl_unicast_config.peerDelay =
+ static_cast<uint32_t>(unicast_config.peerDelay);
+
+ auto& lc3_config = unicast_config.leAudioCodecConfig
+ .get<LeAudioCodecConfiguration::lc3Config>();
+ hidl_unicast_config.lc3Config = to_hidl_lc3_config_2_1(lc3_config);
+
+ hidl_unicast_config.streamMap.resize(unicast_config.streamMap.size());
+ for (int i = 0; i < unicast_config.streamMap.size(); i++) {
+ hidl_unicast_config.streamMap[i].audioChannelAllocation =
+ static_cast<uint32_t>(
+ unicast_config.streamMap[i].audioChannelAllocation);
+ hidl_unicast_config.streamMap[i].streamHandle =
+ static_cast<uint16_t>(unicast_config.streamMap[i].streamHandle);
+ }
+ } else if (leaudio_config.modeConfig.getTag() ==
+ LeAudioConfiguration::LeAudioModeConfig::broadcastConfig) {
+ auto bcast_config =
+ leaudio_config.modeConfig
+ .get<LeAudioConfiguration::LeAudioModeConfig::broadcastConfig>();
+ ::android::hardware::bluetooth::audio::V2_2::BroadcastConfig
+ hidl_bcast_config;
+ hidl_bcast_config.streamMap.resize(bcast_config.streamMap.size());
+ for (int i = 0; i < bcast_config.streamMap.size(); i++) {
+ hidl_bcast_config.streamMap[i].audioChannelAllocation =
+ static_cast<uint32_t>(
+ bcast_config.streamMap[i].audioChannelAllocation);
+ hidl_bcast_config.streamMap[i].streamHandle =
+ static_cast<uint16_t>(bcast_config.streamMap[i].streamHandle);
+ hidl_bcast_config.streamMap[i].lc3Config = to_hidl_lc3_config_2_1(
+ bcast_config.streamMap[i]
+ .leAudioCodecConfig.get<LeAudioCodecConfiguration::lc3Config>());
+ }
+ }
+ return hidl_leaudio_config;
+}
+
+inline AudioConfig_2_1 to_hidl_audio_config_2_1(
+ const AudioConfiguration& audio_config) {
+ AudioConfig_2_1 hidl_audio_config;
+ switch (audio_config.getTag()) {
+ case AudioConfiguration::pcmConfig:
+ hidl_audio_config.pcmConfig(to_hidl_pcm_config_2_1(
+ audio_config.get<AudioConfiguration::pcmConfig>()));
+ break;
+ case AudioConfiguration::a2dpConfig:
+ hidl_audio_config.codecConfig(to_hidl_codec_config_2_0(
+ audio_config.get<AudioConfiguration::a2dpConfig>()));
+ break;
+ case AudioConfiguration::leAudioConfig:
+ hidl_audio_config.leAudioCodecConfig(to_hidl_leaudio_config_2_1(
+ audio_config.get<AudioConfiguration::leAudioConfig>()));
+ break;
+ }
+ return hidl_audio_config;
+}
+
+inline AudioConfig_2_2 to_hidl_audio_config_2_2(
+ const AudioConfiguration& audio_config) {
+ AudioConfig_2_2 hidl_audio_config;
+ switch (audio_config.getTag()) {
+ case AudioConfiguration::pcmConfig:
+ hidl_audio_config.pcmConfig(to_hidl_pcm_config_2_1(
+ audio_config.get<AudioConfiguration::pcmConfig>()));
+ break;
+ case AudioConfiguration::a2dpConfig:
+ hidl_audio_config.codecConfig(to_hidl_codec_config_2_0(
+ audio_config.get<AudioConfiguration::a2dpConfig>()));
+ break;
+ case AudioConfiguration::leAudioConfig:
+ hidl_audio_config.leAudioConfig(to_hidl_leaudio_config_2_2(
+ audio_config.get<AudioConfiguration::leAudioConfig>()));
+ break;
+ }
+ return hidl_audio_config;
+}
+
+/***
+ *
+ * 2.0
+ *
+ ***/
+
+bool HidlToAidlMiddleware_2_0::IsSessionReady(
+ const SessionType_2_0& session_type) {
+ return BluetoothAudioSessionControl::IsSessionReady(
+ from_session_type_2_0(session_type));
+}
+
+uint16_t HidlToAidlMiddleware_2_0::RegisterControlResultCback(
+ const SessionType_2_0& session_type,
+ const PortStatusCallbacks_2_0& cbacks) {
+ PortStatusCallbacks_2_2 callback_2_2{
+ .control_result_cb_ = cbacks.control_result_cb_,
+ .session_changed_cb_ = cbacks.session_changed_cb_,
+ };
+ return HidlToAidlMiddleware_2_2::RegisterControlResultCback(
+ static_cast<SessionType_2_1>(session_type), callback_2_2);
+}
+
+void HidlToAidlMiddleware_2_0::UnregisterControlResultCback(
+ const SessionType_2_0& session_type, uint16_t cookie) {
+ HidlToAidlMiddleware_2_2::UnregisterControlResultCback(
+ static_cast<SessionType_2_1>(session_type), cookie);
+}
+
+const AudioConfig_2_0 HidlToAidlMiddleware_2_0::GetAudioConfig(
+ const SessionType_2_0& session_type) {
+ return to_hidl_audio_config_2_0(BluetoothAudioSessionControl::GetAudioConfig(
+ from_session_type_2_0(session_type)));
+}
+
+bool HidlToAidlMiddleware_2_0::StartStream(
+ const SessionType_2_0& session_type) {
+ return BluetoothAudioSessionControl::StartStream(
+ from_session_type_2_0(session_type));
+}
+
+void HidlToAidlMiddleware_2_0::StopStream(const SessionType_2_0& session_type) {
+ return BluetoothAudioSessionControl::StopStream(
+ from_session_type_2_0(session_type));
+}
+
+bool HidlToAidlMiddleware_2_0::SuspendStream(
+ const SessionType_2_0& session_type) {
+ return BluetoothAudioSessionControl::SuspendStream(
+ from_session_type_2_0(session_type));
+}
+
+bool HidlToAidlMiddleware_2_0::GetPresentationPosition(
+ const SessionType_2_0& session_type, uint64_t* remote_delay_report_ns,
+ uint64_t* total_bytes_readed, timespec* data_position) {
+ PresentationPosition presentation_position;
+ auto ret_val = BluetoothAudioSessionControl::GetPresentationPosition(
+ from_session_type_2_0(session_type), presentation_position);
+ if (remote_delay_report_ns)
+ *remote_delay_report_ns = presentation_position.remoteDeviceAudioDelayNanos;
+ if (total_bytes_readed)
+ *total_bytes_readed = presentation_position.transmittedOctets;
+ if (data_position)
+ *data_position = {
+ .tv_sec = static_cast<__kernel_old_time_t>(
+ presentation_position.transmittedOctetsTimestamp.tvSec),
+ .tv_nsec = static_cast<long>(
+ presentation_position.transmittedOctetsTimestamp.tvNSec)};
+ return ret_val;
+}
+
+void HidlToAidlMiddleware_2_0::UpdateTracksMetadata(
+ const SessionType_2_0& session_type,
+ const struct source_metadata* source_metadata) {
+ return BluetoothAudioSessionControl::UpdateSourceMetadata(
+ from_session_type_2_0(session_type), *source_metadata);
+}
+
+size_t HidlToAidlMiddleware_2_0::OutWritePcmData(
+ const SessionType_2_0& session_type, const void* buffer, size_t bytes) {
+ return BluetoothAudioSessionControl::OutWritePcmData(
+ from_session_type_2_0(session_type), buffer, bytes);
+}
+
+bool HidlToAidlMiddleware_2_0::IsAidlAvailable() {
+ return BluetoothAudioSession::IsAidlAvailable();
+}
+
+/***
+ *
+ * 2.1
+ *
+ ***/
+
+const AudioConfig_2_1 HidlToAidlMiddleware_2_1::GetAudioConfig(
+ const SessionType_2_1& session_type) {
+ return to_hidl_audio_config_2_1(BluetoothAudioSessionControl::GetAudioConfig(
+ from_session_type_2_1(session_type)));
+}
+
+/***
+ *
+ * 2.2
+ *
+ ***/
+
+bool HidlToAidlMiddleware_2_2::IsSessionReady(
+ const SessionType_2_1& session_type) {
+ return BluetoothAudioSessionControl::IsSessionReady(
+ from_session_type_2_1(session_type));
+}
+
+uint16_t HidlToAidlMiddleware_2_2::RegisterControlResultCback(
+ const SessionType_2_1& session_type,
+ const PortStatusCallbacks_2_2& cbacks) {
+ LOG(INFO) << __func__ << ": " << toString(session_type);
+ auto aidl_session_type = from_session_type_2_1(session_type);
+ // Pass the exact reference to the lambda
+ auto& session_legacy_callback_table =
+ legacy_callback_table[aidl_session_type];
+ PortStatusCallbacks aidl_callbacks{};
+ if (cbacks.control_result_cb_) {
+ aidl_callbacks.control_result_cb_ =
+ [&session_legacy_callback_table](uint16_t cookie, bool start_resp,
+ const BluetoothAudioStatus& status) {
+ if (session_legacy_callback_table.find(cookie) ==
+ session_legacy_callback_table.end()) {
+ LOG(ERROR) << __func__ << ": Unknown callback invoked!";
+ return;
+ }
+ auto& cback = session_legacy_callback_table[cookie];
+ cback->control_result_cb_(cookie, start_resp, to_hidl_status(status));
+ };
+ }
+ if (cbacks.session_changed_cb_) {
+ aidl_callbacks.session_changed_cb_ =
+ [&session_legacy_callback_table](uint16_t cookie) {
+ if (session_legacy_callback_table.find(cookie) ==
+ session_legacy_callback_table.end()) {
+ LOG(ERROR) << __func__ << ": Unknown callback invoked!";
+ return;
+ }
+ auto& cback = session_legacy_callback_table[cookie];
+ cback->session_changed_cb_(cookie);
+ };
+ };
+ if (cbacks.audio_configuration_changed_cb_) {
+ aidl_callbacks.audio_configuration_changed_cb_ =
+ [&session_legacy_callback_table](uint16_t cookie) {
+ if (session_legacy_callback_table.find(cookie) ==
+ session_legacy_callback_table.end()) {
+ LOG(ERROR) << __func__ << ": Unknown callback invoked!";
+ return;
+ }
+ auto& cback = session_legacy_callback_table[cookie];
+ cback->audio_configuration_changed_cb_(cookie);
+ };
+ };
+ auto cookie = BluetoothAudioSessionControl::RegisterControlResultCback(
+ aidl_session_type, aidl_callbacks);
+ {
+ std::lock_guard<std::mutex> guard(legacy_callback_lock);
+ session_legacy_callback_table[cookie] =
+ std::make_shared<PortStatusCallbacks_2_2>(cbacks);
+ }
+ return cookie;
+}
+
+void HidlToAidlMiddleware_2_2::UnregisterControlResultCback(
+ const SessionType_2_1& session_type, uint16_t cookie) {
+ LOG(INFO) << __func__ << ": " << toString(session_type);
+ auto aidl_session_type = from_session_type_2_1(session_type);
+ BluetoothAudioSessionControl::UnregisterControlResultCback(aidl_session_type,
+ cookie);
+ auto& session_callback_table = legacy_callback_table[aidl_session_type];
+ if (session_callback_table.find(cookie) != session_callback_table.end()) {
+ std::lock_guard<std::mutex> guard(legacy_callback_lock);
+ session_callback_table.erase(cookie);
+ }
+}
+
+const AudioConfig_2_2 HidlToAidlMiddleware_2_2::GetAudioConfig(
+ const SessionType_2_1& session_type) {
+ return to_hidl_audio_config_2_2(BluetoothAudioSessionControl::GetAudioConfig(
+ from_session_type_2_1(session_type)));
+}
+
+bool HidlToAidlMiddleware_2_2::StartStream(
+ const SessionType_2_1& session_type) {
+ return BluetoothAudioSessionControl::StartStream(
+ from_session_type_2_1(session_type));
+}
+
+bool HidlToAidlMiddleware_2_2::SuspendStream(
+ const SessionType_2_1& session_type) {
+ return BluetoothAudioSessionControl::SuspendStream(
+ from_session_type_2_1(session_type));
+}
+
+void HidlToAidlMiddleware_2_2::StopStream(const SessionType_2_1& session_type) {
+ return BluetoothAudioSessionControl::StopStream(
+ from_session_type_2_1(session_type));
+}
+
+void HidlToAidlMiddleware_2_2::UpdateSinkMetadata(
+ const SessionType_2_1& session_type,
+ const struct sink_metadata* sink_metadata) {
+ return BluetoothAudioSessionControl::UpdateSinkMetadata(
+ from_session_type_2_1(session_type), *sink_metadata);
+}
+
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
+} // namespace aidl