Skip to content

Commit 75e2522

Browse files
marcbaechingertonihei
authored andcommitted
Always return empty timeline when wrapped player is empty
In `PlayerWrapper.getCurrentTimelineWithCommandCheck()` we always return `new CurrentMediaItemOnlyTimeline(this)` in case the wrapped player doesn't have `COMMAND_GET_TIMELINE` available but has `COMMAND_GET_CURRENT_MEDIA_ITEM`. This is emulating a single item timeline with a static window count of 1 which isn't correct when the wrapped player is empty. Instead, when the wrapped player is empty we need to return an empty timeline to match the wrapped player. Issue: #2320 PiperOrigin-RevId: 746071237 (cherry picked from commit 5f940af)
1 parent 157fd8a commit 75e2522

File tree

3 files changed

+56
-1
lines changed

3 files changed

+56
-1
lines changed

RELEASENOTES.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@
6767
configure this value.
6868
* Fix issue where notifications reappear after they have been dismissed by
6969
the user ([#2302](https://github.com/androidx/media/issues/2302)).
70+
* Fix a bug where the `PlayerWrapper` returned a single-item timeline when
71+
the wrapped player is actually empty. This happened when the wrapped
72+
player doesn't have `COMMAND_GET_TIMELINE` available while
73+
`COMMAND_GET_CURRENT_MEDIA_ITEM` is available and the wrapped player is
74+
empty ([#2320](https://github.com/androidx/media/issues/2320)).
7075
* UI:
7176
* Enable `PlayerSurface` to work with `ExoPlayer.setVideoEffects` and
7277
`CompositionPlayer`.

libraries/session/src/main/java/androidx/media3/session/PlayerWrapper.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,9 @@ public Timeline getCurrentTimelineWithCommandCheck() {
710710
if (isCommandAvailable(COMMAND_GET_TIMELINE)) {
711711
return getCurrentTimeline();
712712
} else if (isCommandAvailable(COMMAND_GET_CURRENT_MEDIA_ITEM)) {
713-
return new CurrentMediaItemOnlyTimeline(this);
713+
return getCurrentTimeline().isEmpty()
714+
? Timeline.EMPTY
715+
: new CurrentMediaItemOnlyTimeline(this);
714716
}
715717
return Timeline.EMPTY;
716718
}

libraries/session/src/test/java/androidx/media3/session/PlayerWrapperTest.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import android.os.Bundle;
2323
import android.os.Looper;
2424
import androidx.media3.common.Player;
25+
import androidx.media3.common.Timeline;
26+
import androidx.media3.test.utils.FakeTimeline;
2527
import androidx.test.ext.junit.runners.AndroidJUnit4;
2628
import com.google.common.collect.ImmutableList;
2729
import org.junit.Before;
@@ -57,6 +59,52 @@ public void setUp() {
5759
when(player.getApplicationLooper()).thenReturn(Looper.myLooper());
5860
}
5961

62+
@Test
63+
public void
64+
getCurrentTimelineWithCommandCheck_withoutCommandGetTimelineAndGetCurrentMediaItem_isEmpty() {
65+
when(player.isCommandAvailable(Player.COMMAND_GET_TIMELINE)).thenReturn(false);
66+
when(player.isCommandAvailable(Player.COMMAND_GET_CURRENT_MEDIA_ITEM)).thenReturn(false);
67+
when(player.getCurrentTimeline()).thenReturn(new FakeTimeline(/* windowCount= */ 3));
68+
69+
Timeline currentTimeline = playerWrapper.getCurrentTimelineWithCommandCheck();
70+
71+
assertThat(currentTimeline.isEmpty()).isTrue();
72+
}
73+
74+
@Test
75+
public void getCurrentTimelineWithCommandCheck_withoutCommandGetTimelineWhenEmpty_isEmpty() {
76+
when(player.isCommandAvailable(Player.COMMAND_GET_TIMELINE)).thenReturn(false);
77+
when(player.isCommandAvailable(Player.COMMAND_GET_CURRENT_MEDIA_ITEM)).thenReturn(true);
78+
when(player.getCurrentTimeline()).thenReturn(Timeline.EMPTY);
79+
80+
Timeline currentTimeline = playerWrapper.getCurrentTimelineWithCommandCheck();
81+
82+
assertThat(currentTimeline.isEmpty()).isTrue();
83+
}
84+
85+
@Test
86+
public void
87+
getCurrentTimelineWithCommandCheck_withoutCommandGetTimelineWhenMultipleItems_hasSingleItemTimeline() {
88+
when(player.isCommandAvailable(Player.COMMAND_GET_TIMELINE)).thenReturn(false);
89+
when(player.isCommandAvailable(Player.COMMAND_GET_CURRENT_MEDIA_ITEM)).thenReturn(true);
90+
when(player.getCurrentTimeline()).thenReturn(new FakeTimeline(/* windowCount= */ 3));
91+
92+
Timeline currentTimeline = playerWrapper.getCurrentTimelineWithCommandCheck();
93+
94+
assertThat(currentTimeline.getWindowCount()).isEqualTo(1);
95+
}
96+
97+
@Test
98+
public void getCurrentTimelineWithCommandCheck_withCommandGetTimeline_returnOriginalTimeline() {
99+
when(player.isCommandAvailable(Player.COMMAND_GET_TIMELINE)).thenReturn(true);
100+
when(player.isCommandAvailable(Player.COMMAND_GET_CURRENT_MEDIA_ITEM)).thenReturn(false);
101+
when(player.getCurrentTimeline()).thenReturn(new FakeTimeline(/* windowCount= */ 3));
102+
103+
Timeline currentTimeline = playerWrapper.getCurrentTimelineWithCommandCheck();
104+
105+
assertThat(currentTimeline.getWindowCount()).isEqualTo(3);
106+
}
107+
60108
@Test
61109
public void createSessionPositionInfoForBundling() {
62110
int testAdGroupIndex = 12;

0 commit comments

Comments
 (0)