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

Commit a36cce06 authored by Narayan Kamath's avatar Narayan Kamath
Browse files

Fix a threading issue in AudioPlaybackHandler

Never allow the AudioTrack to be observed in a state where
it is release()d but non null.

Change-Id: I1e5b61355f30c2aafcd55ecdf83077d7a9d99c66
parent 90e5650f
Loading
Loading
Loading
Loading
+22 −14
Original line number Diff line number Diff line
@@ -418,23 +418,31 @@ class AudioPlaybackHandler {
        if (DBG) Log.d(TAG, "handleSynthesisDone()");
        final AudioTrack audioTrack = params.getAudioTrack();

        try {
            if (audioTrack != null) {
        if (audioTrack == null) {
            return;
        }

        if (DBG) Log.d(TAG, "Waiting for audio track to complete : " +
                audioTrack.hashCode());
        blockUntilDone(params);
        if (DBG) Log.d(TAG, "Releasing audio track [" + audioTrack.hashCode() + "]");

        // The last call to AudioTrack.write( ) will return only after
        // all data from the audioTrack has been sent to the mixer, so
                // it's safe to release at this point.
        // it's safe to release at this point. Make sure release() and the call
        // that set the audio track to null are performed atomically.
        synchronized (this) {
            // Never allow the audioTrack to be observed in a state where
            // it is released but non null. The only case this might happen
            // is in the various stopFoo methods that call AudioTrack#stop from
            // different threads, but they are synchronized on AudioPlayBackHandler#this
            // too.
            audioTrack.release();
            }
        } finally {
            params.setAudioTrack(null);
        }
        params.getDispatcher().dispatchUtteranceCompleted();
        mLastSynthesisRequest = null;
    }
    }

    private static void blockUntilDone(SynthesisMessageParams params) {
        if (params.mAudioTrack == null || params.mBytesWritten <= 0) {