Skip to content

Commit 5f940af

Browse files
marcbaechingercopybara-github
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
1 parent f672590 commit 5f940af

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
@@ -68,6 +68,11 @@
6868
configure this value.
6969
* Fix issue where notifications reappear after they have been dismissed by
7070
the user ([#2302](https://github.com/androidx/media/issues/2302)).
71+
* Fix a bug where the `PlayerWrapper` returned a single-item timeline when
72+
the wrapped player is actually empty. This happened when the wrapped
73+
player doesn't have `COMMAND_GET_TIMELINE` available while
74+
`COMMAND_GET_CURRENT_MEDIA_ITEM` is available and the wrapped player is
75+
empty ([#2320](https://github.com/androidx/media/issues/2320)).
7176
* UI:
7277
* Enable `PlayerSurface` to work with `ExoPlayer.setVideoEffects` and
7378
`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
@@ -670,7 +670,9 @@ public Timeline getCurrentTimelineWithCommandCheck() {
670670
if (isCommandAvailable(COMMAND_GET_TIMELINE)) {
671671
return getCurrentTimeline();
672672
} else if (isCommandAvailable(COMMAND_GET_CURRENT_MEDIA_ITEM)) {
673-
return new CurrentMediaItemOnlyTimeline(this);
673+
return getCurrentTimeline().isEmpty()
674+
? Timeline.EMPTY
675+
: new CurrentMediaItemOnlyTimeline(this);
674676
}
675677
return Timeline.EMPTY;
676678
}

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)