diff --git a/bluetooth/audio/2.2/Android.bp b/bluetooth/audio/2.2/Android.bp index 6449c08bc9..8d52ce929c 100644 --- a/bluetooth/audio/2.2/Android.bp +++ b/bluetooth/audio/2.2/Android.bp @@ -14,6 +14,7 @@ hidl_interface { root: "android.hardware", srcs: [ "types.hal", + "IBluetoothAudioPort.hal", "IBluetoothAudioProvider.hal", "IBluetoothAudioProvidersFactory.hal", ], diff --git a/bluetooth/audio/2.2/IBluetoothAudioPort.hal b/bluetooth/audio/2.2/IBluetoothAudioPort.hal new file mode 100644 index 0000000000..344899c036 --- /dev/null +++ b/bluetooth/audio/2.2/IBluetoothAudioPort.hal @@ -0,0 +1,30 @@ +/* + * 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. + */ + +package android.hardware.bluetooth.audio@2.2; + +import @2.0::IBluetoothAudioPort; +import android.hardware.audio.common@5.0::SinkMetadata; + +interface IBluetoothAudioPort extends @2.0::IBluetoothAudioPort { + /** + * Called when the metadata of the stream's sink has been changed. + * + * @param sinkMetadata Description of the audio that is recorded by the + * clients. + */ + updateSinkMetadata(SinkMetadata sinkMetadata); +}; diff --git a/bluetooth/audio/2.2/IBluetoothAudioProvider.hal b/bluetooth/audio/2.2/IBluetoothAudioProvider.hal index ad8c8392a9..bc16b01373 100644 --- a/bluetooth/audio/2.2/IBluetoothAudioProvider.hal +++ b/bluetooth/audio/2.2/IBluetoothAudioProvider.hal @@ -17,7 +17,7 @@ package android.hardware.bluetooth.audio@2.2; import @2.1::IBluetoothAudioProvider; -import @2.0::IBluetoothAudioPort; +import @2.2::IBluetoothAudioPort; import @2.0::Status; /** diff --git a/bluetooth/audio/2.2/default/A2dpOffloadAudioProvider.cpp b/bluetooth/audio/2.2/default/A2dpOffloadAudioProvider.cpp index 126bc9efdd..2a6d93aab4 100644 --- a/bluetooth/audio/2.2/default/A2dpOffloadAudioProvider.cpp +++ b/bluetooth/audio/2.2/default/A2dpOffloadAudioProvider.cpp @@ -54,7 +54,7 @@ bool A2dpOffloadAudioProvider::isValid(const V2_1::SessionType& sessionType) { } Return A2dpOffloadAudioProvider::startSession( - const sp& hostIf, + const sp& hostIf, const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) { /** * Initialize the audio platform if audioConfiguration is supported. diff --git a/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.cpp b/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.cpp index 0d918e1978..ba31d39f2c 100644 --- a/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.cpp +++ b/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.cpp @@ -70,7 +70,7 @@ bool A2dpSoftwareAudioProvider::isValid(const V2_1::SessionType& sessionType) { } Return A2dpSoftwareAudioProvider::startSession( - const sp& hostIf, + const sp& hostIf, const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) { /** * Initialize the audio platform if audioConfiguration is supported. diff --git a/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.h b/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.h index 3d4f0ccd1f..ac3aeced43 100644 --- a/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.h +++ b/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.h @@ -40,7 +40,7 @@ class A2dpSoftwareAudioProvider : public BluetoothAudioProvider { bool isValid(const V2_1::SessionType& sessionType) override; bool isValid(const V2_0::SessionType& sessionType) override; - Return startSession(const sp& hostIf, + Return startSession(const sp& hostIf, const V2_0::AudioConfiguration& audioConfig, startSession_cb _hidl_cb) override; diff --git a/bluetooth/audio/2.2/default/AudioPort_2_0_to_2_2_Wrapper.h b/bluetooth/audio/2.2/default/AudioPort_2_0_to_2_2_Wrapper.h new file mode 100644 index 0000000000..c5613fbf6d --- /dev/null +++ b/bluetooth/audio/2.2/default/AudioPort_2_0_to_2_2_Wrapper.h @@ -0,0 +1,64 @@ +/* + * 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 + +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { +namespace V2_2 { +namespace implementation { + +using ::android::sp; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::audio::common::V5_0::SinkMetadata; +using ::android::hardware::audio::common::V5_0::SourceMetadata; +using ::android::hardware::bluetooth::audio::V2_2::IBluetoothAudioPort; + +class AudioPort_2_0_to_2_2_Wrapper : public V2_2::IBluetoothAudioPort { + public: + AudioPort_2_0_to_2_2_Wrapper(const sp& port) { + this->port = port; + } + + Return startStream() override { return port->startStream(); } + Return suspendStream() override { return port->suspendStream(); } + Return stopStream() override { return port->stopStream(); } + Return getPresentationPosition( + getPresentationPosition_cb _hidl_cb) override { + return port->getPresentationPosition(_hidl_cb); + } + Return updateMetadata(const SourceMetadata& sourceMetadata) override { + return port->updateMetadata(sourceMetadata); + } + Return updateSinkMetadata(const SinkMetadata&) override { + // DO NOTHING, 2.0 AudioPort doesn't support sink metadata updates + return Void(); + } + + sp port; +}; + +} // namespace implementation +} // namespace V2_2 +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android \ No newline at end of file diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp b/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp index 3655bc08bc..3c0ff4214d 100644 --- a/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp +++ b/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp @@ -20,6 +20,7 @@ #include +#include "AudioPort_2_0_to_2_2_Wrapper.h" #include "BluetoothAudioSessionReport_2_2.h" #include "BluetoothAudioSupportedCodecsDB_2_1.h" @@ -51,7 +52,7 @@ BluetoothAudioProvider::BluetoothAudioProvider() audio_config_({}) {} Return BluetoothAudioProvider::startSession( - const sp& hostIf, + const sp& hostIf, const V2_0::AudioConfiguration& audioConfig, startSession_cb _hidl_cb) { AudioConfiguration audioConfig_2_2; @@ -67,11 +68,13 @@ Return BluetoothAudioProvider::startSession( audioConfig_2_2.codecConfig(audioConfig.codecConfig()); } - return startSession_2_2(hostIf, audioConfig_2_2, _hidl_cb); + sp hostIf_2_2 = + new AudioPort_2_0_to_2_2_Wrapper(hostIf); + return startSession_2_2(hostIf_2_2, audioConfig_2_2, _hidl_cb); } Return BluetoothAudioProvider::startSession_2_1( - const sp& hostIf, + const sp& hostIf, const V2_1::AudioConfiguration& audioConfig, startSession_cb _hidl_cb) { AudioConfiguration audioConfig_2_2; if (audioConfig.getDiscriminator() == @@ -92,11 +95,13 @@ Return BluetoothAudioProvider::startSession_2_1( audioConfig_2_2.codecConfig(audioConfig.codecConfig()); } - return startSession_2_2(hostIf, audioConfig_2_2, _hidl_cb); + sp hostIf_2_2 = + new AudioPort_2_0_to_2_2_Wrapper(hostIf); + return startSession_2_2(hostIf_2_2, audioConfig_2_2, _hidl_cb); } Return BluetoothAudioProvider::startSession_2_2( - const sp& hostIf, + const sp& hostIf, const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) { if (hostIf == nullptr) { _hidl_cb(BluetoothAudioStatus::FAILURE, DataMQ::Descriptor()); diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvider.h b/bluetooth/audio/2.2/default/BluetoothAudioProvider.h index b7581ba0c3..0f1f3c6411 100644 --- a/bluetooth/audio/2.2/default/BluetoothAudioProvider.h +++ b/bluetooth/audio/2.2/default/BluetoothAudioProvider.h @@ -26,7 +26,7 @@ namespace V2_2 { namespace implementation { using ::android::sp; -using ::android::hardware::bluetooth::audio::V2_0::IBluetoothAudioPort; +using ::android::hardware::bluetooth::audio::V2_2::IBluetoothAudioPort; using BluetoothAudioStatus = ::android::hardware::bluetooth::audio::V2_0::Status; @@ -41,13 +41,13 @@ class BluetoothAudioProvider : public IBluetoothAudioProvider { virtual bool isValid(const V2_1::SessionType& sessionType) = 0; virtual bool isValid(const V2_0::SessionType& sessionType) = 0; - Return startSession(const sp& hostIf, + Return startSession(const sp& hostIf, const V2_0::AudioConfiguration& audioConfig, startSession_cb _hidl_cb) override; - Return startSession_2_1(const sp& hostIf, + Return startSession_2_1(const sp& hostIf, const V2_1::AudioConfiguration& audioConfig, startSession_cb _hidl_cb) override; - Return startSession_2_2(const sp& hostIf, + Return startSession_2_2(const sp& hostIf, const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) override; Return streamStarted(BluetoothAudioStatus status) override; @@ -59,7 +59,7 @@ class BluetoothAudioProvider : public IBluetoothAudioProvider { V2_1::SessionType session_type_; AudioConfiguration audio_config_; - sp stack_iface_; + sp stack_iface_; virtual Return onSessionReady(startSession_cb _hidl_cb) = 0; }; diff --git a/bluetooth/audio/2.2/default/HearingAidAudioProvider.cpp b/bluetooth/audio/2.2/default/HearingAidAudioProvider.cpp index c79b910ab9..9b3294fe8b 100644 --- a/bluetooth/audio/2.2/default/HearingAidAudioProvider.cpp +++ b/bluetooth/audio/2.2/default/HearingAidAudioProvider.cpp @@ -66,7 +66,7 @@ bool HearingAidAudioProvider::isValid(const V2_1::SessionType& sessionType) { } Return HearingAidAudioProvider::startSession( - const sp& hostIf, + const sp& hostIf, const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) { /** * Initialize the audio platform if audioConfiguration is supported. diff --git a/bluetooth/audio/2.2/default/HearingAidAudioProvider.h b/bluetooth/audio/2.2/default/HearingAidAudioProvider.h index 426c443d89..63290b5c09 100644 --- a/bluetooth/audio/2.2/default/HearingAidAudioProvider.h +++ b/bluetooth/audio/2.2/default/HearingAidAudioProvider.h @@ -40,7 +40,7 @@ class HearingAidAudioProvider : public BluetoothAudioProvider { bool isValid(const V2_1::SessionType& sessionType) override; bool isValid(const V2_0::SessionType& sessionType) override; - Return startSession(const sp& hostIf, + Return startSession(const sp& hostIf, const V2_0::AudioConfiguration& audioConfig, startSession_cb _hidl_cb) override; diff --git a/bluetooth/audio/2.2/default/LeAudioAudioProvider.cpp b/bluetooth/audio/2.2/default/LeAudioAudioProvider.cpp index af6ec99a92..9ec17766f5 100644 --- a/bluetooth/audio/2.2/default/LeAudioAudioProvider.cpp +++ b/bluetooth/audio/2.2/default/LeAudioAudioProvider.cpp @@ -20,6 +20,7 @@ #include +#include "AudioPort_2_0_to_2_2_Wrapper.h" #include "BluetoothAudioSessionReport_2_2.h" #include "BluetoothAudioSupportedCodecsDB_2_1.h" @@ -83,11 +84,13 @@ Return LeAudioAudioProvider::startSession_2_1( .bitsPerSample = audioConfig.pcmConfig().bitsPerSample, .dataIntervalUs = 0}); - return startSession_2_2(hostIf, audioConfig_2_2, _hidl_cb); + sp hostIf_2_2 = + new AudioPort_2_0_to_2_2_Wrapper(hostIf); + return startSession_2_2(hostIf_2_2, audioConfig_2_2, _hidl_cb); } Return LeAudioAudioProvider::startSession_2_2( - const sp& hostIf, + const sp& hostIf, const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) { /** * Initialize the audio platform if audioConfiguration is supported. diff --git a/bluetooth/audio/2.2/default/LeAudioAudioProvider.h b/bluetooth/audio/2.2/default/LeAudioAudioProvider.h index 40c26e0cbf..3de1724bd8 100644 --- a/bluetooth/audio/2.2/default/LeAudioAudioProvider.h +++ b/bluetooth/audio/2.2/default/LeAudioAudioProvider.h @@ -45,7 +45,7 @@ class LeAudioAudioProvider : public BluetoothAudioProvider { const V2_1::AudioConfiguration& audioConfig, startSession_cb _hidl_cb) override; - Return startSession_2_2(const sp& hostIf, + Return startSession_2_2(const sp& hostIf, const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) override; diff --git a/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.cpp b/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.cpp index 7b70654ba8..e3da26757d 100644 --- a/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.cpp +++ b/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.cpp @@ -20,6 +20,7 @@ #include +#include "AudioPort_2_0_to_2_2_Wrapper.h" #include "BluetoothAudioSessionReport_2_2.h" #include "BluetoothAudioSupportedCodecsDB_2_1.h" #include "BluetoothAudioSupportedCodecsDB_2_2.h" @@ -91,11 +92,13 @@ Return LeAudioOffloadAudioProvider::startSession_2_1( .peerDelay = 0, .lc3Config = audioConfig.leAudioCodecConfig().lc3Config}; - return startSession_2_2(hostIf, audioConfig_2_2, _hidl_cb); + sp hostIf_2_2 = + new AudioPort_2_0_to_2_2_Wrapper(hostIf); + return startSession_2_2(hostIf_2_2, audioConfig_2_2, _hidl_cb); } Return LeAudioOffloadAudioProvider::startSession_2_2( - const sp& hostIf, + const sp& hostIf, const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) { /** * Initialize the audio platform if audioConfiguration is supported. diff --git a/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.h b/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.h index 5620295530..fe58de527d 100644 --- a/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.h +++ b/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.h @@ -38,7 +38,7 @@ class LeAudioOffloadAudioProvider : public BluetoothAudioProvider { const V2_1::AudioConfiguration& audioConfig, startSession_cb _hidl_cb) override; - Return startSession_2_2(const sp& hostIf, + Return startSession_2_2(const sp& hostIf, const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) override; diff --git a/bluetooth/audio/utils/Android.bp b/bluetooth/audio/utils/Android.bp index 19d2d920ba..4f712bffab 100644 --- a/bluetooth/audio/utils/Android.bp +++ b/bluetooth/audio/utils/Android.bp @@ -22,6 +22,7 @@ cc_library_shared { export_include_dirs: ["session/"], header_libs: ["libhardware_headers"], shared_libs: [ + "android.hardware.audio.common@5.0", "android.hardware.bluetooth.audio@2.0", "android.hardware.bluetooth.audio@2.1", "android.hardware.bluetooth.audio@2.2", diff --git a/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h index e20914e305..b4ba8cfc4a 100644 --- a/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h +++ b/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h @@ -132,6 +132,15 @@ class BluetoothAudioSessionControl_2_2 { } } + static void UpdateSinkMetadata(const SessionType_2_1& session_type, + const struct sink_metadata* sink_metadata) { + std::shared_ptr session_ptr = + BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + session_ptr->UpdateSinkMetadata(sink_metadata); + } + } + // The control API writes stream to FMQ static size_t OutWritePcmData(const SessionType_2_1& session_type, const void* buffer, size_t bytes) { diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp index 5a6b2e7459..80df5d9eb5 100644 --- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp +++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp @@ -20,10 +20,16 @@ #include #include +#include namespace android { namespace bluetooth { namespace audio { + +using ::android::hardware::audio::common::V5_0::AudioSource; +using ::android::hardware::audio::common::V5_0::RecordTrackMetadata; +using ::android::hardware::audio::common::V5_0::SinkMetadata; + using SessionType_2_1 = ::android::hardware::bluetooth::audio::V2_1::SessionType; using SessionType_2_0 = @@ -37,6 +43,9 @@ using AudioConfiguration_2_1 = ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration BluetoothAudioSession_2_2::invalidOffloadAudioConfiguration = {}; +using IBluetoothAudioPort_2_2 = + ::android::hardware::bluetooth::audio::V2_2::IBluetoothAudioPort; + namespace { bool is_2_0_session_type( const ::android::hardware::bluetooth::audio::V2_1::SessionType& @@ -84,6 +93,54 @@ BluetoothAudioSession_2_2::GetAudioSession_2_1() { return audio_session_2_1; } +void BluetoothAudioSession_2_2::UpdateSinkMetadata( + const struct sink_metadata* sink_metadata) { + std::lock_guard guard(audio_session->mutex_); + if (!IsSessionReady()) { + LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_2_1_) + << " has NO session"; + return; + } + + ssize_t track_count = sink_metadata->track_count; + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_2_1_) + << ", " << track_count << " track(s)"; + if (session_type_2_1_ == SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH || + session_type_2_1_ == SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH) { + return; + } + + struct record_track_metadata* track = sink_metadata->tracks; + SinkMetadata sinkMetadata; + RecordTrackMetadata* halMetadata; + + sinkMetadata.tracks.resize(track_count); + halMetadata = sinkMetadata.tracks.data(); + while (track_count && track) { + halMetadata->source = static_cast(track->source); + halMetadata->gain = track->gain; + // halMetadata->destination leave unspecified + LOG(INFO) << __func__ + << " - SessionType=" << toString(GetAudioSession()->session_type_) + << ", source=" << track->source + << ", dest_device=" << track->dest_device + << ", gain=" << track->gain + << ", dest_device_address=" << track->dest_device_address; + --track_count; + ++track; + ++halMetadata; + } + + /* This is called just for 2.2 sessions, so it's safe to do this casting*/ + IBluetoothAudioPort_2_2* stack_iface_2_2_ = + static_cast(audio_session->stack_iface_.get()); + auto hal_retval = stack_iface_2_2_->updateSinkMetadata(sinkMetadata); + if (!hal_retval.isOk()) { + LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType=" + << toString(session_type_2_1_) << " failed"; + } +} + // The control function is for the bluetooth_audio module to get the current // AudioConfiguration const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h index 7213ede96e..d6ae3d73c4 100644 --- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h +++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h @@ -74,6 +74,8 @@ class BluetoothAudioSession_2_2 { const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration GetAudioConfig(); + void UpdateSinkMetadata(const struct sink_metadata* sink_metadata); + static constexpr ::android::hardware::bluetooth::audio::V2_2:: AudioConfiguration& kInvalidSoftwareAudioConfiguration = invalidSoftwareAudioConfiguration;