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

Commit 79774680 authored by Andy Hung's avatar Andy Hung Committed by Android (Google) Code Review
Browse files

Merge "AudioFlinger: Add MmapThread interfaces" into main

parents 5f55b0d4 7aa7d10f
Loading
Loading
Loading
Loading
+17 −15
Original line number Diff line number Diff line
@@ -678,9 +678,9 @@ status_t AudioFlinger::openMmapStream(MmapStreamInterface::stream_direction_t di

    // at this stage, a MmapThread was created when openOutput() or openInput() was called by
    // audio policy manager and we can retrieve it
    sp<MmapThread> thread = mMmapThreads.valueFor(io);
    const sp<IAfMmapThread> thread = mMmapThreads.valueFor(io);
    if (thread != 0) {
        interface = new MmapThreadHandle(thread);
        interface = IAfMmapThread::createMmapStreamInterfaceAdapter(thread);
        thread->configure(&localAttr, streamType, actualSessionId, callback, *deviceId, portId);
        *handle = portId;
        *sessionId = actualSessionId;
@@ -3039,7 +3039,7 @@ sp<IAfThreadBase> AudioFlinger::openOutput_l(audio_module_handle_t module,

    if (status == NO_ERROR) {
        if (flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) {
            sp<MmapPlaybackThread> thread =
            const sp<IAfMmapPlaybackThread> thread =
                    new MmapPlaybackThread(this, *output, outHwDev, outputStream, mSystemReady);
            mMmapThreads.add(*output, thread);
            ALOGV("openOutput_l() created mmap playback thread: ID %d thread %p",
@@ -3190,7 +3190,7 @@ status_t AudioFlinger::closeOutput_nonvirtual(audio_io_handle_t output)
    // keep strong reference on the playback thread so that
    // it is not destroyed while exit() is executed
    sp<IAfPlaybackThread> playbackThread;
    sp<MmapPlaybackThread> mmapThread;
    sp<IAfMmapPlaybackThread> mmapThread;
    {
        Mutex::Autolock _l(mLock);
        playbackThread = checkPlaybackThread_l(output);
@@ -3227,7 +3227,8 @@ status_t AudioFlinger::closeOutput_nonvirtual(audio_io_handle_t output)
                }
            }
        } else {
            mmapThread = (MmapPlaybackThread *)checkMmapThread_l(output);
            const sp<IAfMmapThread> mt = checkMmapThread_l(output);
            mmapThread = mt ? mt->asIAfMmapPlaybackThread().get() : nullptr;
            if (mmapThread == 0) {
                return BAD_VALUE;
            }
@@ -3409,7 +3410,7 @@ sp<IAfThreadBase> AudioFlinger::openInput_l(audio_module_handle_t module,
    if (status == NO_ERROR && inStream != 0) {
        AudioStreamIn *inputStream = new AudioStreamIn(inHwDev, inStream, flags);
        if ((flags & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0) {
            sp<MmapCaptureThread> thread =
            const sp<IAfMmapCaptureThread> thread =
                    new MmapCaptureThread(this, *input, inHwDev, inputStream, mSystemReady);
            mMmapThreads.add(*input, thread);
            ALOGV("openInput_l() created mmap capture thread: ID %d thread %p", *input,
@@ -3441,7 +3442,7 @@ status_t AudioFlinger::closeInput_nonvirtual(audio_io_handle_t input)
    // keep strong reference on the record thread so that
    // it is not destroyed while exit() is executed
    sp<IAfRecordThread> recordThread;
    sp<MmapCaptureThread> mmapThread;
    sp<IAfMmapCaptureThread> mmapThread;
    {
        Mutex::Autolock _l(mLock);
        recordThread = checkRecordThread_l(input);
@@ -3488,7 +3489,8 @@ status_t AudioFlinger::closeInput_nonvirtual(audio_io_handle_t input)
            }
            mRecordThreads.removeItem(input);
        } else {
            mmapThread = (MmapCaptureThread *)checkMmapThread_l(input);
            const sp<IAfMmapThread> mt = checkMmapThread_l(input);
            mmapThread = mt ? mt->asIAfMmapCaptureThread().get() : nullptr;
            if (mmapThread == 0) {
                return BAD_VALUE;
            }
@@ -3678,7 +3680,7 @@ std::vector<sp<IAfEffectModule>> AudioFlinger::purgeStaleEffects_l() {
    }

    for (size_t i = 0; i < mMmapThreads.size(); i++) {
        sp<MmapThread> t = mMmapThreads.valueAt(i);
        const sp<IAfMmapThread> t = mMmapThreads.valueAt(i);
        Mutex::Autolock _l(t->mutex());
        const Vector<sp<IAfEffectChain>> threadChains = t->getEffectChains_l();
        for (size_t j = 0; j < threadChains.size(); j++) {
@@ -3824,7 +3826,7 @@ IAfRecordThread* AudioFlinger::checkRecordThread_l(audio_io_handle_t input) cons
}

// checkMmapThread_l() must be called with AudioFlinger::mLock held
AudioFlinger::MmapThread *AudioFlinger::checkMmapThread_l(audio_io_handle_t io) const
IAfMmapThread* AudioFlinger::checkMmapThread_l(audio_io_handle_t io) const
{
    return mMmapThreads.valueFor(io).get();
}
@@ -3835,11 +3837,11 @@ sp<VolumeInterface> AudioFlinger::getVolumeInterface_l(audio_io_handle_t output)
{
    sp<VolumeInterface> volumeInterface = mPlaybackThreads.valueFor(output).get();
    if (volumeInterface == nullptr) {
        MmapThread *mmapThread = mMmapThreads.valueFor(output).get();
        IAfMmapThread* const mmapThread = mMmapThreads.valueFor(output).get();
        if (mmapThread != nullptr) {
            if (mmapThread->isOutput()) {
                MmapPlaybackThread *mmapPlaybackThread =
                        static_cast<MmapPlaybackThread *>(mmapThread);
                IAfMmapPlaybackThread* const mmapPlaybackThread =
                        mmapThread->asIAfMmapPlaybackThread().get();
                volumeInterface = mmapPlaybackThread;
            }
        }
@@ -3855,8 +3857,8 @@ std::vector<sp<VolumeInterface>> AudioFlinger::getAllVolumeInterfaces_l() const
    }
    for (size_t i = 0; i < mMmapThreads.size(); i++) {
        if (mMmapThreads.valueAt(i)->isOutput()) {
            MmapPlaybackThread *mmapPlaybackThread =
                    static_cast<MmapPlaybackThread *>(mMmapThreads.valueAt(i).get());
            IAfMmapPlaybackThread* const mmapPlaybackThread =
                    mMmapThreads.valueAt(i)->asIAfMmapPlaybackThread().get();
            volumeInterfaces.push_back(mmapPlaybackThread);
        }
    }
+2 −25
Original line number Diff line number Diff line
@@ -613,35 +613,12 @@ private:
        return io;
    }

    // Mmap stream control interface implementation. Each MmapThreadHandle controls one
    // MmapPlaybackThread or MmapCaptureThread instance.
    class MmapThreadHandle : public MmapStreamInterface {
    public:
        explicit            MmapThreadHandle(const sp<MmapThread>& thread);
        virtual             ~MmapThreadHandle();

        // MmapStreamInterface virtuals
        virtual status_t createMmapBuffer(int32_t minSizeFrames,
                                          struct audio_mmap_buffer_info *info);
        virtual status_t getMmapPosition(struct audio_mmap_position *position);
        virtual status_t getExternalPosition(uint64_t *position, int64_t *timeNanos);
        virtual status_t start(const AudioClient& client,
                               const audio_attributes_t *attr,
                               audio_port_handle_t *handle);
        virtual status_t stop(audio_port_handle_t handle);
        virtual status_t standby();
                status_t reportData(const void* buffer, size_t frameCount) override;

    private:
        const sp<MmapThread> mThread;
    };

    IAfThreadBase* checkThread_l(audio_io_handle_t ioHandle) const;
    sp<IAfThreadBase> checkOutputThread_l(audio_io_handle_t ioHandle) const REQUIRES(mLock);
    IAfPlaybackThread* checkPlaybackThread_l(audio_io_handle_t output) const;
    IAfPlaybackThread* checkMixerThread_l(audio_io_handle_t output) const;
    IAfRecordThread* checkRecordThread_l(audio_io_handle_t input) const;
              MmapThread *checkMmapThread_l(audio_io_handle_t io) const;
    IAfMmapThread* checkMmapThread_l(audio_io_handle_t io) const;
              sp<VolumeInterface> getVolumeInterface_l(audio_io_handle_t output) const;
              std::vector<sp<VolumeInterface>> getAllVolumeInterfaces_l() const;

@@ -865,7 +842,7 @@ private:
                // list of MMAP stream control threads. Those threads allow for wake lock, routing
                // and volume control for activity on the associated MMAP stream at the HAL.
                // Audio data transfer is directly handled by the client creating the MMAP stream
                DefaultKeyedVector< audio_io_handle_t, sp<MmapThread> >  mMmapThreads;
    DefaultKeyedVector<audio_io_handle_t, sp<IAfMmapThread>> mMmapThreads;

private:
    sp<Client>  registerPid(pid_t pid);    // always returns non-0
+53 −0
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ namespace android {

class IAfDirectOutputThread;
class IAfDuplicatingThread;
class IAfMmapCaptureThread;
class IAfMmapPlaybackThread;
class IAfPlaybackThread;
class IAfRecordThread;

@@ -429,4 +431,55 @@ public:
    virtual void resetAudioHistory_l() = 0;
};

class IAfMmapThread : public virtual IAfThreadBase {
public:
    // createIAudioTrackAdapter() is a static constructor which creates an
    // MmapStreamInterface AIDL interface adapter from the MmapThread object that
    // may be passed back to the client.
    //
    // Only one AIDL MmapStreamInterface interface adapter should be created per MmapThread.
    static sp<MmapStreamInterface> createMmapStreamInterfaceAdapter(
            const sp<IAfMmapThread>& mmapThread);

    virtual void configure(
            const audio_attributes_t* attr,
            audio_stream_type_t streamType,
            audio_session_t sessionId,
            const sp<MmapStreamCallback>& callback,
            audio_port_handle_t deviceId,
            audio_port_handle_t portId) = 0;
    virtual void disconnect() = 0;

    // MmapStreamInterface handling (see adapter)
    virtual status_t createMmapBuffer(
            int32_t minSizeFrames, struct audio_mmap_buffer_info* info) = 0;
    virtual status_t getMmapPosition(struct audio_mmap_position* position) const = 0;
    virtual status_t start(
            const AudioClient& client, const audio_attributes_t* attr,
            audio_port_handle_t* handle) = 0;
    virtual status_t stop(audio_port_handle_t handle) = 0;
    virtual status_t standby() = 0;
    virtual status_t getExternalPosition(uint64_t* position, int64_t* timeNanos) const = 0;
    virtual status_t reportData(const void* buffer, size_t frameCount) = 0;

    // TODO(b/288339104)  move to IAfThreadBase?
    virtual void invalidateTracks(std::set<audio_port_handle_t>& portIds) = 0;

    // Sets the UID records silence - TODO(b/288339104)  move to IAfMmapCaptureThread
    virtual void setRecordSilenced(audio_port_handle_t portId, bool silenced) = 0;

    virtual sp<IAfMmapPlaybackThread> asIAfMmapPlaybackThread() { return nullptr; }
    virtual sp<IAfMmapCaptureThread> asIAfMmapCaptureThread() { return nullptr; }
};

class IAfMmapPlaybackThread : public virtual IAfMmapThread, public virtual VolumeInterface {
public:
    virtual AudioStreamOut* clearOutput() = 0;
};

class IAfMmapCaptureThread : public virtual IAfMmapThread {
public:
    virtual AudioStreamIn* clearInput() = 0;
};

}  // namespace android
+40 −11
Original line number Diff line number Diff line
@@ -9773,51 +9773,80 @@ void AudioFlinger::RecordThread::toAudioPortConfig(struct audio_port_config *con
//      Mmap
// ----------------------------------------------------------------------------

AudioFlinger::MmapThreadHandle::MmapThreadHandle(const sp<MmapThread>& thread)
// Mmap stream control interface implementation. Each MmapThreadHandle controls one
// MmapPlaybackThread or MmapCaptureThread instance.
class MmapThreadHandle : public MmapStreamInterface {
public:
    explicit MmapThreadHandle(const sp<IAfMmapThread>& thread);
    ~MmapThreadHandle() override;

    // MmapStreamInterface virtuals
    status_t createMmapBuffer(int32_t minSizeFrames,
        struct audio_mmap_buffer_info* info) final;
    status_t getMmapPosition(struct audio_mmap_position* position) final;
    status_t getExternalPosition(uint64_t* position, int64_t* timeNanos) final;
    status_t start(const AudioClient& client,
           const audio_attributes_t* attr, audio_port_handle_t* handle) final;
    status_t stop(audio_port_handle_t handle) final;
    status_t standby() final;
    status_t reportData(const void* buffer, size_t frameCount) final;
private:
    const sp<IAfMmapThread> mThread;
};

/* static */
sp<MmapStreamInterface> IAfMmapThread::createMmapStreamInterfaceAdapter(
        const sp<IAfMmapThread>& mmapThread) {
    return sp<MmapThreadHandle>::make(mmapThread);
}

MmapThreadHandle::MmapThreadHandle(const sp<IAfMmapThread>& thread)
    : mThread(thread)
{
    assert(thread != 0); // thread must start non-null and stay non-null
}

AudioFlinger::MmapThreadHandle::~MmapThreadHandle()
// MmapStreamInterface could be directly implemented by MmapThread excepting this
// special handling on adapter dtor.
MmapThreadHandle::~MmapThreadHandle()
{
    mThread->disconnect();
}

status_t AudioFlinger::MmapThreadHandle::createMmapBuffer(int32_t minSizeFrames,
status_t MmapThreadHandle::createMmapBuffer(int32_t minSizeFrames,
                                  struct audio_mmap_buffer_info *info)
{
    return mThread->createMmapBuffer(minSizeFrames, info);
}

status_t AudioFlinger::MmapThreadHandle::getMmapPosition(struct audio_mmap_position *position)
status_t MmapThreadHandle::getMmapPosition(struct audio_mmap_position* position)
{
    return mThread->getMmapPosition(position);
}

status_t AudioFlinger::MmapThreadHandle::getExternalPosition(uint64_t *position,
status_t MmapThreadHandle::getExternalPosition(uint64_t* position,
                                                             int64_t *timeNanos) {
    return mThread->getExternalPosition(position, timeNanos);
}

status_t AudioFlinger::MmapThreadHandle::start(const AudioClient& client,
status_t MmapThreadHandle::start(const AudioClient& client,
        const audio_attributes_t *attr, audio_port_handle_t *handle)

{
    return mThread->start(client, attr, handle);
}

status_t AudioFlinger::MmapThreadHandle::stop(audio_port_handle_t handle)
status_t MmapThreadHandle::stop(audio_port_handle_t handle)
{
    return mThread->stop(handle);
}

status_t AudioFlinger::MmapThreadHandle::standby()
status_t MmapThreadHandle::standby()
{
    return mThread->standby();
}

status_t AudioFlinger::MmapThreadHandle::reportData(const void* buffer, size_t frameCount) {
status_t MmapThreadHandle::reportData(const void* buffer, size_t frameCount)
{
    return mThread->reportData(buffer, frameCount);
}

@@ -9891,7 +9920,7 @@ status_t AudioFlinger::MmapThread::createMmapBuffer(int32_t minSizeFrames,
    return mHalStream->createMmapBuffer(minSizeFrames, info);
}

status_t AudioFlinger::MmapThread::getMmapPosition(struct audio_mmap_position *position)
status_t AudioFlinger::MmapThread::getMmapPosition(struct audio_mmap_position* position) const
{
    if (mHalStream == 0) {
        return NO_INIT;
+28 −21
Original line number Diff line number Diff line
@@ -2041,7 +2041,7 @@ private:
            audio_session_t                     mSharedAudioSessionId = AUDIO_SESSION_NONE;
};

class MmapThread : public ThreadBase
class MmapThread : public ThreadBase, public virtual IAfMmapThread
{
 public:
    MmapThread(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
@@ -2049,26 +2049,25 @@ class MmapThread : public ThreadBase
               bool isOut);
    ~MmapThread() override;

    virtual     void        configure(const audio_attributes_t *attr,
    void configure(const audio_attributes_t* attr,
                                      audio_stream_type_t streamType,
                                      audio_session_t sessionId,
                                      const sp<MmapStreamCallback>& callback,
                                      audio_port_handle_t deviceId,
                                      audio_port_handle_t portId);
                                      audio_port_handle_t portId) override;

                void        disconnect();
    void disconnect() final;

    // MmapStreamInterface for adapter.
    virtual status_t createMmapBuffer(int32_t minSizeFrames,
                                      struct audio_mmap_buffer_info *info);
    virtual status_t getMmapPosition(struct audio_mmap_position* position);
    virtual status_t start(const AudioClient& client,
    status_t createMmapBuffer(int32_t minSizeFrames, struct audio_mmap_buffer_info* info) final;
    status_t getMmapPosition(struct audio_mmap_position* position) const override;
    status_t start(const AudioClient& client,
                   const audio_attributes_t *attr,
                   audio_port_handle_t *handle);
    virtual status_t stop(audio_port_handle_t handle);
    virtual status_t standby();
    virtual status_t getExternalPosition(uint64_t* position, int64_t* timeNanos) const = 0;
    virtual status_t reportData(const void* buffer, size_t frameCount);
            audio_port_handle_t* handle) final;
    status_t stop(audio_port_handle_t handle) final;
    status_t standby() final;
    status_t getExternalPosition(uint64_t* position, int64_t* timeNanos) const = 0;
    status_t reportData(const void* buffer, size_t frameCount) override;

    // RefBase
    void onFirstRef() final;
@@ -2115,11 +2114,11 @@ class MmapThread : public ThreadBase
    // Not in ThreadBase
    virtual audio_stream_type_t streamType() const { return AUDIO_STREAM_DEFAULT; }
    virtual void invalidateTracks(audio_stream_type_t /* streamType */) {}
    virtual void invalidateTracks(std::set<audio_port_handle_t>& /* portIds */) {}
    void invalidateTracks(std::set<audio_port_handle_t>& /* portIds */) override {}

                // Sets the UID records silence
    virtual     void        setRecordSilenced(audio_port_handle_t portId __unused,
                                              bool silenced __unused) {}
    void setRecordSilenced(
            audio_port_handle_t /* portId */, bool /* silenced */) override {}

    bool isStreamInitialized() const override { return false; }

@@ -2168,12 +2167,16 @@ class MmapThread : public ThreadBase
     static     constexpr int32_t       kMaxNoCallbackWarnings = 5;
};

class MmapPlaybackThread : public MmapThread, public VolumeInterface
{
class MmapPlaybackThread : public MmapThread, public IAfMmapPlaybackThread,
        public virtual VolumeInterface {
public:
    MmapPlaybackThread(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
                       AudioHwDevice *hwDev, AudioStreamOut *output, bool systemReady);

    sp<IAfMmapPlaybackThread> asIAfMmapPlaybackThread() final {
        return sp<IAfMmapPlaybackThread>::fromExisting(this);
    }

    void configure(const audio_attributes_t* attr,
                                      audio_stream_type_t streamType,
                                      audio_session_t sessionId,
@@ -2181,7 +2184,7 @@ public:
                                      audio_port_handle_t deviceId,
                                      audio_port_handle_t portId) final;

                AudioStreamOut* clearOutput();
    AudioStreamOut* clearOutput() final;

                // VolumeInterface
    void setMasterVolume(float value) final;
@@ -2233,13 +2236,17 @@ protected:
                mediautils::atomic_sp<audio_utils::MelProcessor> mMelProcessor;
};

class MmapCaptureThread : public MmapThread
class MmapCaptureThread : public MmapThread, public IAfMmapCaptureThread
{
public:
    MmapCaptureThread(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
                      AudioHwDevice *hwDev, AudioStreamIn *input, bool systemReady);

                AudioStreamIn* clearInput();
    sp<IAfMmapCaptureThread> asIAfMmapCaptureThread() final {
        return sp<IAfMmapCaptureThread>::fromExisting(this);
    }

    AudioStreamIn* clearInput() final;

    status_t exitStandby_l() REQUIRES(mLock) final;