From f0e49e8c2c8be16a23e088e6be99e3dca54dd52b 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 (cherry picked from commit 3650c2970aebab16a1ced17f849631cea452085b) --- .../android/exoplayer2/audio/DefaultAudioSink.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java index 86c75a0492..d12b5cef48 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/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; @@ -1895,7 +1896,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 @@ -1903,7 +1904,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. @@ -1913,7 +1917,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.