diff --git a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java index efc8c14dcc..b701d0b9d4 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java @@ -75,7 +75,6 @@ import java.util.concurrent.TimeoutException; @RepeatMode private int repeatMode; private boolean shuffleModeEnabled; private int pendingOperationAcks; - private boolean hasPendingSeek; private boolean hasPendingDiscontinuity; @DiscontinuityReason private int pendingDiscontinuityReason; @PlayWhenReadyChangeReason private int pendingPlayWhenReadyChangeReason; @@ -552,7 +551,6 @@ import java.util.concurrent.TimeoutException; if (windowIndex < 0 || (!timeline.isEmpty() && windowIndex >= timeline.getWindowCount())) { throw new IllegalSeekPositionException(timeline, windowIndex, positionMs); } - hasPendingSeek = true; pendingOperationAcks++; if (isPlayingAd()) { // TODO: Investigate adding support for seeking during ads. This is complicated to do in @@ -580,7 +578,7 @@ import java.util.concurrent.TimeoutException; /* positionDiscontinuityReason= */ DISCONTINUITY_REASON_SEEK, /* ignored */ TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED, /* ignored */ PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST, - /* seekProcessed= */ false); + /* seekProcessed= */ true); } /** @deprecated Use {@link #setPlaybackSpeed(float)} instead. */ @@ -889,9 +887,7 @@ import java.util.concurrent.TimeoutException; // Update the masking variables, which are used when the timeline becomes empty. resetMaskingPosition(); } - boolean seekProcessed = hasPendingSeek; boolean positionDiscontinuity = hasPendingDiscontinuity; - hasPendingSeek = false; hasPendingDiscontinuity = false; updatePlaybackInfo( playbackInfoUpdate.playbackInfo, @@ -899,7 +895,7 @@ import java.util.concurrent.TimeoutException; pendingDiscontinuityReason, TIMELINE_CHANGE_REASON_SOURCE_UPDATE, pendingPlayWhenReadyChangeReason, - seekProcessed); + /* seekProcessed= */ false); } } diff --git a/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java b/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java index 035cf542b1..c2d61dd800 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java @@ -531,72 +531,6 @@ public final class ExoPlayerTest { assertThat(renderer.isEnded).isTrue(); } - @Test - public void seekProcessedCallback() throws Exception { - Timeline timeline = new FakeTimeline(/* windowCount= */ 2); - ActionSchedule actionSchedule = - new ActionSchedule.Builder(TAG) - // Initial seek. Expect immediate seek processed. - .pause() - .seek(5) - .waitForSeekProcessed() - // Multiple overlapping seeks while the player is still preparing. Expect only one seek - // processed. - .seek(2) - .seek(10) - // Wait until media source prepared and re-seek to same position. Expect a seek - // processed while still being in STATE_READY. - .waitForPlaybackState(Player.STATE_READY) - .seek(10) - // Start playback and wait until playback reaches second window. - .playUntilStartOfWindow(/* windowIndex= */ 1) - // Seek twice in concession, expecting the first seek to be replaced (and thus except - // only on seek processed callback). - .seek(5) - .seek(60) - .waitForSeekProcessed() - .play() - .build(); - final List playbackStatesWhenSeekProcessed = new ArrayList<>(); - EventListener eventListener = - new EventListener() { - private int currentPlaybackState = Player.STATE_IDLE; - - @Override - public void onPlaybackStateChanged(@Player.State int playbackState) { - currentPlaybackState = playbackState; - } - - @Override - public void onSeekProcessed() { - playbackStatesWhenSeekProcessed.add(currentPlaybackState); - } - }; - ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() - .setTimeline(timeline) - .setEventListener(eventListener) - .setActionSchedule(actionSchedule) - .build(context) - .start() - .blockUntilEnded(TIMEOUT_MS); - testRunner.assertPositionDiscontinuityReasonsEqual( - Player.DISCONTINUITY_REASON_SEEK, - Player.DISCONTINUITY_REASON_SEEK, - Player.DISCONTINUITY_REASON_SEEK, - Player.DISCONTINUITY_REASON_SEEK, - Player.DISCONTINUITY_REASON_PERIOD_TRANSITION, - Player.DISCONTINUITY_REASON_SEEK, - Player.DISCONTINUITY_REASON_SEEK); - assertThat(playbackStatesWhenSeekProcessed) - .containsExactly( - Player.STATE_BUFFERING, - Player.STATE_BUFFERING, - Player.STATE_READY, - Player.STATE_BUFFERING) - .inOrder(); - } - @Test public void illegalSeekPositionDoesThrow() throws Exception { final IllegalSeekPositionException[] exception = new IllegalSeekPositionException[1]; @@ -1407,9 +1341,8 @@ public final class ExoPlayerTest { ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) .waitForPlaybackState(Player.STATE_BUFFERING) - .seek(0) .stop(true) - .waitForSeekProcessed() + .waitForPendingPlayerCommands() .build(); ExoPlayerTestRunner testRunner = new ExoPlayerTestRunner.Builder() @@ -1423,21 +1356,19 @@ public final class ExoPlayerTest { testRunner.assertTimelineChangeReasonsEqual( Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED, Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED); - testRunner.assertPositionDiscontinuityReasonsEqual(Player.DISCONTINUITY_REASON_SEEK); } @Test public void stopAndSeekAfterStopDoesNotResetTimeline() throws Exception { - // Combining additional stop and seek after initial stop in one test to get the seek processed - // callback which ensures that all operations have been processed by the player. Timeline timeline = new FakeTimeline(/* windowCount= */ 1); ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) .waitForPlaybackState(Player.STATE_READY) .stop(false) .stop(false) - .seek(0) - .waitForSeekProcessed() + // Wait until the player fully processed the second stop to see that no further + // callbacks are triggered. + .waitForPendingPlayerCommands() .build(); ExoPlayerTestRunner testRunner = new ExoPlayerTestRunner.Builder() @@ -1451,7 +1382,6 @@ public final class ExoPlayerTest { testRunner.assertTimelineChangeReasonsEqual( Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED, Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE); - testRunner.assertPositionDiscontinuityReasonsEqual(Player.DISCONTINUITY_REASON_SEEK); } @Test @@ -1493,7 +1423,7 @@ public final class ExoPlayerTest { .throwPlaybackException(ExoPlaybackException.createForSource(new IOException())) .waitForPlaybackState(Player.STATE_IDLE) .seek(/* positionMs= */ 50) - .waitForSeekProcessed() + .waitForPendingPlayerCommands() .executeRunnable( new PlayerRunnable() { @Override @@ -1517,12 +1447,14 @@ public final class ExoPlayerTest { .setTimeline(timeline) .setActionSchedule(actionSchedule) .build(context); - try { - testRunner.start().blockUntilActionScheduleFinished(TIMEOUT_MS).blockUntilEnded(TIMEOUT_MS); - fail(); - } catch (ExoPlaybackException e) { - // Expected exception. - } + + assertThrows( + ExoPlaybackException.class, + () -> + testRunner + .start() + .blockUntilActionScheduleFinished(TIMEOUT_MS) + .blockUntilEnded(TIMEOUT_MS)); testRunner.assertTimelinesSame(dummyTimeline, timeline); testRunner.assertTimelineChangeReasonsEqual( Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED, @@ -1690,7 +1622,7 @@ public final class ExoPlayerTest { } }) .seek(/* windowIndex= */ 0, /* positionMs= */ C.TIME_UNSET) - .waitForSeekProcessed() + .waitForPendingPlayerCommands() .executeRunnable( new PlayerRunnable() { @Override @@ -1717,12 +1649,14 @@ public final class ExoPlayerTest { .setMediaSources(firstMediaSource) .setActionSchedule(actionSchedule) .build(context); - try { - testRunner.start().blockUntilActionScheduleFinished(TIMEOUT_MS).blockUntilEnded(TIMEOUT_MS); - fail(); - } catch (ExoPlaybackException e) { - // Expected exception. - } + + assertThrows( + ExoPlaybackException.class, + () -> + testRunner + .start() + .blockUntilActionScheduleFinished(TIMEOUT_MS) + .blockUntilEnded(TIMEOUT_MS)); assertThat(positionHolder[0]).isAtLeast(500L); assertThat(positionHolder[1]).isEqualTo(0L); assertThat(positionHolder[2]).isEqualTo(0L); @@ -2459,11 +2393,12 @@ public final class ExoPlayerTest { .pause() .waitForPlaybackState(Player.STATE_READY) .seek(/* windowIndex= */ 0, /* positionMs= */ 9999) - .waitForSeekProcessed() + // Wait after each seek until the internal player has updated its state. + .waitForPendingPlayerCommands() .seek(/* windowIndex= */ 0, /* positionMs= */ 1) - .waitForSeekProcessed() + .waitForPendingPlayerCommands() .seek(/* windowIndex= */ 0, /* positionMs= */ 9999) - .waitForSeekProcessed() + .waitForPendingPlayerCommands() .play() .build(); ExoPlayerTestRunner testRunner = @@ -2526,7 +2461,7 @@ public final class ExoPlayerTest { player.seekTo(/* windowIndex= */ 0, /* positionMs= */ 1000L); } }) - .waitForSeekProcessed() + .waitForPendingPlayerCommands() .executeRunnable( new PlayerRunnable() { @Override @@ -2795,7 +2730,7 @@ public final class ExoPlayerTest { .pause() .waitForPlaybackState(Player.STATE_READY) .seek(/* windowIndex= */ 1, /* positionMs= */ 0) - .waitForSeekProcessed() + .waitForPendingPlayerCommands() .play() .build(); List trackGroupsList = new ArrayList<>(); @@ -2949,8 +2884,10 @@ public final class ExoPlayerTest { new ActionSchedule.Builder(TAG) .pause() .waitForPlaybackState(Player.STATE_BUFFERING) + // Seek while unprepared and wait until the player handled all updates. .seek(/* positionMs= */ 10) - .waitForSeekProcessed() + .waitForPendingPlayerCommands() + // Finish preparation. .executeRunnable(() -> mediaSource.setNewSourceInfo(timeline)) .waitForTimelineChanged() .waitForPlaybackState(Player.STATE_READY) @@ -2995,7 +2932,6 @@ public final class ExoPlayerTest { .waitForPlaybackState(Player.STATE_BUFFERING) // Seek 10ms into the second period. .seek(/* positionMs= */ periodDurationMs + 10) - .waitForSeekProcessed() .executeRunnable(() -> mediaSource.setNewSourceInfo(timeline)) .waitForTimelineChanged() .waitForPlaybackState(Player.STATE_READY) @@ -3369,7 +3305,6 @@ public final class ExoPlayerTest { ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) .seek(/* windowIndex= */ 1, /* positionMs= */ 5000) - .waitForSeekProcessed() .waitForTimelineChanged( /* expectedTimeline= */ null, Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE) .executeRunnable( @@ -3882,7 +3817,6 @@ public final class ExoPlayerTest { .executeRunnable( new PlaybackStateCollector(/* index= */ 3, playbackStates, timelineWindowCounts)) .seek(/* windowIndex= */ 1, /* positionMs= */ 2000) - .waitForSeekProcessed() .prepare() // The first expected buffering state arrives after prepare but not before. .waitForPlaybackState(Player.STATE_BUFFERING) @@ -3956,7 +3890,6 @@ public final class ExoPlayerTest { .addMediaSources(secondMediaSource) // add again to be able to test the seek .waitForTimelineChanged() .seek(/* positionMs= */ 2_000) // seek must transition to buffering - .waitForSeekProcessed() .waitForPlaybackState(Player.STATE_BUFFERING) .waitForPlaybackState(Player.STATE_READY) .waitForPlaybackState(Player.STATE_ENDED) @@ -4120,7 +4053,8 @@ public final class ExoPlayerTest { int seekToWindowIndex = 1; ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) - .waitForSeekProcessed() + .waitForPlaybackState(Player.STATE_BUFFERING) + .waitForTimelineChanged() .executeRunnable( new PlayerRunnable() { @Override @@ -4280,9 +4214,8 @@ public final class ExoPlayerTest { ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) .waitForPlaybackState(Player.STATE_BUFFERING) - // Do something and wait so that the player can create its unprepared MaskingMediaPeriod - .seek(/* positionMs= */ 0) - .waitForSeekProcessed() + // Wait so that the player can create its unprepared MaskingMediaPeriod. + .waitForPendingPlayerCommands() // Let the player assign the unprepared period to window1. .executeRunnable(() -> mediaSource.setNewSourceInfo(new FakeTimeline(window1, window2))) .waitForTimelineChanged() @@ -4398,7 +4331,9 @@ public final class ExoPlayerTest { final int[] currentWindowIndices = {C.INDEX_UNSET, C.INDEX_UNSET, C.INDEX_UNSET}; ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) - .waitForSeekProcessed() + // Wait for initial seek to be fully handled by internal player. + .waitForPositionDiscontinuity() + .waitForPendingPlayerCommands() .executeRunnable( new PlayerRunnable() { @Override @@ -4440,7 +4375,9 @@ public final class ExoPlayerTest { final int[] currentWindowIndices = {C.INDEX_UNSET, C.INDEX_UNSET, C.INDEX_UNSET}; ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) - .waitForSeekProcessed() + // Wait for initial seek to be fully handled by internal player. + .waitForPositionDiscontinuity() + .waitForPendingPlayerCommands() .executeRunnable( new PlayerRunnable() { @Override @@ -4547,7 +4484,9 @@ public final class ExoPlayerTest { final int[] currentWindowIndices = {C.INDEX_UNSET, C.INDEX_UNSET, C.INDEX_UNSET}; ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) - .waitForSeekProcessed() + // Wait for initial seek to be fully handled by internal player. + .waitForPositionDiscontinuity() + .waitForPendingPlayerCommands() .executeRunnable( new PlayerRunnable() { @Override @@ -4589,7 +4528,9 @@ public final class ExoPlayerTest { final int[] currentWindowIndices = {C.INDEX_UNSET, C.INDEX_UNSET, C.INDEX_UNSET}; ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) - .waitForSeekProcessed() + // Wait for initial seek to be fully handled by internal player. + .waitForPositionDiscontinuity() + .waitForPendingPlayerCommands() .executeRunnable( new PlayerRunnable() { @Override @@ -4735,7 +4676,9 @@ public final class ExoPlayerTest { Arrays.fill(maskingPlaybackStates, C.INDEX_UNSET); ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) - .waitForSeekProcessed() + // Wait for initial seek to be fully handled by internal player. + .waitForPositionDiscontinuity() + .waitForPendingPlayerCommands() .executeRunnable( new PlayerRunnable() { @Override @@ -4931,7 +4874,6 @@ public final class ExoPlayerTest { Arrays.fill(maskingPlaybackStates, C.INDEX_UNSET); ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) - .waitForSeekProcessed() .waitForPlaybackState(Player.STATE_ENDED) .executeRunnable( new PlayerRunnable() { @@ -5215,7 +5157,9 @@ public final class ExoPlayerTest { Arrays.fill(currentWindowIndices, C.INDEX_UNSET); ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) - .waitForSeekProcessed() + // Wait for initial seek to be fully handled by internal player. + .waitForPositionDiscontinuity() + .waitForPendingPlayerCommands() .executeRunnable( new PlayerRunnable() { @Override @@ -5262,7 +5206,9 @@ public final class ExoPlayerTest { final int[] currentWindowIndices = {C.INDEX_UNSET, C.INDEX_UNSET, C.INDEX_UNSET}; ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) - .waitForSeekProcessed() + // Wait for initial seek to be fully handled by internal player. + .waitForPositionDiscontinuity() + .waitForPendingPlayerCommands() .executeRunnable( new PlayerRunnable() { @Override @@ -5324,7 +5270,6 @@ public final class ExoPlayerTest { } }) .seek(/* windowIndex= */ 2, C.TIME_UNSET) - .waitForSeekProcessed() .executeRunnable( new PlayerRunnable() { @Override @@ -5354,7 +5299,6 @@ public final class ExoPlayerTest { } }) .seek(/* windowIndex= */ 0, C.TIME_UNSET) - .waitForSeekProcessed() .executeRunnable( new PlayerRunnable() { @Override @@ -5425,7 +5369,7 @@ public final class ExoPlayerTest { final int[] currentWindowIndices = {C.INDEX_UNSET, C.INDEX_UNSET}; ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) - .waitForSeekProcessed() + .waitForPlaybackState(Player.STATE_BUFFERING) .executeRunnable( new PlayerRunnable() { @Override @@ -5458,7 +5402,7 @@ public final class ExoPlayerTest { final long[] currentPositions = {C.TIME_UNSET, C.TIME_UNSET}; ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) - .waitForSeekProcessed() + .waitForPlaybackState(Player.STATE_BUFFERING) .executeRunnable( new PlayerRunnable() { @Override @@ -5501,7 +5445,6 @@ public final class ExoPlayerTest { Arrays.fill(maskingPlaybackStates, C.INDEX_UNSET); ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) - .waitForSeekProcessed() .waitForPlaybackState(Player.STATE_READY) .executeRunnable( new PlayerRunnable() { @@ -5610,7 +5553,7 @@ public final class ExoPlayerTest { ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) .seek(/* windowIndex= */ 1, /* positionMs= */ C.TIME_UNSET) - .waitForSeekProcessed() + .waitForPendingPlayerCommands() .removeMediaItem(/* index= */ 1) .prepare() .waitForPlaybackState(Player.STATE_ENDED) @@ -5637,7 +5580,7 @@ public final class ExoPlayerTest { final int[] maskingPlaybackState = {C.INDEX_UNSET}; ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) - .waitForSeekProcessed() + .waitForPlaybackState(Player.STATE_BUFFERING) .executeRunnable( new PlayerRunnable() { @Override @@ -5671,7 +5614,9 @@ public final class ExoPlayerTest { final int[] currentStates = {C.INDEX_UNSET, C.INDEX_UNSET, C.INDEX_UNSET}; ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) - .waitForSeekProcessed() + // Wait for initial seek to be fully handled by internal player. + .waitForPositionDiscontinuity() + .waitForPendingPlayerCommands() .executeRunnable( new PlayerRunnable() { @Override diff --git a/library/core/src/test/java/com/google/android/exoplayer2/analytics/AnalyticsCollectorTest.java b/library/core/src/test/java/com/google/android/exoplayer2/analytics/AnalyticsCollectorTest.java index df318df774..f9f7f15abc 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/analytics/AnalyticsCollectorTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/analytics/AnalyticsCollectorTest.java @@ -319,7 +319,6 @@ public final class AnalyticsCollectorTest { .waitForIsLoading(true) .waitForIsLoading(false) .seek(/* windowIndex= */ 1, /* positionMs= */ 0) - .waitForSeekProcessed() .play() .build(); TestAnalyticsListener listener = runAnalyticsTest(mediaSource, actionSchedule); @@ -1088,7 +1087,7 @@ public final class AnalyticsCollectorTest { midrollAd /* seek adjustment */, contentAfterMidroll /* ad transition */); assertThat(listener.getEvents(EVENT_SEEK_STARTED)).containsExactly(contentBeforeMidroll); - assertThat(listener.getEvents(EVENT_SEEK_PROCESSED)).containsExactly(midrollAd); + assertThat(listener.getEvents(EVENT_SEEK_PROCESSED)).containsExactly(contentAfterMidroll); assertThat(listener.getEvents(EVENT_LOADING_CHANGED)) .containsExactly( contentBeforeMidroll, diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/Action.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/Action.java index c1aa6cbd6b..835100101c 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/Action.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/Action.java @@ -1024,12 +1024,12 @@ public abstract class Action { } } - /** Waits for {@link Player.EventListener#onSeekProcessed()}. */ - public static final class WaitForSeekProcessed extends Action { + /** Waits until the player acknowledged all pending player commands. */ + public static final class WaitForPendingPlayerCommands extends Action { /** @param tag A tag to use for logging. */ - public WaitForSeekProcessed(String tag) { - super(tag, "WaitForSeekProcessed"); + public WaitForPendingPlayerCommands(String tag) { + super(tag, "WaitForPendingPlayerCommands"); } @Override @@ -1042,14 +1042,14 @@ public abstract class Action { if (nextAction == null) { return; } - player.addListener( - new Player.EventListener() { - @Override - public void onSeekProcessed() { - player.removeListener(this); - nextAction.schedule(player, trackSelector, surface, handler); - } - }); + // Send message to player that will arrive after all other pending commands. Thus, the message + // execution on the app thread will also happen after all other pending command + // acknowledgements have arrived back on the app thread. + player + .createMessage( + (type, data) -> nextAction.schedule(player, trackSelector, surface, handler)) + .setHandler(Util.createHandler()) + .send(); } @Override diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/ActionSchedule.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/ActionSchedule.java index 092326d043..d116fdc6b5 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/ActionSchedule.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/ActionSchedule.java @@ -45,10 +45,10 @@ import com.google.android.exoplayer2.testutil.Action.Stop; import com.google.android.exoplayer2.testutil.Action.ThrowPlaybackException; import com.google.android.exoplayer2.testutil.Action.WaitForIsLoading; import com.google.android.exoplayer2.testutil.Action.WaitForMessage; +import com.google.android.exoplayer2.testutil.Action.WaitForPendingPlayerCommands; import com.google.android.exoplayer2.testutil.Action.WaitForPlayWhenReady; import com.google.android.exoplayer2.testutil.Action.WaitForPlaybackState; import com.google.android.exoplayer2.testutil.Action.WaitForPositionDiscontinuity; -import com.google.android.exoplayer2.testutil.Action.WaitForSeekProcessed; import com.google.android.exoplayer2.testutil.Action.WaitForTimelineChanged; import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; import com.google.android.exoplayer2.util.Assertions; @@ -198,17 +198,19 @@ public final class ActionSchedule { */ public Builder seekAndWait(long positionMs) { return apply(new Seek(tag, positionMs)) - .apply(new WaitForSeekProcessed(tag)) .apply(new WaitForPlaybackState(tag, Player.STATE_READY)); } /** - * Schedules a delay until the player indicates that a seek has been processed. + * Schedules a delay until all pending player commands have been handled. + * + *

A command is considered as having been handled if it arrived on the playback thread and + * the player acknowledged that it received the command back to the app thread. * * @return The builder, for convenience. */ - public Builder waitForSeekProcessed() { - return apply(new WaitForSeekProcessed(tag)); + public Builder waitForPendingPlayerCommands() { + return apply(new WaitForPendingPlayerCommands(tag)); } /**