Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 73b06adb authored by Mikhail Naganov's avatar Mikhail Naganov
Browse files

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
Merged-In: Iddb1bff9f11bc867aba61897ea2f8b9bc3c27544
Change-Id: Iddb1bff9f11bc867aba61897ea2f8b9bc3c27544
(cherry picked from commit 9d16a6ac)
parent efe980bb
Loading
Loading
Loading
Loading
+20 −29
Original line number Diff line number Diff line
@@ -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> 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,7 +662,7 @@ ndk::ScopedAStatus Module::openInputStream(const OpenInputStreamArguments& in_ar
                                               nullptr, nullptr, &context));
    context.fillDescriptor(&_aidl_return->desc);
    std::shared_ptr<StreamIn> stream;
    RETURN_STATUS_IF_ERROR(getStreamInCreator(mType)(in_args.sinkMetadata, std::move(context),
    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()) {
@@ -733,7 +708,7 @@ ndk::ScopedAStatus Module::openOutputStream(const OpenOutputStreamArguments& in_
                                               in_args.eventCallback, &context));
    context.fillDescriptor(&_aidl_return->desc);
    std::shared_ptr<StreamOut> stream;
    RETURN_STATUS_IF_ERROR(getStreamOutCreator(mType)(in_args.sourceMetadata, std::move(context),
    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()) {
@@ -1346,6 +1321,22 @@ bool Module::isMmapSupported() {
    return mIsMmapSupported.value();
}

ndk::ScopedAStatus Module::createInputStream(const SinkMetadata& sinkMetadata,
                                             StreamContext&& context,
                                             const std::vector<MicrophoneInfo>& microphones,
                                             std::shared_ptr<StreamIn>* result) {
    return createStreamInstance<StreamInStub>(result, sinkMetadata, std::move(context),
                                              microphones);
}

ndk::ScopedAStatus Module::createOutputStream(const SourceMetadata& sourceMetadata,
                                              StreamContext&& context,
                                              const std::optional<AudioOffloadInfo>& offloadInfo,
                                              std::shared_ptr<StreamOut>* result) {
    return createStreamInstance<StreamOutStub>(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();
+0 −28
Original line number Diff line number Diff line
@@ -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<MicrophoneInfo>& microphones,
                                                std::shared_ptr<StreamIn>* result) {
    std::shared_ptr<StreamIn> stream =
            ndk::SharedRefBase::make<StreamInStub>(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<MicrophoneInfo>& microphones)
    : StreamStub(sinkMetadata, std::move(context)), StreamIn(microphones) {}

// static
ndk::ScopedAStatus StreamOutStub::createInstance(const SourceMetadata& sourceMetadata,
                                                 StreamContext&& context,
                                                 const std::optional<AudioOffloadInfo>& offloadInfo,
                                                 std::shared_ptr<StreamOut>* result) {
    std::shared_ptr<StreamOut> stream = ndk::SharedRefBase::make<StreamOutStub>(
            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<AudioOffloadInfo>& offloadInfo)
    : StreamStub(sourceMetadata, std::move(context)), StreamOut(offloadInfo) {}
+13 −4
Original line number Diff line number Diff line
@@ -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<Module> 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<StreamIn>* 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<StreamOut>* 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(
+11 −0
Original line number Diff line number Diff line
@@ -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<StreamIn>* 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<StreamOut>* result) override;
    ndk::ScopedAStatus populateConnectedDevicePort(
            ::aidl::android::media::audio::common::AudioPort* audioPort) override;
    ndk::ScopedAStatus checkAudioPatchEndpointsMatch(
+14 −15
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <variant>

#include <StreamWorker.h>
#include <Utils.h>
#include <aidl/android/hardware/audio/common/SinkMetadata.h>
#include <aidl/android/hardware/audio/common/SourceMetadata.h>
#include <aidl/android/hardware/audio/core/BnStreamCommon.h>
@@ -37,6 +38,7 @@
#include <aidl/android/media/audio/common/AudioIoFlags.h>
#include <aidl/android/media/audio/common/AudioOffloadInfo.h>
#include <aidl/android/media/audio/common/MicrophoneInfo.h>
#include <error/expected_utils.h>
#include <fmq/AidlMessageQueue.h>
#include <system/thread_defs.h>
#include <utils/Errors.h>
@@ -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<ndk::ScopedAStatus(
            const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
            StreamContext&& context,
            const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones,
            std::shared_ptr<StreamIn>* 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<ndk::ScopedAStatus(
            const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
            StreamContext&& context,
            const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
                    offloadInfo,
            std::shared_ptr<StreamOut>* 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 <class StreamImpl, class StreamInOrOut, class... Args>
ndk::ScopedAStatus createStreamInstance(std::shared_ptr<StreamInOrOut>* result, Args&&... args) {
    std::shared_ptr<StreamInOrOut> stream =
            ::ndk::SharedRefBase::make<StreamImpl>(std::forward<Args>(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>& streamIn)
Loading