diff --git a/libraries/exoplayer_ima/src/main/java/androidx/media3/exoplayer/ima/AdTagLoader.java b/libraries/exoplayer_ima/src/main/java/androidx/media3/exoplayer/ima/AdTagLoader.java index e03b2293fce..c6a61fd05e8 100644 --- a/libraries/exoplayer_ima/src/main/java/androidx/media3/exoplayer/ima/AdTagLoader.java +++ b/libraries/exoplayer_ima/src/main/java/androidx/media3/exoplayer/ima/AdTagLoader.java @@ -391,7 +391,23 @@ public void activate(Player player) { /** Deactivates playback. */ public void deactivate() { Player player = checkNotNull(this.player); - if (!AdPlaybackState.NONE.equals(adPlaybackState) && imaPausedContent) { + // Post release of listener behind any already queued Player.Listener events to ensure that + // any pending events are processed before the player is deferred. + handler.post( + () -> { + deactivateInternal(player); + }); + } + + /** + * Deactivates playback internally, after the Listener.onEvents() cycle completes so the complete + * state change picture is clear. For example, if an error caused the deactivation, need to + * determine whether the error was for an ad or content. + */ + private void deactivateInternal(Player player) { + if (!AdPlaybackState.NONE.equals(adPlaybackState) + && imaPausedContent + && player.getPlayerError() == null) { if (adsManager != null) { adsManager.pause(); } @@ -402,9 +418,7 @@ public void deactivate() { lastVolumePercent = getPlayerVolumePercent(); lastAdProgress = getAdVideoProgressUpdate(); lastContentProgress = getContentVideoProgressUpdate(); - - // Post release of listener so that we can report any already pending errors via onPlayerError. - handler.post(() -> player.removeListener(this)); + player.removeListener(this); this.player = null; } @@ -539,7 +553,7 @@ public void onPlayWhenReadyChanged( @Override public void onPlayerError(PlaybackException error) { - if (imaAdState != IMA_AD_STATE_NONE) { + if (imaAdState != IMA_AD_STATE_NONE && player.isPlayingAd()) { AdMediaInfo adMediaInfo = checkNotNull(imaAdMediaInfo); for (int i = 0; i < adCallbacks.size(); i++) { adCallbacks.get(i).onError(adMediaInfo);