From 20bac52a5b9b18789ba4ccad986cdf3effd0bd86 Mon Sep 17 00:00:00 2001 From: Josh Wu Date: Wed, 29 Dec 2021 23:52:39 -0800 Subject: Add Bluetooth Audio AIDL utils Test: manual Bug: 203490261 Change-Id: Ia299a61e89273ea1c9d132425598975418f57a03 --- .../utils/aidl_session/HidlToAidlMiddleware.cpp | 775 +++++++++++++++++++++ 1 file changed, 775 insertions(+) create mode 100644 bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp (limited to 'bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp') diff --git a/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp new file mode 100644 index 0000000000..91e0238783 --- /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 +#include +#include +#include + +#include +#include + +#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>> + legacy_callback_table; + +const static std::unordered_map + 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 + 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 + 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 + 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 + 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 + 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 + 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 + sbc_subbands_to_hidl_map{ + {4, SbcNumSubbands_2_0::SUBBAND_4}, + {8, SbcNumSubbands_2_0::SUBBAND_8}, + }; + +const static std::unordered_map + 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 + 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 + 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 + 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 + 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(codec_config.encodedAudioBitrate); + hidl_codec_config.peerMtu = static_cast(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())); + break; + case CodecConfiguration::CodecSpecific::aacConfig: + hidl_codec_config.config.aacConfig(to_hidl_aac_config( + codec_config.config + .get())); + break; + case CodecConfiguration::CodecSpecific::ldacConfig: + hidl_codec_config.config.ldacConfig(to_hidl_ldac_config( + codec_config.config + .get())); + break; + case CodecConfiguration::CodecSpecific::aptxConfig: + hidl_codec_config.config.aptxConfig(to_hidl_aptx_config( + codec_config.config + .get())); + 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())); + } else if (audio_config.getTag() == AudioConfiguration::a2dpConfig) { + hidl_audio_config.codecConfig(to_hidl_codec_config_2_0( + audio_config.get())); + } + 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(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(lc3_config.octetsPerFrame); + hidl_lc3_config.blocksPerSdu = static_cast(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(); + + auto& le_codec_config = unicast_config.leAudioCodecConfig + .get(); + + 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(); + ::android::hardware::bluetooth::audio::V2_2::UnicastConfig + hidl_unicast_config; + hidl_unicast_config.peerDelay = + static_cast(unicast_config.peerDelay); + + auto& lc3_config = unicast_config.leAudioCodecConfig + .get(); + 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( + unicast_config.streamMap[i].audioChannelAllocation); + hidl_unicast_config.streamMap[i].streamHandle = + static_cast(unicast_config.streamMap[i].streamHandle); + } + } else if (leaudio_config.modeConfig.getTag() == + LeAudioConfiguration::LeAudioModeConfig::broadcastConfig) { + auto bcast_config = + leaudio_config.modeConfig + .get(); + ::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( + bcast_config.streamMap[i].audioChannelAllocation); + hidl_bcast_config.streamMap[i].streamHandle = + static_cast(bcast_config.streamMap[i].streamHandle); + hidl_bcast_config.streamMap[i].lc3Config = to_hidl_lc3_config_2_1( + bcast_config.streamMap[i] + .leAudioCodecConfig.get()); + } + } + 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())); + break; + case AudioConfiguration::a2dpConfig: + hidl_audio_config.codecConfig(to_hidl_codec_config_2_0( + audio_config.get())); + break; + case AudioConfiguration::leAudioConfig: + hidl_audio_config.leAudioCodecConfig(to_hidl_leaudio_config_2_1( + audio_config.get())); + 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())); + break; + case AudioConfiguration::a2dpConfig: + hidl_audio_config.codecConfig(to_hidl_codec_config_2_0( + audio_config.get())); + break; + case AudioConfiguration::leAudioConfig: + hidl_audio_config.leAudioConfig(to_hidl_leaudio_config_2_2( + audio_config.get())); + 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(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(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( + 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 guard(legacy_callback_lock); + session_legacy_callback_table[cookie] = + std::make_shared(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 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 -- cgit v1.2.3