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

Commit 5c25d563 authored by Eric Laurent's avatar Eric Laurent
Browse files

AudioFlinger: fix capture stop sequence

Make sure that the HAL input stream is actually in standby when audio policy
is notified by stopInput().
There was a race condition where it was possible for a new capture stream to be started
in the interval between stopInput() notification and input stream going into
standby because of the state update and sleep sequence in the record thread loop.

Also make sure we interrupt the sleep period if a command is pending.

Bug: 29865791
Change-Id: Ife720fbd2e5d0df8792669dc724b1fd70f63ab8a
parent bea67b8a
Loading
Loading
Loading
Loading
+19 −8
Original line number Diff line number Diff line
@@ -5985,14 +5985,6 @@ reacquire_wakelock:
    for (;;) {
        Vector< sp<EffectChain> > effectChains;

        // sleep with mutex unlocked
        if (sleepUs > 0) {
            ATRACE_BEGIN("sleep");
            usleep(sleepUs);
            ATRACE_END();
            sleepUs = 0;
        }

        // activeTracks accumulates a copy of a subset of mActiveTracks
        Vector< sp<RecordTrack> > activeTracks;

@@ -6013,6 +6005,15 @@ reacquire_wakelock:
                break;
            }

            // sleep with mutex unlocked
            if (sleepUs > 0) {
                ATRACE_BEGIN("sleep");
                mWaitWorkCV.waitRelative(mLock, microseconds((nsecs_t)sleepUs));
                ATRACE_END();
                sleepUs = 0;
                continue;
            }

            // if no active track(s), then standby and release wakelock
            size_t size = mActiveTracks.size();
            if (size == 0) {
@@ -6036,6 +6037,7 @@ reacquire_wakelock:
            }

            bool doBroadcast = false;
            bool allStopped = true;
            for (size_t i = 0; i < size; ) {

                activeTrack = mActiveTracks[i];
@@ -6064,15 +6066,18 @@ reacquire_wakelock:
                case TrackBase::STARTING_1:
                    sleepUs = 10000;
                    i++;
                    allStopped = false;
                    continue;

                case TrackBase::STARTING_2:
                    doBroadcast = true;
                    mStandby = false;
                    activeTrack->mState = TrackBase::ACTIVE;
                    allStopped = false;
                    break;

                case TrackBase::ACTIVE:
                    allStopped = false;
                    break;

                case TrackBase::IDLE:
@@ -6092,6 +6097,10 @@ reacquire_wakelock:
                    fastTrack = activeTrack;
                }
            }

            if (allStopped) {
                standbyIfNotAlreadyInStandby();
            }
            if (doBroadcast) {
                mStartStopCond.broadcast();
            }
@@ -6674,6 +6683,8 @@ bool AudioFlinger::RecordThread::stop(RecordThread::RecordTrack* recordTrack) {
    }
    // note that threadLoop may still be processing the track at this point [without lock]
    recordTrack->mState = TrackBase::PAUSING;
    // signal thread to stop
    mWaitWorkCV.broadcast();
    // do not wait for mStartStopCond if exiting
    if (exitPending()) {
        return true;