From 9d16a6ac106f9c43200825232a7db797c8ef6e4f Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Mon, 26 Jun 2023 17:21:04 -0700 Subject: [PATCH] audio: Allow Module subclasses to customize stream creation Since specializations of the 'Module' class likely need to provide their own specializations for streams, provide virtual methods for them. Bug: 282568751 Test: atest VtsHalAudioCoreTargetTest Change-Id: Iddb1bff9f11bc867aba61897ea2f8b9bc3c27544 --- audio/aidl/default/Module.cpp | 49 ++++++++----------- audio/aidl/default/StreamStub.cpp | 28 ----------- audio/aidl/default/include/core-impl/Module.h | 17 +++++-- .../default/include/core-impl/ModuleUsb.h | 11 +++++ audio/aidl/default/include/core-impl/Stream.h | 29 ++++++----- .../default/include/core-impl/StreamStub.h | 15 ------ .../default/include/core-impl/StreamUsb.h | 25 +++------- audio/aidl/default/usb/ModuleUsb.cpp | 24 +++++++++ audio/aidl/default/usb/StreamUsb.cpp | 32 ------------ 9 files changed, 88 insertions(+), 142 deletions(-) diff --git a/audio/aidl/default/Module.cpp b/audio/aidl/default/Module.cpp index c0c6c4889d..6f89d4bc11 100644 --- a/audio/aidl/default/Module.cpp +++ b/audio/aidl/default/Module.cpp @@ -30,7 +30,6 @@ #include "core-impl/ModuleUsb.h" #include "core-impl/SoundDose.h" #include "core-impl/StreamStub.h" -#include "core-impl/StreamUsb.h" #include "core-impl/Telephony.h" #include "core-impl/utils.h" @@ -119,30 +118,6 @@ std::shared_ptr Module::createInstance(Type type) { } } -// static -StreamIn::CreateInstance Module::getStreamInCreator(Type type) { - switch (type) { - case Type::USB: - return StreamInUsb::createInstance; - case Type::DEFAULT: - case Type::R_SUBMIX: - default: - return StreamInStub::createInstance; - } -} - -// static -StreamOut::CreateInstance Module::getStreamOutCreator(Type type) { - switch (type) { - case Type::USB: - return StreamOutUsb::createInstance; - case Type::DEFAULT: - case Type::R_SUBMIX: - default: - return StreamOutStub::createInstance; - } -} - std::ostream& operator<<(std::ostream& os, Module::Type t) { switch (t) { case Module::Type::DEFAULT: @@ -687,8 +662,8 @@ ndk::ScopedAStatus Module::openInputStream(const OpenInputStreamArguments& in_ar nullptr, nullptr, &context)); context.fillDescriptor(&_aidl_return->desc); std::shared_ptr stream; - RETURN_STATUS_IF_ERROR(getStreamInCreator(mType)(in_args.sinkMetadata, std::move(context), - mConfig->microphones, &stream)); + RETURN_STATUS_IF_ERROR(createInputStream(in_args.sinkMetadata, std::move(context), + mConfig->microphones, &stream)); StreamWrapper streamWrapper(stream); if (auto patchIt = mPatches.find(in_args.portConfigId); patchIt != mPatches.end()) { RETURN_STATUS_IF_ERROR( @@ -733,8 +708,8 @@ ndk::ScopedAStatus Module::openOutputStream(const OpenOutputStreamArguments& in_ in_args.eventCallback, &context)); context.fillDescriptor(&_aidl_return->desc); std::shared_ptr stream; - RETURN_STATUS_IF_ERROR(getStreamOutCreator(mType)(in_args.sourceMetadata, std::move(context), - in_args.offloadInfo, &stream)); + RETURN_STATUS_IF_ERROR(createOutputStream(in_args.sourceMetadata, std::move(context), + in_args.offloadInfo, &stream)); StreamWrapper streamWrapper(stream); if (auto patchIt = mPatches.find(in_args.portConfigId); patchIt != mPatches.end()) { RETURN_STATUS_IF_ERROR( @@ -1346,6 +1321,22 @@ bool Module::isMmapSupported() { return mIsMmapSupported.value(); } +ndk::ScopedAStatus Module::createInputStream(const SinkMetadata& sinkMetadata, + StreamContext&& context, + const std::vector& microphones, + std::shared_ptr* result) { + return createStreamInstance(result, sinkMetadata, std::move(context), + microphones); +} + +ndk::ScopedAStatus Module::createOutputStream(const SourceMetadata& sourceMetadata, + StreamContext&& context, + const std::optional& offloadInfo, + std::shared_ptr* result) { + return createStreamInstance(result, sourceMetadata, std::move(context), + offloadInfo); +} + ndk::ScopedAStatus Module::populateConnectedDevicePort(AudioPort* audioPort __unused) { LOG(VERBOSE) << __func__ << ": do nothing and return ok"; return ndk::ScopedAStatus::ok(); diff --git a/audio/aidl/default/StreamStub.cpp b/audio/aidl/default/StreamStub.cpp index 289afa1c85..d88dfbc3c2 100644 --- a/audio/aidl/default/StreamStub.cpp +++ b/audio/aidl/default/StreamStub.cpp @@ -87,38 +87,10 @@ StreamStub::StreamStub(const Metadata& metadata, StreamContext&& context) void StreamStub::shutdown() {} -// static -ndk::ScopedAStatus StreamInStub::createInstance(const SinkMetadata& sinkMetadata, - StreamContext&& context, - const std::vector& microphones, - std::shared_ptr* result) { - std::shared_ptr stream = - ndk::SharedRefBase::make(sinkMetadata, std::move(context), microphones); - if (auto status = stream->initInstance(stream); !status.isOk()) { - return status; - } - *result = std::move(stream); - return ndk::ScopedAStatus::ok(); -} - StreamInStub::StreamInStub(const SinkMetadata& sinkMetadata, StreamContext&& context, const std::vector& microphones) : StreamStub(sinkMetadata, std::move(context)), StreamIn(microphones) {} -// static -ndk::ScopedAStatus StreamOutStub::createInstance(const SourceMetadata& sourceMetadata, - StreamContext&& context, - const std::optional& offloadInfo, - std::shared_ptr* result) { - std::shared_ptr stream = ndk::SharedRefBase::make( - sourceMetadata, std::move(context), offloadInfo); - if (auto status = stream->initInstance(stream); !status.isOk()) { - return status; - } - *result = std::move(stream); - return ndk::ScopedAStatus::ok(); -} - StreamOutStub::StreamOutStub(const SourceMetadata& sourceMetadata, StreamContext&& context, const std::optional& offloadInfo) : StreamStub(sourceMetadata, std::move(context)), StreamOut(offloadInfo) {} diff --git a/audio/aidl/default/include/core-impl/Module.h b/audio/aidl/default/include/core-impl/Module.h index 212cfd9570..4a23637d86 100644 --- a/audio/aidl/default/include/core-impl/Module.h +++ b/audio/aidl/default/include/core-impl/Module.h @@ -33,11 +33,9 @@ class Module : public BnModule { static constexpr int32_t kLatencyMs = 10; enum Type : int { DEFAULT, R_SUBMIX, USB }; - explicit Module(Type type) : mType(type) {} - static std::shared_ptr createInstance(Type type); - static StreamIn::CreateInstance getStreamInCreator(Type type); - static StreamOut::CreateInstance getStreamOutCreator(Type type); + + explicit Module(Type type) : mType(type) {} protected: // The vendor extension done via inheritance can override interface methods and augment @@ -182,6 +180,17 @@ class Module : public BnModule { protected: // The following virtual functions are intended for vendor extension via inheritance. + virtual ndk::ScopedAStatus createInputStream( + const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata, + StreamContext&& context, + const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones, + std::shared_ptr* result); + virtual ndk::ScopedAStatus createOutputStream( + const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata, + StreamContext&& context, + const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>& + offloadInfo, + std::shared_ptr* result); // If the module is unable to populate the connected device port correctly, the returned error // code must correspond to the errors of `IModule.connectedExternalDevice` method. virtual ndk::ScopedAStatus populateConnectedDevicePort( diff --git a/audio/aidl/default/include/core-impl/ModuleUsb.h b/audio/aidl/default/include/core-impl/ModuleUsb.h index 1aa22445b4..5a5429db64 100644 --- a/audio/aidl/default/include/core-impl/ModuleUsb.h +++ b/audio/aidl/default/include/core-impl/ModuleUsb.h @@ -32,6 +32,17 @@ class ModuleUsb : public Module { ndk::ScopedAStatus setMicMute(bool in_mute) override; // Module interfaces + ndk::ScopedAStatus createInputStream( + const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata, + StreamContext&& context, + const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones, + std::shared_ptr* result) override; + ndk::ScopedAStatus createOutputStream( + const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata, + StreamContext&& context, + const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>& + offloadInfo, + std::shared_ptr* result) override; ndk::ScopedAStatus populateConnectedDevicePort( ::aidl::android::media::audio::common::AudioPort* audioPort) override; ndk::ScopedAStatus checkAudioPatchEndpointsMatch( diff --git a/audio/aidl/default/include/core-impl/Stream.h b/audio/aidl/default/include/core-impl/Stream.h index ff5b5a0ab1..c20a4213ed 100644 --- a/audio/aidl/default/include/core-impl/Stream.h +++ b/audio/aidl/default/include/core-impl/Stream.h @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -37,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -482,13 +484,6 @@ class StreamIn : virtual public StreamCommonInterface, public BnStreamIn { const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones); const std::map<::aidl::android::media::audio::common::AudioDevice, std::string> mMicrophones; - - public: - using CreateInstance = std::function& microphones, - std::shared_ptr* result)>; }; class StreamOut : virtual public StreamCommonInterface, public BnStreamOut { @@ -531,16 +526,20 @@ class StreamOut : virtual public StreamCommonInterface, public BnStreamOut { std::optional<::aidl::android::media::audio::common::AudioOffloadInfo> mOffloadInfo; std::optional<::aidl::android::hardware::audio::common::AudioOffloadMetadata> mOffloadMetadata; - - public: - using CreateInstance = std::function& - offloadInfo, - std::shared_ptr* result)>; }; +// The recommended way to create a stream instance. +// 'StreamImpl' is the concrete stream implementation, 'StreamInOrOut' is either 'StreamIn' or +// 'StreamOut', the rest are the arguments forwarded to the constructor of 'StreamImpl'. +template +ndk::ScopedAStatus createStreamInstance(std::shared_ptr* result, Args&&... args) { + std::shared_ptr stream = + ::ndk::SharedRefBase::make(std::forward(args)...); + RETURN_STATUS_IF_ERROR(stream->initInstance(stream)); + *result = std::move(stream); + return ndk::ScopedAStatus::ok(); +} + class StreamWrapper { public: explicit StreamWrapper(const std::shared_ptr& streamIn) diff --git a/audio/aidl/default/include/core-impl/StreamStub.h b/audio/aidl/default/include/core-impl/StreamStub.h index def98b7986..c8900f3223 100644 --- a/audio/aidl/default/include/core-impl/StreamStub.h +++ b/audio/aidl/default/include/core-impl/StreamStub.h @@ -42,13 +42,6 @@ class StreamStub : public StreamCommonImpl { class StreamInStub final : public StreamStub, public StreamIn { public: - static ndk::ScopedAStatus createInstance( - const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata, - StreamContext&& context, - const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones, - std::shared_ptr* result); - - private: friend class ndk::SharedRefBase; StreamInStub( const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata, @@ -58,14 +51,6 @@ class StreamInStub final : public StreamStub, public StreamIn { class StreamOutStub final : public StreamStub, public StreamOut { public: - static ndk::ScopedAStatus createInstance( - const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata, - StreamContext&& context, - const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>& - offloadInfo, - std::shared_ptr* result); - - private: friend class ndk::SharedRefBase; StreamOutStub(const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata, StreamContext&& context, diff --git a/audio/aidl/default/include/core-impl/StreamUsb.h b/audio/aidl/default/include/core-impl/StreamUsb.h index 24ea8be51c..5e55cd8cb8 100644 --- a/audio/aidl/default/include/core-impl/StreamUsb.h +++ b/audio/aidl/default/include/core-impl/StreamUsb.h @@ -60,41 +60,28 @@ class StreamUsb : public StreamCommonImpl { }; class StreamInUsb final : public StreamUsb, public StreamIn { - ndk::ScopedAStatus getActiveMicrophones( - std::vector<::aidl::android::media::audio::common::MicrophoneDynamicInfo>* _aidl_return) - override; - public: - static ndk::ScopedAStatus createInstance( - const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata, - StreamContext&& context, - const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones, - std::shared_ptr* result); - - private: friend class ndk::SharedRefBase; StreamInUsb( const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata, StreamContext&& context, const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones); + + private: + ndk::ScopedAStatus getActiveMicrophones( + std::vector<::aidl::android::media::audio::common::MicrophoneDynamicInfo>* _aidl_return) + override; }; class StreamOutUsb final : public StreamUsb, public StreamOut { public: - static ndk::ScopedAStatus createInstance( - const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata, - StreamContext&& context, - const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>& - offloadInfo, - std::shared_ptr* result); - - private: friend class ndk::SharedRefBase; StreamOutUsb(const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata, StreamContext&& context, const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>& offloadInfo); + private: ndk::ScopedAStatus getHwVolume(std::vector* _aidl_return) override; ndk::ScopedAStatus setHwVolume(const std::vector& in_channelVolumes) override; diff --git a/audio/aidl/default/usb/ModuleUsb.cpp b/audio/aidl/default/usb/ModuleUsb.cpp index c568dc94ab..5c9d4776ee 100644 --- a/audio/aidl/default/usb/ModuleUsb.cpp +++ b/audio/aidl/default/usb/ModuleUsb.cpp @@ -25,11 +25,14 @@ #include "UsbAlsaMixerControl.h" #include "UsbAlsaUtils.h" #include "core-impl/ModuleUsb.h" +#include "core-impl/StreamUsb.h" extern "C" { #include "alsa_device_profile.h" } +using aidl::android::hardware::audio::common::SinkMetadata; +using aidl::android::hardware::audio::common::SourceMetadata; using aidl::android::media::audio::common::AudioChannelLayout; using aidl::android::media::audio::common::AudioDeviceAddress; using aidl::android::media::audio::common::AudioDeviceDescription; @@ -37,10 +40,12 @@ using aidl::android::media::audio::common::AudioDeviceType; using aidl::android::media::audio::common::AudioFormatDescription; using aidl::android::media::audio::common::AudioFormatType; using aidl::android::media::audio::common::AudioIoFlags; +using aidl::android::media::audio::common::AudioOffloadInfo; using aidl::android::media::audio::common::AudioPort; using aidl::android::media::audio::common::AudioPortConfig; using aidl::android::media::audio::common::AudioPortExt; using aidl::android::media::audio::common::AudioProfile; +using aidl::android::media::audio::common::MicrophoneInfo; namespace aidl::android::hardware::audio::core { @@ -97,6 +102,25 @@ ndk::ScopedAStatus ModuleUsb::setMicMute(bool in_mute __unused) { return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } +ndk::ScopedAStatus ModuleUsb::createInputStream(const SinkMetadata& sinkMetadata, + StreamContext&& context, + const std::vector& microphones, + std::shared_ptr* result) { + return createStreamInstance(result, sinkMetadata, std::move(context), microphones); +} + +ndk::ScopedAStatus ModuleUsb::createOutputStream(const SourceMetadata& sourceMetadata, + StreamContext&& context, + const std::optional& offloadInfo, + std::shared_ptr* result) { + if (offloadInfo.has_value()) { + LOG(ERROR) << __func__ << ": offload is not supported"; + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + return createStreamInstance(result, sourceMetadata, std::move(context), + offloadInfo); +} + ndk::ScopedAStatus ModuleUsb::populateConnectedDevicePort(AudioPort* audioPort) { if (audioPort->ext.getTag() != AudioPortExt::Tag::device) { LOG(ERROR) << __func__ << ": port id " << audioPort->id << " is not a device port"; diff --git a/audio/aidl/default/usb/StreamUsb.cpp b/audio/aidl/default/usb/StreamUsb.cpp index fcac5dfc49..49bc1d67a0 100644 --- a/audio/aidl/default/usb/StreamUsb.cpp +++ b/audio/aidl/default/usb/StreamUsb.cpp @@ -205,20 +205,6 @@ void StreamUsb::shutdown() {} return ::android::OK; } -// static -ndk::ScopedAStatus StreamInUsb::createInstance(const SinkMetadata& sinkMetadata, - StreamContext&& context, - const std::vector& microphones, - std::shared_ptr* result) { - std::shared_ptr stream = - ndk::SharedRefBase::make(sinkMetadata, std::move(context), microphones); - if (auto status = stream->initInstance(stream); !status.isOk()) { - return status; - } - *result = std::move(stream); - return ndk::ScopedAStatus::ok(); -} - StreamInUsb::StreamInUsb(const SinkMetadata& sinkMetadata, StreamContext&& context, const std::vector& microphones) : StreamUsb(sinkMetadata, std::move(context)), StreamIn(microphones) {} @@ -229,24 +215,6 @@ ndk::ScopedAStatus StreamInUsb::getActiveMicrophones( return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } -// static -ndk::ScopedAStatus StreamOutUsb::createInstance(const SourceMetadata& sourceMetadata, - StreamContext&& context, - const std::optional& offloadInfo, - std::shared_ptr* result) { - if (offloadInfo.has_value()) { - LOG(ERROR) << __func__ << ": offload is not supported"; - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); - } - std::shared_ptr stream = - ndk::SharedRefBase::make(sourceMetadata, std::move(context), offloadInfo); - if (auto status = stream->initInstance(stream); !status.isOk()) { - return status; - } - *result = std::move(stream); - return ndk::ScopedAStatus::ok(); -} - StreamOutUsb::StreamOutUsb(const SourceMetadata& sourceMetadata, StreamContext&& context, const std::optional& offloadInfo) : StreamUsb(sourceMetadata, std::move(context)), StreamOut(offloadInfo) {