/* * 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" 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; std::mutex legacy_callback_lock; std::unordered_map< SessionType, std::unordered_map>> legacy_callback_table; 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_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}, }; 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 SessionType from_session_type_2_0( const SessionType_2_0& session_type_hidl) { return from_session_type_2_1(static_cast(session_type_hidl)); } 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_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 SampleRate_2_0 to_hidl_sample_rate_2_0(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 static_cast(it->second); return SampleRate_2_0::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& unicast_config) { Lc3CodecConfig_2_1 hidl_lc3_codec_config = { .audioChannelAllocation = 0, }; if (unicast_config.leAudioCodecConfig.getTag() == LeAudioCodecConfiguration::lc3Config) { LOG(FATAL) << __func__ << ": unexpected codec type(vendor?)"; } auto& le_codec_config = unicast_config.leAudioCodecConfig .get(); hidl_lc3_codec_config.lc3Config = to_hidl_lc3_config_2_1(le_codec_config); for (const auto& map : unicast_config.streamMap) { hidl_lc3_codec_config.audioChannelAllocation |= map.audioChannelAllocation; } return hidl_lc3_codec_config; } inline Lc3CodecConfig_2_1 to_hidl_leaudio_broadcast_config_2_1( const LeAudioBroadcastConfiguration& broadcast_config) { Lc3CodecConfig_2_1 hidl_lc3_codec_config = { .audioChannelAllocation = 0, }; // NOTE: Broadcast is not officially supported in HIDL if (broadcast_config.streamMap.empty()) { return hidl_lc3_codec_config; } if (broadcast_config.streamMap[0].leAudioCodecConfig.getTag() != LeAudioCodecConfiguration::lc3Config) { LOG(FATAL) << __func__ << ": unexpected codec type(vendor?)"; } auto& le_codec_config = broadcast_config.streamMap[0] .leAudioCodecConfig.get(); hidl_lc3_codec_config.lc3Config = to_hidl_lc3_config_2_1(le_codec_config); for (const auto& map : broadcast_config.streamMap) { hidl_lc3_codec_config.audioChannelAllocation |= map.audioChannelAllocation; } return hidl_lc3_codec_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; case AudioConfiguration::leAudioBroadcastConfig: hidl_audio_config.leAudioCodecConfig(to_hidl_leaudio_broadcast_config_2_1( 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) { LOG(INFO) << __func__ << ": " << toString(session_type); auto aidl_session_type = from_session_type_2_0(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); }; }; 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_0::UnregisterControlResultCback( const SessionType_2_0& session_type, uint16_t cookie) { LOG(INFO) << __func__ << ": " << toString(session_type); auto aidl_session_type = from_session_type_2_0(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_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); } size_t HidlToAidlMiddleware_2_0::InReadPcmData( const SessionType_2_0& session_type, void* buffer, size_t bytes) { return BluetoothAudioSessionControl::InReadPcmData( 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))); } } // namespace audio } // namespace bluetooth } // namespace hardware } // namespace android } // namespace aidl