From e331bf2c53c2ff7a3c998ccd3a58eb4b7c948fcc Mon Sep 17 00:00:00 2001 From: tonihei Date: Thu, 28 Jul 2022 16:08:21 +0000 Subject: [PATCH] Ignore stale events in StreamEventCallbackV29. Despite unregistering the callback and clearing pending Handler messages, the callback may still receive pending calls if they are already triggered by the AudioTrack. Instead of asserting that the track is correct, we should gracefully ignore stale events. PiperOrigin-RevId: 463851393 --- .../media3/exoplayer/audio/DefaultAudioSink.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioSink.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioSink.java index c3bb029d38..ccfe4ffc97 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioSink.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioSink.java @@ -30,6 +30,7 @@ import android.media.AudioTrack; import android.media.PlaybackParams; import android.media.metrics.LogSessionId; import android.os.Handler; +import android.os.Looper; import android.os.SystemClock; import android.util.Pair; import androidx.annotation.DoNotInline; @@ -1904,7 +1905,7 @@ public final class DefaultAudioSink implements AudioSink { private final AudioTrack.StreamEventCallback callback; public StreamEventCallbackV29() { - handler = new Handler(); + handler = new Handler(Looper.myLooper()); // Avoid StreamEventCallbackV29 inheriting directly from AudioTrack.StreamEventCallback as it // would cause a NoClassDefFoundError warning on load of DefaultAudioSink for SDK < 29. // See: https://github.com/google/ExoPlayer/issues/8058 @@ -1912,7 +1913,10 @@ public final class DefaultAudioSink implements AudioSink { new AudioTrack.StreamEventCallback() { @Override public void onDataRequest(AudioTrack track, int size) { - Assertions.checkState(track == audioTrack); + if (!track.equals(audioTrack)) { + // Stale event. + return; + } if (listener != null && playing) { // Do not signal that the buffer is emptying if not playing as it is a transient // state. @@ -1922,7 +1926,10 @@ public final class DefaultAudioSink implements AudioSink { @Override public void onTearDown(AudioTrack track) { - Assertions.checkState(track == audioTrack); + if (!track.equals(audioTrack)) { + // Stale event. + return; + } if (listener != null && playing) { // The audio track was destroyed while in use. Thus a new AudioTrack needs to be // created and its buffer filled, which will be done on the next handleBuffer call.