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

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

Merge "AudioFlinger: Remove invalidateTracks based on streamType" into main

parents 64e9f326 e4a7892e
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -3625,13 +3625,13 @@ status_t AudioFlinger::invalidateTracks(const std::vector<audio_port_handle_t> &
    std::set<audio_port_handle_t> portIdSet(portIds.begin(), portIds.end());
    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
        IAfPlaybackThread* const thread = mPlaybackThreads.valueAt(i).get();
        thread->invalidateTracks(portIdSet);
        thread->invalidateTracks(&portIdSet);
        if (portIdSet.empty()) {
            return NO_ERROR;
        }
    }
    for (size_t i = 0; i < mMmapThreads.size(); i++) {
        mMmapThreads[i]->invalidateTracks(portIdSet);
        mMmapThreads[i]->invalidateTracks(&portIdSet);
        if (portIdSet.empty()) {
            return NO_ERROR;
        }
@@ -5043,7 +5043,9 @@ void AudioFlinger::onNonOffloadableGlobalEffectEnable()
    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
        const sp<IAfPlaybackThread> t = mPlaybackThreads.valueAt(i);
        if (t->type() == IAfThreadBase::OFFLOAD) {
            t->invalidateTracks(AUDIO_STREAM_MUSIC);
            // we could invalidate based on session id, but offload threads
            // are based on single client access, so we invalidate everything.
            t->invalidateTracks();
        }
    }

+10 −17
Original line number Diff line number Diff line
@@ -418,6 +418,16 @@ public:

    virtual std::vector<sp<IAfTrackBase>> getTracks_l() REQUIRES(mutex()) = 0;

    // Invalidate tracks by a set of port ids. The port id will be removed from
    // the given set if the corresponding track is found and invalidated.
    //
    // If portIds == nullptr, all tracks, including internal tracks are invalidated.
    virtual bool invalidateTracks_l(std::set<audio_port_handle_t>* portIds = {})
            REQUIRES(mutex()) = 0;

    virtual bool invalidateTracks(std::set<audio_port_handle_t>* portIds = {})
            EXCLUDES_ThreadBase_Mutex = 0;

    virtual status_t setPortsVolume(const std::vector<audio_port_handle_t> &portIds, float volume,
            bool muted) EXCLUDES_ThreadBase_Mutex = 0;

@@ -520,16 +530,6 @@ public:
    virtual status_t attachAuxEffect_l(const sp<IAfTrack>& track, int EffectId)
            REQUIRES(mutex()) = 0;

    // called with AudioFlinger lock held
    virtual bool invalidateTracks_l(audio_stream_type_t streamType) REQUIRES(mutex()) = 0;
    virtual bool invalidateTracks_l(std::set<audio_port_handle_t>& portIds) REQUIRES(mutex()) = 0;
    virtual void invalidateTracks(audio_stream_type_t streamType)
            EXCLUDES_ThreadBase_Mutex = 0;
    // Invalidate tracks by a set of port ids. The port id will be removed from
    // the given set if the corresponding track is found and invalidated.
    virtual void invalidateTracks(std::set<audio_port_handle_t>& portIds)
            EXCLUDES_ThreadBase_Mutex = 0;

    virtual status_t getTimestamp_l(AudioTimestamp& timestamp) REQUIRES(mutex()) = 0;
    virtual void addPatchTrack(const sp<IAfPatchTrack>& track) EXCLUDES_ThreadBase_Mutex = 0;
    virtual void deletePatchTrack(const sp<IAfPatchTrack>& track) EXCLUDES_ThreadBase_Mutex = 0;
@@ -691,13 +691,6 @@ public:
    virtual status_t reportData(const void* buffer, size_t frameCount)
            EXCLUDES_ThreadBase_Mutex = 0;

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

    virtual void invalidateTracks(audio_stream_type_t streamType)
            EXCLUDES_ThreadBase_Mutex = 0;

    // Sets the UID records silence - TODO(b/291317898)  move to IAfMmapCaptureThread
    virtual void setRecordSilenced(audio_port_handle_t portId, bool silenced)
            EXCLUDES_ThreadBase_Mutex = 0;
+60 −101
Original line number Diff line number Diff line
@@ -1793,7 +1793,7 @@ void ThreadBase::onEffectEnable(const sp<IAfEffectModule>& effect) {
    if (!effect->isOffloadable()) {
        if (mType == ThreadBase::OFFLOAD) {
            PlaybackThread *t = (PlaybackThread *)this;
            t->invalidateTracks(AUDIO_STREAM_MUSIC);
            t->invalidateTracks();
        }
        if (effect->sessionId() == AUDIO_SESSION_OUTPUT_MIX) {
            mAfThreadCallback->onNonOffloadableGlobalEffectEnable();
@@ -2165,6 +2165,48 @@ void ThreadBase::stopMelComputation_l()
    ALOGW("%s: ThreadBase does not support CSD", __func__);
}

std::set<audio_port_handle_t> ThreadBase::getTrackPortIds_l() const
{
    std::set<int32_t> result;
    for (const auto& t : mTracks) {
        if (t->isExternalTrack()) {
            result.insert(t->portId());
        }
    }
    return result;
}

std::set<audio_port_handle_t> ThreadBase::getTrackPortIds() const
{
    audio_utils::lock_guard _l(mutex());
    return getTrackPortIds_l();
}

bool ThreadBase::invalidateTracks(std::set<audio_port_handle_t>* portIds) {
    audio_utils::lock_guard _l(mutex());
    return invalidateTracks_l(portIds);
}

// Only Playback Threads invalidate tracks based on portIds, but we keep
// open the possibility that Record / Capture Threads may eventually use it.
bool ThreadBase::invalidateTracks_l(std::set<audio_port_handle_t>* portIds) {
    bool trackMatch = false;
    for (const auto& t : mTracks) {
        if (portIds == nullptr ||
                (t->isExternalTrack() && portIds->find(t->portId()) != portIds->end())) {
            t->invalidate();
            if (portIds) portIds->erase(t->portId());
            trackMatch = true;
        }
    }

    // TODO(b/410038399) consider to apply to all threads for symmetry.
    if (trackMatch && (type() == MMAP_PLAYBACK || type() == MMAP_CAPTURE)) {
        broadcast_l();
    }
    return trackMatch;
}

status_t ThreadBase::setPortsVolume(
        const std::vector<audio_port_handle_t>& portIds, float volume, bool muted) {
    audio_utils::lock_guard _l(mutex());
@@ -3072,23 +3114,6 @@ void PlaybackThread::removeTrack_l(const sp<IAfTrack>& track)
    }
}

std::set<audio_port_handle_t> PlaybackThread::getTrackPortIds_l()
{
    std::set<int32_t> result;
    for (const auto& t : mTracks) {
        if (t->isExternalTrack()) {
            result.insert(t->portId());
        }
    }
    return result;
}

std::set<audio_port_handle_t> PlaybackThread::getTrackPortIds()
{
    audio_utils::lock_guard _l(mutex());
    return getTrackPortIds_l();
}

String8 PlaybackThread::getParameters(const String8& keys)
{
    audio_utils::lock_guard _l(mutex());
@@ -3728,46 +3753,6 @@ void PlaybackThread::cacheParameters_l()
    }
}

bool PlaybackThread::invalidateTracks_l(audio_stream_type_t streamType)
{
    ALOGV("MixerThread::invalidateTracks() mixer %p, streamType %d, mTracks.size %zu",
            this,  streamType, mTracks.size());
    bool trackMatch = false;
    for (const auto& t : mPlaybackTracksView) {
        if (t->streamType() == streamType && t->isExternalTrack()) {
            t->invalidate();
            trackMatch = true;
        }
    }
    return trackMatch;
}

void PlaybackThread::invalidateTracks(audio_stream_type_t streamType)
{
    audio_utils::lock_guard _l(mutex());
    invalidateTracks_l(streamType);
}

void PlaybackThread::invalidateTracks(std::set<audio_port_handle_t>& portIds) {
    audio_utils::lock_guard _l(mutex());
    invalidateTracks_l(portIds);
}

bool PlaybackThread::invalidateTracks_l(std::set<audio_port_handle_t>& portIds) {
    bool trackMatch = false;
    for (const auto& t : mTracks) {
        if (t->isExternalTrack() && portIds.find(t->portId()) != portIds.end()) {
            t->invalidate();
            portIds.erase(t->portId());
            trackMatch = true;
        }
        if (portIds.empty()) {
            break;
        }
    }
    return trackMatch;
}

status_t PlaybackThread::addEffectChain_l(const sp<IAfEffectChain>& chain)
{
    audio_session_t session = chain->sessionId();
@@ -5487,9 +5472,7 @@ void PlaybackThread::onAddNewTrack_l()
void PlaybackThread::onAsyncError(bool isHardError)
{
    auto allTrackPortIds = getTrackPortIds();
    for (int i = AUDIO_STREAM_SYSTEM; i < (int)AUDIO_STREAM_CNT; i++) {
        invalidateTracks((audio_stream_type_t)i);
    }
    invalidateTracks();
    if (isHardError) {
        mAfThreadCallback->onHardError(allTrackPortIds);
    }
@@ -7773,19 +7756,25 @@ void OffloadThread::flushHw_l()
    }
}

void OffloadThread::invalidateTracks(audio_stream_type_t streamType)
{
    audio_utils::lock_guard _l(mutex());
    if (PlaybackThread::invalidateTracks_l(streamType)) {
        mFlushPending = true;
    }
}
// TODO(b/410038399) move to base class and unify with Mmap implementation for clarity.

void OffloadThread::invalidateTracks(std::set<audio_port_handle_t>& portIds) {
    audio_utils::lock_guard _l(mutex());
    if (PlaybackThread::invalidateTracks_l(portIds)) {
bool OffloadThread::invalidateTracks_l(std::set<audio_port_handle_t>* portIds) {
    const bool trackMatch = ThreadBase::invalidateTracks_l(portIds);
    if (trackMatch) {
        // On invalidating an offload track, the IAudioTrack instance is
        // destroyed and the offload output is released. If it so happens
        // that APM::getOutputForAttr for the new IAudioTrack is called before
        // OffloadThread::prepareTracks_l checks and removes an invalid track,
        // the same output can get reused.
        //
        // The side effect of this is data present in HAL and below from before the
        // invalidate will be rendered before data from the new seek position
        // is rendered. This is unexpected.
        //
        // To fix this, set hint to issue flush when an offload track is invalidated.
        mFlushPending = true;
    }
    return trackMatch;
}

// ----------------------------------------------------------------------------
@@ -11343,36 +11332,6 @@ void MmapPlaybackThread::setStreamMute(audio_stream_type_t stream, bool muted)
    }
}

void MmapPlaybackThread::invalidateTracks(audio_stream_type_t streamType)
{
    audio_utils::lock_guard _l(mutex());
    if (streamType == mStreamType) {
        for (const auto& track : mActiveTracks) {
            track->invalidate();
        }
        broadcast_l();
    }
}

void MmapPlaybackThread::invalidateTracks(std::set<audio_port_handle_t>& portIds)
{
    audio_utils::lock_guard _l(mutex());
    bool trackMatch = false;
    for (const auto& track : mActiveTracks) {
        if (portIds.find(track->portId()) != portIds.end()) {
            track->invalidate();
            trackMatch = true;
            portIds.erase(track->portId());
        }
        if (portIds.empty()) {
            break;
        }
    }
    if (trackMatch) {
        broadcast_l();
    }
}

void MmapPlaybackThread::processVolume_l()
NO_THREAD_SAFETY_ANALYSIS // access of track->processMuteEvent
{
+13 −22
Original line number Diff line number Diff line
@@ -947,6 +947,18 @@ protected:

    std::vector<sp<IAfTrackBase>> getTracks_l() final REQUIRES(mutex());

    std::set<audio_port_handle_t> getTrackPortIds_l() const REQUIRES(mutex());
    std::set<audio_port_handle_t> getTrackPortIds() const EXCLUDES_ThreadBase_Mutex;

    // Invalidate tracks by a set of port ids. The port id will be removed from
    // the given set if the corresponding track is found and invalidated.
    //
    // If portIds == nullptr, all tracks, including internal tracks are invalidated.
    bool invalidateTracks_l(std::set<audio_port_handle_t>* portIds = {}) override
            REQUIRES(mutex());
    bool invalidateTracks(std::set<audio_port_handle_t>* portIds = {}) override
            EXCLUDES_ThreadBase_Mutex;

    status_t setPortsVolume(const std::vector<audio_port_handle_t>& portIds, float volume,
                            bool muted) final EXCLUDES_ThreadBase_Mutex;

@@ -1172,17 +1184,6 @@ public:
    // could be static.
    bool isValidSyncEvent(const sp<audioflinger::SyncEvent>& event) const final;

    // Does this require the AudioFlinger mutex as well?
    bool invalidateTracks_l(audio_stream_type_t streamType) final
            REQUIRES(mutex());
    bool invalidateTracks_l(std::set<audio_port_handle_t>& portIds) final
            REQUIRES(mutex());
    void invalidateTracks(audio_stream_type_t streamType) override;
                // Invalidate tracks by a set of port ids. The port id will be removed from
                // the given set if the corresponding track is found and invalidated.
    void invalidateTracks(std::set<audio_port_handle_t>& portIds) override
            EXCLUDES_ThreadBase_Mutex;

    size_t frameCount() const final { return mNormalFrameCount; }

    audio_channel_mask_t mixerChannelMask() const final {
@@ -1468,8 +1469,6 @@ protected:
    bool destroyTrack_l(const sp<IAfTrack>& track) final REQUIRES(mutex());

    void removeTrack_l(const sp<IAfTrack>& track) REQUIRES(mutex());
    std::set<audio_port_handle_t> getTrackPortIds_l() REQUIRES(mutex());
    std::set<audio_port_handle_t> getTrackPortIds();

    void readOutputParameters_l() REQUIRES(mutex());
    MetadataUpdate updateMetadata_l() final REQUIRES(mutex(), ThreadBase_ThreadLoop);
@@ -1855,8 +1854,7 @@ protected:

    bool waitingAsyncCallback() final;
    bool waitingAsyncCallback_l() final REQUIRES(mutex());
    void invalidateTracks(audio_stream_type_t streamType) final EXCLUDES_ThreadBase_Mutex;
    void invalidateTracks(std::set<audio_port_handle_t>& portIds) final EXCLUDES_ThreadBase_Mutex;
    bool invalidateTracks_l(std::set<audio_port_handle_t>* portIds) final REQUIRES(mutex());

    bool keepWakeLock() const final { return (mKeepWakeLock || (mDrainSequence & 1)); }

@@ -2342,10 +2340,6 @@ class MmapThread : public ThreadBase, public virtual IAfMmapThread
    virtual audio_stream_type_t streamType_l() const REQUIRES(mutex()) {
        return AUDIO_STREAM_DEFAULT;
    }
    virtual void invalidateTracks(audio_stream_type_t /* streamType */)
            EXCLUDES_ThreadBase_Mutex {}
    void invalidateTracks(std::set<audio_port_handle_t>& /* portIds */) override
            EXCLUDES_ThreadBase_Mutex {}

                // Sets the UID records silence
    void setRecordSilenced(
@@ -2440,9 +2434,6 @@ public:

    void setMasterMute_l(bool muted) REQUIRES(mutex()) { mMasterMute = muted; }

    void invalidateTracks(audio_stream_type_t streamType) final EXCLUDES_ThreadBase_Mutex;
    void invalidateTracks(std::set<audio_port_handle_t>& portIds) final EXCLUDES_ThreadBase_Mutex;

    audio_stream_type_t streamType_l() const final REQUIRES(mutex()) {
        return mStreamType;
    }