From c8861ece90c97af043afe969b6b9939e2565c592 Mon Sep 17 00:00:00 2001 From: Jakub Pawlowski Date: Wed, 2 Jun 2021 12:50:41 +0200 Subject: [PATCH] bluetooth.audio@2.1: add internal HW offloading data path routing Bug: 150670922 Tag: #feature Test: vts-tradefed run vts -m VtsHalBluetoothAudioV2_1TargetTest Change-Id: Id18b269a3a6ebcd56ba39158edc336c176cd2c16 --- bluetooth/audio/2.1/default/Android.bp | 1 + .../BluetoothAudioProvidersFactory.cpp | 10 ++ .../default/BluetoothAudioProvidersFactory.h | 3 + .../default/LeAudioOffloadAudioProvider.cpp | 108 ++++++++++++++++++ .../2.1/default/LeAudioOffloadAudioProvider.h | 60 ++++++++++ .../session/BluetoothAudioSession_2_1.cpp | 17 ++- .../BluetoothAudioSupportedCodecsDB_2_1.cpp | 15 +++ .../BluetoothAudioSupportedCodecsDB_2_1.h | 5 + 8 files changed, 215 insertions(+), 4 deletions(-) create mode 100644 bluetooth/audio/2.1/default/LeAudioOffloadAudioProvider.cpp create mode 100644 bluetooth/audio/2.1/default/LeAudioOffloadAudioProvider.h diff --git a/bluetooth/audio/2.1/default/Android.bp b/bluetooth/audio/2.1/default/Android.bp index 5c30f79001..3000223f73 100644 --- a/bluetooth/audio/2.1/default/Android.bp +++ b/bluetooth/audio/2.1/default/Android.bp @@ -19,6 +19,7 @@ cc_library_shared { "A2dpSoftwareAudioProvider.cpp", "HearingAidAudioProvider.cpp", "LeAudioAudioProvider.cpp", + "LeAudioOffloadAudioProvider.cpp", ], header_libs: ["libhardware_headers"], shared_libs: [ diff --git a/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.cpp b/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.cpp index e1b1ac6793..b0d171a7ba 100644 --- a/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.cpp +++ b/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.cpp @@ -41,8 +41,12 @@ HearingAidAudioProvider BluetoothAudioProvidersFactory::hearing_aid_provider_instance_; LeAudioOutputAudioProvider BluetoothAudioProvidersFactory::leaudio_output_provider_instance_; +LeAudioOffloadOutputAudioProvider + BluetoothAudioProvidersFactory::leaudio_offload_output_provider_instance_; LeAudioInputAudioProvider BluetoothAudioProvidersFactory::leaudio_input_provider_instance_; +LeAudioOffloadInputAudioProvider + BluetoothAudioProvidersFactory::leaudio_offload_input_provider_instance_; Return BluetoothAudioProvidersFactory::openProvider( const V2_0::SessionType sessionType, openProvider_cb _hidl_cb) { @@ -90,9 +94,15 @@ Return BluetoothAudioProvidersFactory::openProvider_2_1( case SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH: provider = &leaudio_output_provider_instance_; break; + case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH: + provider = &leaudio_offload_output_provider_instance_; + break; case SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH: provider = &leaudio_input_provider_instance_; break; + case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH: + provider = &leaudio_offload_input_provider_instance_; + break; default: status = BluetoothAudioStatus::FAILURE; } diff --git a/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.h b/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.h index fd836945d6..f8f557e8c7 100644 --- a/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.h +++ b/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.h @@ -23,6 +23,7 @@ #include "BluetoothAudioProvider.h" #include "HearingAidAudioProvider.h" #include "LeAudioAudioProvider.h" +#include "LeAudioOffloadAudioProvider.h" namespace android { namespace hardware { @@ -55,6 +56,8 @@ class BluetoothAudioProvidersFactory : public IBluetoothAudioProvidersFactory { static HearingAidAudioProvider hearing_aid_provider_instance_; static LeAudioOutputAudioProvider leaudio_output_provider_instance_; static LeAudioInputAudioProvider leaudio_input_provider_instance_; + static LeAudioOffloadOutputAudioProvider leaudio_offload_output_provider_instance_; + static LeAudioOffloadInputAudioProvider leaudio_offload_input_provider_instance_; }; extern "C" IBluetoothAudioProvidersFactory* diff --git a/bluetooth/audio/2.1/default/LeAudioOffloadAudioProvider.cpp b/bluetooth/audio/2.1/default/LeAudioOffloadAudioProvider.cpp new file mode 100644 index 0000000000..c11bdad2d9 --- /dev/null +++ b/bluetooth/audio/2.1/default/LeAudioOffloadAudioProvider.cpp @@ -0,0 +1,108 @@ +/* + * Copyright 2021 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 "BTAudioProviderLeAudioOffload" + +#include "LeAudioOffloadAudioProvider.h" + +#include + +#include "BluetoothAudioSessionReport_2_1.h" +#include "BluetoothAudioSupportedCodecsDB_2_1.h" + +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { +namespace V2_1 { +namespace implementation { + +using ::android::bluetooth::audio::BluetoothAudioSessionReport_2_1; +using ::android::hardware::Void; +using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample; +using ::android::hardware::bluetooth::audio::V2_0::ChannelMode; +using ::android::hardware::bluetooth::audio::V2_1::SampleRate; + +using DataMQ = MessageQueue; + +LeAudioOffloadOutputAudioProvider::LeAudioOffloadOutputAudioProvider() + : LeAudioOffloadAudioProvider() { + session_type_ = SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH; +} + +LeAudioOffloadInputAudioProvider::LeAudioOffloadInputAudioProvider() + : LeAudioOffloadAudioProvider() { + session_type_ = SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH; +} + +LeAudioOffloadAudioProvider::LeAudioOffloadAudioProvider() + : BluetoothAudioProvider() {} + +bool LeAudioOffloadAudioProvider::isValid(const V2_0::SessionType& sessionType) { + LOG(ERROR) << __func__ << ", invalid session type for Offloaded Le Audio provider: " + << toString(sessionType); + + return false; +} + +bool LeAudioOffloadAudioProvider::isValid(const SessionType& sessionType) { + return (sessionType == session_type_); +} + +Return LeAudioOffloadAudioProvider::startSession_2_1( + const sp& hostIf, + const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) { + /** + * Initialize the audio platform if audioConfiguration is supported. + * Save the IBluetoothAudioPort interface, so that it can be used + * later to send stream control commands to the HAL client, based on + * interaction with Audio framework. + */ + if (audioConfig.getDiscriminator() != + AudioConfiguration::hidl_discriminator::leAudioCodecConfig) { + LOG(WARNING) << __func__ + << " - Invalid Audio Configuration=" << toString(audioConfig); + _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION, + DataMQ::Descriptor()); + return Void(); + } + + if (!android::bluetooth::audio::IsOffloadLeAudioConfigurationValid(session_type_, + audioConfig.leAudioCodecConfig())) { + LOG(WARNING) << __func__ << " - Unsupported LC3 Offloaded Configuration=" + << toString(audioConfig.leAudioCodecConfig()); + _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION, + DataMQ::Descriptor()); + return Void(); + } + + return BluetoothAudioProvider::startSession_2_1(hostIf, audioConfig, + _hidl_cb); +} + +Return LeAudioOffloadAudioProvider::onSessionReady(startSession_cb _hidl_cb) { + BluetoothAudioSessionReport_2_1::OnSessionStarted(session_type_, stack_iface_, + nullptr, audio_config_); + _hidl_cb(BluetoothAudioStatus::SUCCESS, DataMQ::Descriptor()); + return Void(); +} + +} // namespace implementation +} // namespace V2_1 +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android diff --git a/bluetooth/audio/2.1/default/LeAudioOffloadAudioProvider.h b/bluetooth/audio/2.1/default/LeAudioOffloadAudioProvider.h new file mode 100644 index 0000000000..564e9a361d --- /dev/null +++ b/bluetooth/audio/2.1/default/LeAudioOffloadAudioProvider.h @@ -0,0 +1,60 @@ +/* + * Copyright 2021 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. + */ + +#pragma once + +#include + +#include "BluetoothAudioProvider.h" + +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { +namespace V2_1 { +namespace implementation { + +class LeAudioOffloadAudioProvider : public BluetoothAudioProvider { + public: + LeAudioOffloadAudioProvider(); + + bool isValid(const SessionType& sessionType) override; + bool isValid(const V2_0::SessionType& sessionType) override; + + Return startSession_2_1(const sp& hostIf, + const AudioConfiguration& audioConfig, + startSession_cb _hidl_cb) override; + + private: + Return onSessionReady(startSession_cb _hidl_cb) override; +}; + +class LeAudioOffloadOutputAudioProvider : public LeAudioOffloadAudioProvider { + public: + LeAudioOffloadOutputAudioProvider(); +}; + +class LeAudioOffloadInputAudioProvider : public LeAudioOffloadAudioProvider { + public: + LeAudioOffloadInputAudioProvider(); +}; + +} // namespace implementation +} // namespace V2_1 +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp index 9d91196d4d..3228a09feb 100644 --- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp +++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp @@ -110,20 +110,29 @@ bool BluetoothAudioSession_2_1::UpdateAudioConfig( SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH || session_type_2_1_ == SessionType_2_1::LE_AUDIO_SOFTWARE_DECODED_DATAPATH); - bool is_offload_session = + bool is_offload_a2dp_session = (session_type_2_1_ == SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH); + bool is_offload_le_audio_session = + (session_type_2_1_ == SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH || + session_type_2_1_ == SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH); auto audio_config_discriminator = audio_config.getDiscriminator(); bool is_software_audio_config = (is_software_session && audio_config_discriminator == ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration:: hidl_discriminator::pcmConfig); - bool is_offload_audio_config = - (is_offload_session && + bool is_a2dp_offload_audio_config = + (is_offload_a2dp_session && audio_config_discriminator == ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration:: hidl_discriminator::codecConfig); - if (!is_software_audio_config && !is_offload_audio_config) { + bool is_le_audio_offload_audio_config = + (is_offload_le_audio_session && + audio_config_discriminator == + ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration:: + hidl_discriminator::leAudioCodecConfig); + if (!is_software_audio_config && !is_a2dp_offload_audio_config && + !is_le_audio_offload_audio_config) { return false; } audio_config_2_1_ = audio_config; diff --git a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_1.cpp b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_1.cpp index 8b0b0f743a..c90ce6d197 100644 --- a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_1.cpp +++ b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_1.cpp @@ -122,6 +122,21 @@ bool IsOffloadCodecConfigurationValid( return false; } +bool IsOffloadLeAudioConfigurationValid( + const ::android::hardware::bluetooth::audio::V2_1::SessionType& + session_type, + const ::android::hardware::bluetooth::audio::V2_1::Lc3CodecConfiguration&) { + + if (session_type != SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH && + session_type != SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) { + return false; + } + + //TODO: perform checks on le_audio_codec_config once we know supported parameters + + return true; +} + } // namespace audio } // namespace bluetooth } // namespace android diff --git a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_1.h b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_1.h index 746d9c05ed..a52636cfbd 100644 --- a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_1.h +++ b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_1.h @@ -41,6 +41,11 @@ bool IsOffloadCodecConfigurationValid( const ::android::hardware::bluetooth::audio::V2_0::CodecConfiguration& codec_config); +bool IsOffloadLeAudioConfigurationValid( + const ::android::hardware::bluetooth::audio::V2_1::SessionType& + session_type, + const ::android::hardware::bluetooth::audio::V2_1::Lc3CodecConfiguration& + le_audio_codec_config); } // namespace audio } // namespace bluetooth } // namespace android