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

Commit 19d08c00 authored by Mikhail Naganov's avatar Mikhail Naganov
Browse files

audio: Add DriverInterface::start method

This method is used to bring out the hardware from standby.
It replaces the ad hoc 'exitStandby' method in StreamUsb.

Streamlined StreamUsb code to avoid locking during transfers.

Updated StreamRemoteSubmix to use 'start'.

Added extra checks to StreamStub to ensure that 'init/shutdown'
and 'standby/start' methods are called as expected. This allows
removing extra checks from non-stub stream implementations.

Bug: 205884982
Test: atest VtsHalAudioCoreTargetTest
Merged-In: I3615a7ca99cb4f1e149dcbfbc912f2ed58fb033f
Change-Id: I3615a7ca99cb4f1e149dcbfbc912f2ed58fb033f
(cherry picked from commit 49712b56)
parent 588943ab
Loading
Loading
Loading
Loading
+27 −12
Original line number Diff line number Diff line
@@ -166,10 +166,15 @@ StreamInWorkerLogic::Status StreamInWorkerLogic::cycle() {
        case Tag::start:
            if (mState == StreamDescriptor::State::STANDBY ||
                mState == StreamDescriptor::State::DRAINING) {
                if (::android::status_t status = mDriver->start(); status == ::android::OK) {
                    populateReply(&reply, mIsConnected);
                    mState = mState == StreamDescriptor::State::STANDBY
                                     ? StreamDescriptor::State::IDLE
                                     : StreamDescriptor::State::ACTIVE;
                } else {
                    LOG(ERROR) << __func__ << ": start failed: " << status;
                    mState = StreamDescriptor::State::ERROR;
                }
            } else {
                populateReplyWrongState(&reply, command);
            }
@@ -377,26 +382,36 @@ StreamOutWorkerLogic::Status StreamOutWorkerLogic::cycle() {
            populateReply(&reply, mIsConnected);
            break;
        case Tag::start: {
            bool commandAccepted = true;
            std::optional<StreamDescriptor::State> nextState;
            switch (mState) {
                case StreamDescriptor::State::STANDBY:
                    mState = StreamDescriptor::State::IDLE;
                    nextState = StreamDescriptor::State::IDLE;
                    break;
                case StreamDescriptor::State::PAUSED:
                    mState = StreamDescriptor::State::ACTIVE;
                    nextState = StreamDescriptor::State::ACTIVE;
                    break;
                case StreamDescriptor::State::DRAIN_PAUSED:
                    switchToTransientState(StreamDescriptor::State::DRAINING);
                    nextState = StreamDescriptor::State::DRAINING;
                    break;
                case StreamDescriptor::State::TRANSFER_PAUSED:
                    switchToTransientState(StreamDescriptor::State::TRANSFERRING);
                    nextState = StreamDescriptor::State::TRANSFERRING;
                    break;
                default:
                    populateReplyWrongState(&reply, command);
                    commandAccepted = false;
            }
            if (commandAccepted) {
            if (nextState.has_value()) {
                if (::android::status_t status = mDriver->start(); status == ::android::OK) {
                    populateReply(&reply, mIsConnected);
                    if (*nextState == StreamDescriptor::State::IDLE ||
                        *nextState == StreamDescriptor::State::ACTIVE) {
                        mState = *nextState;
                    } else {
                        switchToTransientState(*nextState);
                    }
                } else {
                    LOG(ERROR) << __func__ << ": start failed: " << status;
                    mState = StreamDescriptor::State::ERROR;
                }
            }
        } break;
        case Tag::burst:
+39 −8
Original line number Diff line number Diff line
@@ -33,33 +33,67 @@ namespace aidl::android::hardware::audio::core {

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

::android::status_t StreamStub::init() {
    mIsInitialized = true;
    usleep(500);
    return ::android::OK;
}

::android::status_t StreamStub::drain(StreamDescriptor::DrainMode) {
    if (!mIsInitialized) {
        LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
    }
    usleep(500);
    return ::android::OK;
}

::android::status_t StreamStub::flush() {
    if (!mIsInitialized) {
        LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
    }
    usleep(500);
    return ::android::OK;
}

::android::status_t StreamStub::pause() {
    if (!mIsInitialized) {
        LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
    }
    usleep(500);
    return ::android::OK;
}

::android::status_t StreamStub::standby() {
    if (!mIsInitialized) {
        LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
    }
    usleep(500);
    mIsStandby = true;
    return ::android::OK;
}

::android::status_t StreamStub::start() {
    if (!mIsInitialized) {
        LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
    }
    usleep(500);
    mIsStandby = false;
    return ::android::OK;
}

::android::status_t StreamStub::transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
                                         int32_t* latencyMs) {
    if (!mIsInitialized) {
        LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
    }
    if (mIsStandby) {
        LOG(FATAL) << __func__ << ": must not happen while in standby";
    }
    static constexpr float kMicrosPerSecond = MICROS_PER_SECOND;
    static constexpr float kScaleFactor = .8f;
    if (mIsAsynchronous) {
@@ -80,13 +114,10 @@ StreamStub::StreamStub(const Metadata& metadata, StreamContext&& context)
    return ::android::OK;
}

::android::status_t StreamStub::standby() {
    usleep(500);
    return ::android::OK;
void StreamStub::shutdown() {
    mIsInitialized = false;
}

void StreamStub::shutdown() {}

StreamInStub::StreamInStub(const SinkMetadata& sinkMetadata, StreamContext&& context,
                           const std::vector<MicrophoneInfo>& microphones)
    : StreamStub(sinkMetadata, std::move(context)), StreamIn(microphones) {}
+2 −1
Original line number Diff line number Diff line
@@ -180,9 +180,10 @@ struct DriverInterface {
    virtual ::android::status_t drain(StreamDescriptor::DrainMode mode) = 0;
    virtual ::android::status_t flush() = 0;
    virtual ::android::status_t pause() = 0;
    virtual ::android::status_t standby() = 0;
    virtual ::android::status_t start() = 0;
    virtual ::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
                                         int32_t* latencyMs) = 0;
    virtual ::android::status_t standby() = 0;
    virtual void shutdown() = 0;  // This function is only called once.
};

+2 −2
Original line number Diff line number Diff line
@@ -35,9 +35,10 @@ class StreamRemoteSubmix : public StreamCommonImpl {
    ::android::status_t drain(StreamDescriptor::DrainMode) override;
    ::android::status_t flush() override;
    ::android::status_t pause() override;
    ::android::status_t standby() override;
    ::android::status_t start() override;
    ::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
                                 int32_t* latencyMs) override;
    ::android::status_t standby() override;
    void shutdown() override;

    // Overridden methods of 'StreamCommonImpl', called on a Binder thread.
@@ -53,7 +54,6 @@ class StreamRemoteSubmix : public StreamCommonImpl {
    const bool mIsInput;
    AudioConfig mStreamConfig;
    std::shared_ptr<SubmixRoute> mCurrentRoute = nullptr;
    ::android::status_t mStatus = ::android::NO_INIT;

    // 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.
+4 −1
Original line number Diff line number Diff line
@@ -28,9 +28,10 @@ class StreamStub : public StreamCommonImpl {
    ::android::status_t drain(StreamDescriptor::DrainMode) override;
    ::android::status_t flush() override;
    ::android::status_t pause() override;
    ::android::status_t standby() override;
    ::android::status_t start() override;
    ::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
                                 int32_t* latencyMs) override;
    ::android::status_t standby() override;
    void shutdown() override;

  private:
@@ -38,6 +39,8 @@ class StreamStub : public StreamCommonImpl {
    const int mSampleRate;
    const bool mIsAsynchronous;
    const bool mIsInput;
    bool mIsInitialized = false;  // Used for validating the state machine logic.
    bool mIsStandby = true;       // Used for validating the state machine logic.
};

class StreamInStub final : public StreamStub, public StreamIn {
Loading