From 2e460345a267388794f53516acb700f9ce3a221e Mon Sep 17 00:00:00 2001 From: Shraddha Basantwani Date: Wed, 26 Jul 2023 16:12:21 +0000 Subject: [PATCH] Audio r_submix : Replace usage of portId by device address Use stream switcher to obtain device address for creation of a remote submix stream. Bug: 286914845 Test: atest VtsHalAudioCoreTargetTest Change-Id: I8dde3d59e488c9621dce78ffd5249254ecfc0b1a --- .../include/core-impl/StreamRemoteSubmix.h | 35 +++++--- .../default/r_submix/StreamRemoteSubmix.cpp | 83 ++++++++++++++++--- 2 files changed, 96 insertions(+), 22 deletions(-) diff --git a/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h b/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h index b39583ea8b..74854c6037 100644 --- a/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h +++ b/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h @@ -20,16 +20,16 @@ #include #include "core-impl/Stream.h" +#include "core-impl/StreamSwitcher.h" #include "r_submix/SubmixRoute.h" namespace aidl::android::hardware::audio::core { -using aidl::android::hardware::audio::core::r_submix::AudioConfig; -using aidl::android::hardware::audio::core::r_submix::SubmixRoute; - class StreamRemoteSubmix : public StreamCommonImpl { public: - StreamRemoteSubmix(StreamContext* context, const Metadata& metadata); + StreamRemoteSubmix( + StreamContext* context, const Metadata& metadata, + const ::aidl::android::media::audio::common::AudioDeviceAddress& deviceAddress); ::android::status_t init() override; ::android::status_t drain(StreamDescriptor::DrainMode) override; @@ -51,16 +51,17 @@ class StreamRemoteSubmix : public StreamCommonImpl { ::android::status_t outWrite(void* buffer, size_t frameCount, size_t* actualFrameCount); ::android::status_t inRead(void* buffer, size_t frameCount, size_t* actualFrameCount); - const int mPortId; + const ::aidl::android::media::audio::common::AudioDeviceAddress mDeviceAddress; const bool mIsInput; - AudioConfig mStreamConfig; - std::shared_ptr mCurrentRoute = nullptr; + r_submix::AudioConfig mStreamConfig; + std::shared_ptr mCurrentRoute = nullptr; // Mutex lock to protect vector of submix routes, each of these submix routes have their mutex // locks and none of the mutex locks should be taken together. static std::mutex sSubmixRoutesLock; - static std::map> sSubmixRoutes - GUARDED_BY(sSubmixRoutesLock); + static std::map<::aidl::android::media::audio::common::AudioDeviceAddress, + std::shared_ptr> + sSubmixRoutes GUARDED_BY(sSubmixRoutesLock); // limit for number of read error log entries to avoid spamming the logs static constexpr int kMaxReadErrorLogs = 5; @@ -72,7 +73,7 @@ class StreamRemoteSubmix : public StreamCommonImpl { static constexpr int kReadAttemptSleepUs = 5000; }; -class StreamInRemoteSubmix final : public StreamIn, public StreamRemoteSubmix { +class StreamInRemoteSubmix final : public StreamIn, public StreamSwitcher { public: friend class ndk::SharedRefBase; StreamInRemoteSubmix( @@ -81,13 +82,19 @@ class StreamInRemoteSubmix final : public StreamIn, public StreamRemoteSubmix { const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones); private: + DeviceSwitchBehavior switchCurrentStream( + const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) + override; + std::unique_ptr createNewStream( + const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices, + StreamContext* context, const Metadata& metadata) override; void onClose(StreamDescriptor::State) override { defaultOnClose(); } ndk::ScopedAStatus getActiveMicrophones( std::vector<::aidl::android::media::audio::common::MicrophoneDynamicInfo>* _aidl_return) override; }; -class StreamOutRemoteSubmix final : public StreamOut, public StreamRemoteSubmix { +class StreamOutRemoteSubmix final : public StreamOut, public StreamSwitcher { public: friend class ndk::SharedRefBase; StreamOutRemoteSubmix( @@ -97,6 +104,12 @@ class StreamOutRemoteSubmix final : public StreamOut, public StreamRemoteSubmix offloadInfo); private: + DeviceSwitchBehavior switchCurrentStream( + const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) + override; + std::unique_ptr createNewStream( + const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices, + StreamContext* context, const Metadata& metadata) override; void onClose(StreamDescriptor::State) override { defaultOnClose(); } }; diff --git a/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp b/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp index 9537ebc56d..74dea53b3e 100644 --- a/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp +++ b/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp @@ -23,15 +23,18 @@ using aidl::android::hardware::audio::common::SinkMetadata; using aidl::android::hardware::audio::common::SourceMetadata; +using aidl::android::hardware::audio::core::r_submix::SubmixRoute; +using aidl::android::media::audio::common::AudioDeviceAddress; using aidl::android::media::audio::common::AudioOffloadInfo; using aidl::android::media::audio::common::MicrophoneDynamicInfo; using aidl::android::media::audio::common::MicrophoneInfo; namespace aidl::android::hardware::audio::core { -StreamRemoteSubmix::StreamRemoteSubmix(StreamContext* context, const Metadata& metadata) +StreamRemoteSubmix::StreamRemoteSubmix(StreamContext* context, const Metadata& metadata, + const AudioDeviceAddress& deviceAddress) : StreamCommonImpl(context, metadata), - mPortId(context->getPortId()), + mDeviceAddress(deviceAddress), mIsInput(isInput(metadata)) { mStreamConfig.frameSize = context->getFrameSize(); mStreamConfig.format = context->getFormat(); @@ -40,13 +43,14 @@ StreamRemoteSubmix::StreamRemoteSubmix(StreamContext* context, const Metadata& m } std::mutex StreamRemoteSubmix::sSubmixRoutesLock; -std::map> StreamRemoteSubmix::sSubmixRoutes; +std::map> StreamRemoteSubmix::sSubmixRoutes; ::android::status_t StreamRemoteSubmix::init() { { std::lock_guard guard(sSubmixRoutesLock); - if (sSubmixRoutes.find(mPortId) != sSubmixRoutes.end()) { - mCurrentRoute = sSubmixRoutes[mPortId]; + auto routeItr = sSubmixRoutes.find(mDeviceAddress); + if (routeItr != sSubmixRoutes.end()) { + mCurrentRoute = routeItr->second; } } // If route is not available for this port, add it. @@ -59,7 +63,7 @@ std::map> StreamRemoteSubmix::sSubmixRoute } { std::lock_guard guard(sSubmixRoutesLock); - sSubmixRoutes.emplace(mPortId, mCurrentRoute); + sSubmixRoutes.emplace(mDeviceAddress, mCurrentRoute); } } else { if (!mCurrentRoute->isStreamConfigValid(mIsInput, mStreamConfig)) { @@ -116,8 +120,9 @@ ndk::ScopedAStatus StreamRemoteSubmix::prepareToClose() { std::shared_ptr route = nullptr; { std::lock_guard guard(sSubmixRoutesLock); - if (sSubmixRoutes.find(mPortId) != sSubmixRoutes.end()) { - route = sSubmixRoutes[mPortId]; + auto routeItr = sSubmixRoutes.find(mDeviceAddress); + if (routeItr != sSubmixRoutes.end()) { + route = routeItr->second; } } if (route != nullptr) { @@ -146,7 +151,7 @@ void StreamRemoteSubmix::shutdown() { LOG(DEBUG) << __func__ << ": pipe destroyed"; std::lock_guard guard(sSubmixRoutesLock); - sSubmixRoutes.erase(mPortId); + sSubmixRoutes.erase(mDeviceAddress); } mCurrentRoute.reset(); } @@ -357,7 +362,7 @@ StreamInRemoteSubmix::StreamInRemoteSubmix(StreamContext&& context, const SinkMetadata& sinkMetadata, const std::vector& microphones) : StreamIn(std::move(context), microphones), - StreamRemoteSubmix(&(StreamIn::mContext), sinkMetadata) {} + StreamSwitcher(&(StreamIn::mContext), sinkMetadata) {} ndk::ScopedAStatus StreamInRemoteSubmix::getActiveMicrophones( std::vector* _aidl_return) { @@ -366,10 +371,66 @@ ndk::ScopedAStatus StreamInRemoteSubmix::getActiveMicrophones( return ndk::ScopedAStatus::ok(); } +StreamSwitcher::DeviceSwitchBehavior StreamInRemoteSubmix::switchCurrentStream( + const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) { + // This implementation effectively postpones stream creation until + // receiving the first call to 'setConnectedDevices' with a non-empty list. + if (isStubStream()) { + if (devices.size() == 1) { + auto deviceDesc = devices.front().type; + if (deviceDesc.type == + ::aidl::android::media::audio::common::AudioDeviceType::IN_SUBMIX) { + return DeviceSwitchBehavior::CREATE_NEW_STREAM; + } + LOG(ERROR) << __func__ << ": Device type " << toString(deviceDesc.type) + << " not supported"; + } else { + LOG(ERROR) << __func__ << ": Only single device supported."; + } + return DeviceSwitchBehavior::UNSUPPORTED_DEVICES; + } + return DeviceSwitchBehavior::USE_CURRENT_STREAM; +} + +std::unique_ptr StreamInRemoteSubmix::createNewStream( + const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices, + StreamContext* context, const Metadata& metadata) { + return std::unique_ptr( + new InnerStreamWrapper(context, metadata, devices.front().address)); +} + StreamOutRemoteSubmix::StreamOutRemoteSubmix(StreamContext&& context, const SourceMetadata& sourceMetadata, const std::optional& offloadInfo) : StreamOut(std::move(context), offloadInfo), - StreamRemoteSubmix(&(StreamOut::mContext), sourceMetadata) {} + StreamSwitcher(&(StreamOut::mContext), sourceMetadata) {} + +StreamSwitcher::DeviceSwitchBehavior StreamOutRemoteSubmix::switchCurrentStream( + const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) { + // This implementation effectively postpones stream creation until + // receiving the first call to 'setConnectedDevices' with a non-empty list. + if (isStubStream()) { + if (devices.size() == 1) { + auto deviceDesc = devices.front().type; + if (deviceDesc.type == + ::aidl::android::media::audio::common::AudioDeviceType::OUT_SUBMIX) { + return DeviceSwitchBehavior::CREATE_NEW_STREAM; + } + LOG(ERROR) << __func__ << ": Device type " << toString(deviceDesc.type) + << " not supported"; + } else { + LOG(ERROR) << __func__ << ": Only single device supported."; + } + return DeviceSwitchBehavior::UNSUPPORTED_DEVICES; + } + return DeviceSwitchBehavior::USE_CURRENT_STREAM; +} + +std::unique_ptr StreamOutRemoteSubmix::createNewStream( + const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices, + StreamContext* context, const Metadata& metadata) { + return std::unique_ptr( + new InnerStreamWrapper(context, metadata, devices.front().address)); +} } // namespace aidl::android::hardware::audio::core