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

Commit f27d1e47 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "PatchPanel: Fix crash when tearing down "pass thru" software patch"

parents ba385271 dd91ce21
Loading
Loading
Loading
Loading
+11 −3
Original line number Diff line number Diff line
@@ -496,10 +496,12 @@ status_t AudioFlinger::PatchPanel::Patch::createConnections(PatchPanel *panel)
    }

    sp<RecordThread::PatchRecord> tempRecordTrack;
    const bool usePassthruPatchRecord =
            (inputFlags & AUDIO_INPUT_FLAG_DIRECT) && (outputFlags & AUDIO_OUTPUT_FLAG_DIRECT);
    const size_t playbackFrameCount = mPlayback.thread()->frameCount();
    const size_t recordFrameCount = mRecord.thread()->frameCount();
    size_t frameCount = 0;
    if ((inputFlags & AUDIO_INPUT_FLAG_DIRECT) && (outputFlags & AUDIO_OUTPUT_FLAG_DIRECT)) {
    if (usePassthruPatchRecord) {
        // PassthruPatchRecord producesBufferOnDemand, so use
        // maximum of playback and record thread framecounts
        frameCount = std::max(playbackFrameCount, recordFrameCount);
@@ -556,8 +558,14 @@ status_t AudioFlinger::PatchPanel::Patch::createConnections(PatchPanel *panel)
    }

    // tie playback and record tracks together
    mRecord.setTrackAndPeer(tempRecordTrack, tempPatchTrack);
    mPlayback.setTrackAndPeer(tempPatchTrack, tempRecordTrack);
    // In the case of PassthruPatchRecord no I/O activity happens on RecordThread,
    // everything is driven from PlaybackThread. Thus AudioBufferProvider methods
    // of PassthruPatchRecord can only be called if the corresponding PatchTrack
    // is alive. There is no need to hold a reference, and there is no need
    // to clear it. In fact, since playback stopping is asynchronous, there is
    // no proper time when clearing could be done.
    mRecord.setTrackAndPeer(tempRecordTrack, tempPatchTrack, !usePassthruPatchRecord);
    mPlayback.setTrackAndPeer(tempPatchTrack, tempRecordTrack, true /*holdReference*/);

    // start capture and playback
    mRecord.track()->start(AudioSystem::SYNC_EVENT_NONE, AUDIO_SESSION_NONE);
+6 −3
Original line number Diff line number Diff line
@@ -128,18 +128,20 @@ public:
            mCloseThread = closeThread;
        }
        template <typename T>
        void setTrackAndPeer(const sp<TrackType>& track, const sp<T> &peer) {
        void setTrackAndPeer(const sp<TrackType>& track, const sp<T> &peer, bool holdReference) {
            mTrack = track;
            mThread->addPatchTrack(mTrack);
            mTrack->setPeerProxy(peer, true /* holdReference */);
            mTrack->setPeerProxy(peer, holdReference);
            mClearPeerProxy = holdReference;
        }
        void clearTrackPeer() { if (mTrack) mTrack->clearPeerProxy(); }
        void clearTrackPeer() { if (mClearPeerProxy && mTrack) mTrack->clearPeerProxy(); }
        void stopTrack() { if (mTrack) mTrack->stop(); }

        void swap(Endpoint &other) noexcept {
            using std::swap;
            swap(mThread, other.mThread);
            swap(mCloseThread, other.mCloseThread);
            swap(mClearPeerProxy, other.mClearPeerProxy);
            swap(mHandle, other.mHandle);
            swap(mTrack, other.mTrack);
        }
@@ -151,6 +153,7 @@ public:
    private:
        sp<ThreadType> mThread;
        bool mCloseThread = true;
        bool mClearPeerProxy = true;
        audio_patch_handle_t mHandle = AUDIO_PATCH_HANDLE_NONE;
        sp<TrackType> mTrack;
    };