From caf1c77af1822d0268d7f028f358374bbe2ba1c8 Mon Sep 17 00:00:00 2001 From: tonihei Date: Mon, 22 May 2023 13:32:46 +0100 Subject: [PATCH] Keep pending initial position when setting empty playlist MediaControllerImplBase currently drops the pending initial seek position when a user sets an empty playlist. When seeking in empty playlists and setting new empty playlists, the class also drops the the period index (and wrongly assigns zero instead of the windowIndex). #minor-release PiperOrigin-RevId: 534035046 --- .../session/MediaControllerImplBase.java | 6 +-- .../MediaControllerStateMaskingTest.java | 37 ++++++++++++++++++- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/libraries/session/src/main/java/androidx/media3/session/MediaControllerImplBase.java b/libraries/session/src/main/java/androidx/media3/session/MediaControllerImplBase.java index 7ad7b1d91e..58870ee93c 100644 --- a/libraries/session/src/main/java/androidx/media3/session/MediaControllerImplBase.java +++ b/libraries/session/src/main/java/androidx/media3/session/MediaControllerImplBase.java @@ -1804,7 +1804,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; } else if (startIndex == C.INDEX_UNSET) { startIndex = playerInfo.sessionPositionInfo.positionInfo.mediaItemIndex; startPositionMs = playerInfo.sessionPositionInfo.positionInfo.positionMs; - if (startIndex >= newTimeline.getWindowCount()) { + if (!newTimeline.isEmpty() && startIndex >= newTimeline.getWindowCount()) { correctedStartIndex = true; startIndex = newTimeline.getFirstWindowIndex(playerInfo.shuffleModeEnabled); startPositionMs = C.TIME_UNSET; @@ -1821,7 +1821,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; startIndex, /* mediaItem= */ null, /* periodUid= */ null, - /* periodIndex= */ 0, + startIndex, /* positionMs= */ startPositionMs == C.TIME_UNSET ? 0 : startPositionMs, /* contentPositionMs= */ startPositionMs == C.TIME_UNSET ? 0 : startPositionMs, /* adGroupIndex= */ C.INDEX_UNSET, @@ -1987,7 +1987,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; windowIndex, /* mediaItem= */ null, /* periodUid= */ null, - /* periodIndex= */ 0, + windowIndex, /* positionMs= */ positionMs == C.TIME_UNSET ? 0 : positionMs, /* contentPositionMs= */ positionMs == C.TIME_UNSET ? 0 : positionMs, /* adGroupIndex= */ C.INDEX_UNSET, diff --git a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerStateMaskingTest.java b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerStateMaskingTest.java index 03642c0d85..086930523f 100644 --- a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerStateMaskingTest.java +++ b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerStateMaskingTest.java @@ -1308,7 +1308,7 @@ public class MediaControllerStateMaskingTest { int initialBufferedPosition = 0; int initialTotalBufferedPosition = 0; int testMediaItemIndex = 3; - int testPeriodIndex = initialPeriodIndex; + int testPeriodIndex = 3; long testSeekPositionMs = 3_000; long testPosition = testSeekPositionMs; long testBufferedPosition = testSeekPositionMs; @@ -1576,6 +1576,39 @@ public class MediaControllerStateMaskingTest { assertThat(totalBufferedDurationRef.get()).isEqualTo(testTotalBufferedDuration); } + @Test + public void setMediaItems_toEmptyListAndResetPositionFalse_correctMasking() throws Exception { + Bundle playerConfig = + new RemoteMediaSession.MockPlayerConfigBuilder() + .setCurrentMediaItemIndex(2) + .setCurrentPeriodIndex(2) + .setCurrentPosition(8000) + .setContentPosition(8000) + .build(); + remoteSession.setPlayer(playerConfig); + MediaController controller = controllerTestRule.createController(remoteSession.getToken()); + + AtomicReference currentTimelineRef = new AtomicReference<>(); + AtomicInteger currentMediaItemIndexRef = new AtomicInteger(); + AtomicLong currentPositionRef = new AtomicLong(); + AtomicInteger currentPeriodIndexRef = new AtomicInteger(); + threadTestRule + .getHandler() + .postAndSync( + () -> { + controller.setMediaItems(ImmutableList.of(), /* resetPosition= */ false); + currentTimelineRef.set(controller.getCurrentTimeline()); + currentMediaItemIndexRef.set(controller.getCurrentMediaItemIndex()); + currentPositionRef.set((int) controller.getCurrentPosition()); + currentPeriodIndexRef.set(controller.getCurrentPeriodIndex()); + }); + + assertThat(currentPositionRef.get()).isEqualTo(8000); + assertThat(currentTimelineRef.get().isEmpty()).isTrue(); + assertThat(currentMediaItemIndexRef.get()).isEqualTo(2); + assertThat(currentPeriodIndexRef.get()).isEqualTo(2); + } + @Test public void setMediaItems_withStartMediaItemIndexAndStartPosition() throws Exception { int initialMediaItemIndex = 2; @@ -1687,7 +1720,7 @@ public class MediaControllerStateMaskingTest { long initialTotalBufferedDuration = 1_200; List testMediaItemList = new ArrayList<>(); int testMediaItemIndex = 1; - int testPeriodIndex = 0; + int testPeriodIndex = 1; long testPosition = 1_000; long testBufferedPosition = 1_000; long testTotalBufferedDuration = 0;