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

Commit efe980bb authored by Mikhail Naganov's avatar Mikhail Naganov
Browse files

audio: Refactor streams implementation

Simplify the experience of implementing stream variants.
Stream class now exposes two interfaces: DriverInterface
and StreamCommonInterface, which represent the two
aspects of its usage: via the FMQ on the worker thread,
and via IStreamCommon Binder interface.

Input/output streams now inherit the concrete stream
variant, and implement interface methods specific for
IStreamIn and IStreamOut.

Added DriverInterface::shutdown method which is called
on the worker thread prior to the exit.

Bug: 282568751
Test: atest VtsHalAudioCoreTargetTest
Merged-In: I5bf8da2f22b27f0e284a41fc30b920d87ac2936c
Change-Id: I5bf8da2f22b27f0e284a41fc30b920d87ac2936c
(cherry picked from commit d5554cfa)
parent ef1345a8
Loading
Loading
Loading
Loading
+30 −58
Original line number Original line Diff line number Diff line
@@ -152,6 +152,7 @@ StreamInWorkerLogic::Status StreamInWorkerLogic::cycle() {
        case Tag::halReservedExit:
        case Tag::halReservedExit:
            if (const int32_t cookie = command.get<Tag::halReservedExit>();
            if (const int32_t cookie = command.get<Tag::halReservedExit>();
                cookie == mInternalCommandCookie) {
                cookie == mInternalCommandCookie) {
                mDriver->shutdown();
                setClosed();
                setClosed();
                // This is an internal command, no need to reply.
                // This is an internal command, no need to reply.
                return Status::EXIT;
                return Status::EXIT;
@@ -364,6 +365,7 @@ StreamOutWorkerLogic::Status StreamOutWorkerLogic::cycle() {
        case Tag::halReservedExit:
        case Tag::halReservedExit:
            if (const int32_t cookie = command.get<Tag::halReservedExit>();
            if (const int32_t cookie = command.get<Tag::halReservedExit>();
                cookie == mInternalCommandCookie) {
                cookie == mInternalCommandCookie) {
                mDriver->shutdown();
                setClosed();
                setClosed();
                // This is an internal command, no need to reply.
                // This is an internal command, no need to reply.
                return Status::EXIT;
                return Status::EXIT;
@@ -567,8 +569,7 @@ bool StreamOutWorkerLogic::write(size_t clientSize, StreamDescriptor::Reply* rep
    return !fatal;
    return !fatal;
}
}


template <class Metadata>
StreamCommonImpl::~StreamCommonImpl() {
StreamCommonImpl<Metadata>::~StreamCommonImpl() {
    if (!isClosed()) {
    if (!isClosed()) {
        LOG(ERROR) << __func__ << ": stream was not closed prior to destruction, resource leak";
        LOG(ERROR) << __func__ << ": stream was not closed prior to destruction, resource leak";
        stopWorker();
        stopWorker();
@@ -576,19 +577,16 @@ StreamCommonImpl<Metadata>::~StreamCommonImpl() {
    }
    }
}
}


template <class Metadata>
ndk::ScopedAStatus StreamCommonImpl::initInstance(
void StreamCommonImpl<Metadata>::createStreamCommon(
        const std::shared_ptr<StreamCommonInterface>& delegate) {
        const std::shared_ptr<StreamCommonInterface>& delegate) {
    if (mCommon != nullptr) {
    mCommon = ndk::SharedRefBase::make<StreamCommonDelegator>(delegate);
        LOG(FATAL) << __func__ << ": attempting to create the common interface twice";
    }
    mCommon = ndk::SharedRefBase::make<StreamCommon>(delegate);
    mCommonBinder = mCommon->asBinder();
    mCommonBinder = mCommon->asBinder();
    AIBinder_setMinSchedulerPolicy(mCommonBinder.get(), SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
    AIBinder_setMinSchedulerPolicy(mCommonBinder.get(), SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
    return mWorker->start() ? ndk::ScopedAStatus::ok()
                            : ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
}
}


template <class Metadata>
ndk::ScopedAStatus StreamCommonImpl::getStreamCommonCommon(
ndk::ScopedAStatus StreamCommonImpl<Metadata>::getStreamCommon(
        std::shared_ptr<IStreamCommon>* _aidl_return) {
        std::shared_ptr<IStreamCommon>* _aidl_return) {
    if (mCommon == nullptr) {
    if (mCommon == nullptr) {
        LOG(FATAL) << __func__ << ": the common interface was not created";
        LOG(FATAL) << __func__ << ": the common interface was not created";
@@ -598,30 +596,26 @@ ndk::ScopedAStatus StreamCommonImpl<Metadata>::getStreamCommon(
    return ndk::ScopedAStatus::ok();
    return ndk::ScopedAStatus::ok();
}
}


template <class Metadata>
ndk::ScopedAStatus StreamCommonImpl::updateHwAvSyncId(int32_t in_hwAvSyncId) {
ndk::ScopedAStatus StreamCommonImpl<Metadata>::updateHwAvSyncId(int32_t in_hwAvSyncId) {
    LOG(DEBUG) << __func__ << ": id " << in_hwAvSyncId;
    LOG(DEBUG) << __func__ << ": id " << in_hwAvSyncId;
    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
}


template <class Metadata>
ndk::ScopedAStatus StreamCommonImpl::getVendorParameters(
ndk::ScopedAStatus StreamCommonImpl<Metadata>::getVendorParameters(
        const std::vector<std::string>& in_ids, std::vector<VendorParameter>* _aidl_return) {
        const std::vector<std::string>& in_ids, std::vector<VendorParameter>* _aidl_return) {
    LOG(DEBUG) << __func__ << ": id count: " << in_ids.size();
    LOG(DEBUG) << __func__ << ": id count: " << in_ids.size();
    (void)_aidl_return;
    (void)_aidl_return;
    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
}


template <class Metadata>
ndk::ScopedAStatus StreamCommonImpl::setVendorParameters(
ndk::ScopedAStatus StreamCommonImpl<Metadata>::setVendorParameters(
        const std::vector<VendorParameter>& in_parameters, bool in_async) {
        const std::vector<VendorParameter>& in_parameters, bool in_async) {
    LOG(DEBUG) << __func__ << ": parameters count " << in_parameters.size()
    LOG(DEBUG) << __func__ << ": parameters count " << in_parameters.size()
               << ", async: " << in_async;
               << ", async: " << in_async;
    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
}


template <class Metadata>
ndk::ScopedAStatus StreamCommonImpl::addEffect(
ndk::ScopedAStatus StreamCommonImpl<Metadata>::addEffect(
        const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect) {
        const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect) {
    if (in_effect == nullptr) {
    if (in_effect == nullptr) {
        LOG(DEBUG) << __func__ << ": null effect";
        LOG(DEBUG) << __func__ << ": null effect";
@@ -631,8 +625,7 @@ ndk::ScopedAStatus StreamCommonImpl<Metadata>::addEffect(
    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
}


template <class Metadata>
ndk::ScopedAStatus StreamCommonImpl::removeEffect(
ndk::ScopedAStatus StreamCommonImpl<Metadata>::removeEffect(
        const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect) {
        const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect) {
    if (in_effect == nullptr) {
    if (in_effect == nullptr) {
        LOG(DEBUG) << __func__ << ": null effect";
        LOG(DEBUG) << __func__ << ": null effect";
@@ -642,8 +635,7 @@ ndk::ScopedAStatus StreamCommonImpl<Metadata>::removeEffect(
    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
}


template <class Metadata>
ndk::ScopedAStatus StreamCommonImpl::close() {
ndk::ScopedAStatus StreamCommonImpl<Metadata>::close() {
    LOG(DEBUG) << __func__;
    LOG(DEBUG) << __func__;
    if (!isClosed()) {
    if (!isClosed()) {
        stopWorker();
        stopWorker();
@@ -659,8 +651,7 @@ ndk::ScopedAStatus StreamCommonImpl<Metadata>::close() {
    }
    }
}
}


template <class Metadata>
ndk::ScopedAStatus StreamCommonImpl::prepareToClose() {
ndk::ScopedAStatus StreamCommonImpl<Metadata>::prepareToClose() {
    LOG(DEBUG) << __func__;
    LOG(DEBUG) << __func__;
    if (!isClosed()) {
    if (!isClosed()) {
        return ndk::ScopedAStatus::ok();
        return ndk::ScopedAStatus::ok();
@@ -669,8 +660,7 @@ ndk::ScopedAStatus StreamCommonImpl<Metadata>::prepareToClose() {
    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
}
}


template <class Metadata>
void StreamCommonImpl::stopWorker() {
void StreamCommonImpl<Metadata>::stopWorker() {
    if (auto commandMQ = mContext.getCommandMQ(); commandMQ != nullptr) {
    if (auto commandMQ = mContext.getCommandMQ(); commandMQ != nullptr) {
        LOG(DEBUG) << __func__ << ": asking the worker to exit...";
        LOG(DEBUG) << __func__ << ": asking the worker to exit...";
        auto cmd = StreamDescriptor::Command::make<StreamDescriptor::Command::Tag::halReservedExit>(
        auto cmd = StreamDescriptor::Command::make<StreamDescriptor::Command::Tag::halReservedExit>(
@@ -686,10 +676,12 @@ void StreamCommonImpl<Metadata>::stopWorker() {
    }
    }
}
}


template <class Metadata>
ndk::ScopedAStatus StreamCommonImpl::updateMetadataCommon(const Metadata& metadata) {
ndk::ScopedAStatus StreamCommonImpl<Metadata>::updateMetadata(const Metadata& metadata) {
    LOG(DEBUG) << __func__;
    LOG(DEBUG) << __func__;
    if (!isClosed()) {
    if (!isClosed()) {
        if (metadata.index() != mMetadata.index()) {
            LOG(FATAL) << __func__ << ": changing metadata variant is not allowed";
        }
        mMetadata = metadata;
        mMetadata = metadata;
        return ndk::ScopedAStatus::ok();
        return ndk::ScopedAStatus::ok();
    }
    }
@@ -697,12 +689,10 @@ ndk::ScopedAStatus StreamCommonImpl<Metadata>::updateMetadata(const Metadata& me
    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
}
}


// static
ndk::ScopedAStatus StreamCommonImpl::setConnectedDevices(
ndk::ScopedAStatus StreamIn::initInstance(const std::shared_ptr<StreamIn>& stream) {
        const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) {
    if (auto status = stream->init(); !status.isOk()) {
    mWorker->setIsConnected(!devices.empty());
        return status;
    mConnectedDevices = devices;
    }
    stream->createStreamCommon(stream);
    return ndk::ScopedAStatus::ok();
    return ndk::ScopedAStatus::ok();
}
}


@@ -716,12 +706,8 @@ static std::map<AudioDevice, std::string> transformMicrophones(
}
}
}  // namespace
}  // namespace


StreamIn::StreamIn(const SinkMetadata& sinkMetadata, StreamContext&& context,
StreamIn::StreamIn(const std::vector<MicrophoneInfo>& microphones)
                   const DriverInterface::CreateInstance& createDriver,
    : mMicrophones(transformMicrophones(microphones)) {
                   const StreamWorkerInterface::CreateInstance& createWorker,
                   const std::vector<MicrophoneInfo>& microphones)
    : StreamCommonImpl<SinkMetadata>(sinkMetadata, std::move(context), createDriver, createWorker),
      mMicrophones(transformMicrophones(microphones)) {
    LOG(DEBUG) << __func__;
    LOG(DEBUG) << __func__;
}
}


@@ -729,9 +715,9 @@ ndk::ScopedAStatus StreamIn::getActiveMicrophones(
        std::vector<MicrophoneDynamicInfo>* _aidl_return) {
        std::vector<MicrophoneDynamicInfo>* _aidl_return) {
    std::vector<MicrophoneDynamicInfo> result;
    std::vector<MicrophoneDynamicInfo> result;
    std::vector<MicrophoneDynamicInfo::ChannelMapping> channelMapping{
    std::vector<MicrophoneDynamicInfo::ChannelMapping> channelMapping{
            getChannelCount(mContext.getChannelLayout()),
            getChannelCount(getContext().getChannelLayout()),
            MicrophoneDynamicInfo::ChannelMapping::DIRECT};
            MicrophoneDynamicInfo::ChannelMapping::DIRECT};
    for (auto it = mConnectedDevices.begin(); it != mConnectedDevices.end(); ++it) {
    for (auto it = getConnectedDevices().begin(); it != getConnectedDevices().end(); ++it) {
        if (auto micIt = mMicrophones.find(*it); micIt != mMicrophones.end()) {
        if (auto micIt = mMicrophones.find(*it); micIt != mMicrophones.end()) {
            MicrophoneDynamicInfo dynMic;
            MicrophoneDynamicInfo dynMic;
            dynMic.id = micIt->second;
            dynMic.id = micIt->second;
@@ -777,22 +763,8 @@ ndk::ScopedAStatus StreamIn::setHwGain(const std::vector<float>& in_channelGains
    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
}


// static
StreamOut::StreamOut(const std::optional<AudioOffloadInfo>& offloadInfo)
ndk::ScopedAStatus StreamOut::initInstance(const std::shared_ptr<StreamOut>& stream) {
    : mOffloadInfo(offloadInfo) {
    if (auto status = stream->init(); !status.isOk()) {
        return status;
    }
    stream->createStreamCommon(stream);
    return ndk::ScopedAStatus::ok();
}

StreamOut::StreamOut(const SourceMetadata& sourceMetadata, StreamContext&& context,
                     const DriverInterface::CreateInstance& createDriver,
                     const StreamWorkerInterface::CreateInstance& createWorker,
                     const std::optional<AudioOffloadInfo>& offloadInfo)
    : StreamCommonImpl<SourceMetadata>(sourceMetadata, std::move(context), createDriver,
                                       createWorker),
      mOffloadInfo(offloadInfo) {
    LOG(DEBUG) << __func__;
    LOG(DEBUG) << __func__;
}
}


+15 −36
Original line number Original line Diff line number Diff line
@@ -31,33 +31,34 @@ using aidl::android::media::audio::common::MicrophoneInfo;


namespace aidl::android::hardware::audio::core {
namespace aidl::android::hardware::audio::core {


DriverStub::DriverStub(const StreamContext& context, bool isInput)
StreamStub::StreamStub(const Metadata& metadata, StreamContext&& context)
    : mFrameSizeBytes(context.getFrameSize()),
    : StreamCommonImpl(metadata, std::move(context)),
      mFrameSizeBytes(context.getFrameSize()),
      mSampleRate(context.getSampleRate()),
      mSampleRate(context.getSampleRate()),
      mIsAsynchronous(!!context.getAsyncCallback()),
      mIsAsynchronous(!!context.getAsyncCallback()),
      mIsInput(isInput) {}
      mIsInput(isInput(metadata)) {}


::android::status_t DriverStub::init() {
::android::status_t StreamStub::init() {
    usleep(500);
    usleep(500);
    return ::android::OK;
    return ::android::OK;
}
}


::android::status_t DriverStub::drain(StreamDescriptor::DrainMode) {
::android::status_t StreamStub::drain(StreamDescriptor::DrainMode) {
    usleep(500);
    usleep(500);
    return ::android::OK;
    return ::android::OK;
}
}


::android::status_t DriverStub::flush() {
::android::status_t StreamStub::flush() {
    usleep(500);
    usleep(500);
    return ::android::OK;
    return ::android::OK;
}
}


::android::status_t DriverStub::pause() {
::android::status_t StreamStub::pause() {
    usleep(500);
    usleep(500);
    return ::android::OK;
    return ::android::OK;
}
}


::android::status_t DriverStub::transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
::android::status_t StreamStub::transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
                                         int32_t* latencyMs) {
                                         int32_t* latencyMs) {
    static constexpr float kMicrosPerSecond = MICROS_PER_SECOND;
    static constexpr float kMicrosPerSecond = MICROS_PER_SECOND;
    static constexpr float kScaleFactor = .8f;
    static constexpr float kScaleFactor = .8f;
@@ -79,16 +80,12 @@ DriverStub::DriverStub(const StreamContext& context, bool isInput)
    return ::android::OK;
    return ::android::OK;
}
}


::android::status_t DriverStub::standby() {
::android::status_t StreamStub::standby() {
    usleep(500);
    usleep(500);
    return ::android::OK;
    return ::android::OK;
}
}


::android::status_t DriverStub::setConnectedDevices(
void StreamStub::shutdown() {}
        const std::vector<AudioDevice>& connectedDevices __unused) {
    usleep(500);
    return ::android::OK;
}


// static
// static
ndk::ScopedAStatus StreamInStub::createInstance(const SinkMetadata& sinkMetadata,
ndk::ScopedAStatus StreamInStub::createInstance(const SinkMetadata& sinkMetadata,
@@ -97,7 +94,7 @@ ndk::ScopedAStatus StreamInStub::createInstance(const SinkMetadata& sinkMetadata
                                                std::shared_ptr<StreamIn>* result) {
                                                std::shared_ptr<StreamIn>* result) {
    std::shared_ptr<StreamIn> stream =
    std::shared_ptr<StreamIn> stream =
            ndk::SharedRefBase::make<StreamInStub>(sinkMetadata, std::move(context), microphones);
            ndk::SharedRefBase::make<StreamInStub>(sinkMetadata, std::move(context), microphones);
    if (auto status = initInstance(stream); !status.isOk()) {
    if (auto status = stream->initInstance(stream); !status.isOk()) {
        return status;
        return status;
    }
    }
    *result = std::move(stream);
    *result = std::move(stream);
@@ -106,16 +103,7 @@ ndk::ScopedAStatus StreamInStub::createInstance(const SinkMetadata& sinkMetadata


StreamInStub::StreamInStub(const SinkMetadata& sinkMetadata, StreamContext&& context,
StreamInStub::StreamInStub(const SinkMetadata& sinkMetadata, StreamContext&& context,
                           const std::vector<MicrophoneInfo>& microphones)
                           const std::vector<MicrophoneInfo>& microphones)
    : StreamIn(
    : StreamStub(sinkMetadata, std::move(context)), StreamIn(microphones) {}
              sinkMetadata, std::move(context),
              [](const StreamContext& ctx) -> DriverInterface* {
                  return new DriverStub(ctx, true /*isInput*/);
              },
              [](const StreamContext& ctx, DriverInterface* driver) -> StreamWorkerInterface* {
                  // The default worker implementation is used.
                  return new StreamInWorker(ctx, driver);
              },
              microphones) {}


// static
// static
ndk::ScopedAStatus StreamOutStub::createInstance(const SourceMetadata& sourceMetadata,
ndk::ScopedAStatus StreamOutStub::createInstance(const SourceMetadata& sourceMetadata,
@@ -124,7 +112,7 @@ ndk::ScopedAStatus StreamOutStub::createInstance(const SourceMetadata& sourceMet
                                                 std::shared_ptr<StreamOut>* result) {
                                                 std::shared_ptr<StreamOut>* result) {
    std::shared_ptr<StreamOut> stream = ndk::SharedRefBase::make<StreamOutStub>(
    std::shared_ptr<StreamOut> stream = ndk::SharedRefBase::make<StreamOutStub>(
            sourceMetadata, std::move(context), offloadInfo);
            sourceMetadata, std::move(context), offloadInfo);
    if (auto status = initInstance(stream); !status.isOk()) {
    if (auto status = stream->initInstance(stream); !status.isOk()) {
        return status;
        return status;
    }
    }
    *result = std::move(stream);
    *result = std::move(stream);
@@ -133,15 +121,6 @@ ndk::ScopedAStatus StreamOutStub::createInstance(const SourceMetadata& sourceMet


StreamOutStub::StreamOutStub(const SourceMetadata& sourceMetadata, StreamContext&& context,
StreamOutStub::StreamOutStub(const SourceMetadata& sourceMetadata, StreamContext&& context,
                             const std::optional<AudioOffloadInfo>& offloadInfo)
                             const std::optional<AudioOffloadInfo>& offloadInfo)
    : StreamOut(
    : StreamStub(sourceMetadata, std::move(context)), StreamOut(offloadInfo) {}
              sourceMetadata, std::move(context),
              [](const StreamContext& ctx) -> DriverInterface* {
                  return new DriverStub(ctx, false /*isInput*/);
              },
              [](const StreamContext& ctx, DriverInterface* driver) -> StreamWorkerInterface* {
                  // The default worker implementation is used.
                  return new StreamOutWorker(ctx, driver);
              },
              offloadInfo) {}


}  // namespace aidl::android::hardware::audio::core
}  // namespace aidl::android::hardware::audio::core
+95 −94

File changed.

Preview size limit exceeded, changes collapsed.

+6 −8
Original line number Original line Diff line number Diff line
@@ -20,9 +20,10 @@


namespace aidl::android::hardware::audio::core {
namespace aidl::android::hardware::audio::core {


class DriverStub : public DriverInterface {
class StreamStub : public StreamCommonImpl {
  public:
  public:
    DriverStub(const StreamContext& context, bool isInput);
    StreamStub(const Metadata& metadata, StreamContext&& context);
    // Methods of 'DriverInterface'.
    ::android::status_t init() override;
    ::android::status_t init() override;
    ::android::status_t drain(StreamDescriptor::DrainMode) override;
    ::android::status_t drain(StreamDescriptor::DrainMode) override;
    ::android::status_t flush() override;
    ::android::status_t flush() override;
@@ -30,10 +31,7 @@ class DriverStub : public DriverInterface {
    ::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
    ::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
                                 int32_t* latencyMs) override;
                                 int32_t* latencyMs) override;
    ::android::status_t standby() override;
    ::android::status_t standby() override;
    // Note: called on a different thread.
    void shutdown() override;
    ::android::status_t setConnectedDevices(
            const std::vector<::aidl::android::media::audio::common::AudioDevice>& connectedDevices)
            override;


  private:
  private:
    const size_t mFrameSizeBytes;
    const size_t mFrameSizeBytes;
@@ -42,7 +40,7 @@ class DriverStub : public DriverInterface {
    const bool mIsInput;
    const bool mIsInput;
};
};


class StreamInStub final : public StreamIn {
class StreamInStub final : public StreamStub, public StreamIn {
  public:
  public:
    static ndk::ScopedAStatus createInstance(
    static ndk::ScopedAStatus createInstance(
            const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
            const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
@@ -58,7 +56,7 @@ class StreamInStub final : public StreamIn {
            const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones);
            const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones);
};
};


class StreamOutStub final : public StreamOut {
class StreamOutStub final : public StreamStub, public StreamOut {
  public:
  public:
    static ndk::ScopedAStatus createInstance(
    static ndk::ScopedAStatus createInstance(
            const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
            const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
+11 −12
Original line number Original line Diff line number Diff line
@@ -30,9 +30,10 @@ extern "C" {


namespace aidl::android::hardware::audio::core {
namespace aidl::android::hardware::audio::core {


class DriverUsb : public DriverInterface {
class StreamUsb : public StreamCommonImpl {
  public:
  public:
    DriverUsb(const StreamContext& context, bool isInput);
    StreamUsb(const Metadata& metadata, StreamContext&& context);
    // Methods of 'DriverInterface'.
    ::android::status_t init() override;
    ::android::status_t init() override;
    ::android::status_t drain(StreamDescriptor::DrainMode) override;
    ::android::status_t drain(StreamDescriptor::DrainMode) override;
    ::android::status_t flush() override;
    ::android::status_t flush() override;
@@ -40,27 +41,25 @@ class DriverUsb : public DriverInterface {
    ::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
    ::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
                                 int32_t* latencyMs) override;
                                 int32_t* latencyMs) override;
    ::android::status_t standby() override;
    ::android::status_t standby() override;
    // Note: called on a different thread.
    void shutdown() override;
    ::android::status_t setConnectedDevices(

            const std::vector<::aidl::android::media::audio::common::AudioDevice>& connectedDevices)
    // Overridden methods of 'StreamCommonImpl', called on a Binder thread.
            override;
    const ConnectedDevices& getConnectedDevices() const override;
    ndk::ScopedAStatus setConnectedDevices(const ConnectedDevices& devices) override;


  private:
  private:
    ::android::status_t exitStandby();
    ::android::status_t exitStandby();


    std::mutex mLock;
    mutable std::mutex mLock;


    const size_t mFrameSizeBytes;
    const size_t mFrameSizeBytes;
    std::optional<struct pcm_config> mConfig;
    std::optional<struct pcm_config> mConfig;
    const bool mIsInput;
    const bool mIsInput;
    // Cached device addresses for connected devices.
    std::vector<::aidl::android::media::audio::common::AudioDeviceAddress> mConnectedDevices
            GUARDED_BY(mLock);
    std::vector<std::shared_ptr<alsa_device_proxy>> mAlsaDeviceProxies GUARDED_BY(mLock);
    std::vector<std::shared_ptr<alsa_device_proxy>> mAlsaDeviceProxies GUARDED_BY(mLock);
    bool mIsStandby = true;
    bool mIsStandby = true;
};
};


class StreamInUsb final : public StreamIn {
class StreamInUsb final : public StreamUsb, public StreamIn {
    ndk::ScopedAStatus getActiveMicrophones(
    ndk::ScopedAStatus getActiveMicrophones(
            std::vector<::aidl::android::media::audio::common::MicrophoneDynamicInfo>* _aidl_return)
            std::vector<::aidl::android::media::audio::common::MicrophoneDynamicInfo>* _aidl_return)
            override;
            override;
@@ -80,7 +79,7 @@ class StreamInUsb final : public StreamIn {
            const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones);
            const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones);
};
};


class StreamOutUsb final : public StreamOut {
class StreamOutUsb final : public StreamUsb, public StreamOut {
  public:
  public:
    static ndk::ScopedAStatus createInstance(
    static ndk::ScopedAStatus createInstance(
            const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
            const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
Loading