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: androidx/media#2320
PiperOrigin-RevId: 746071237
This commit is contained in:
bachinger 2025-04-10 09:57:21 -07:00 committed by Copybara-Service
parent f672590b2d
commit 5f940af3df
3 changed files with 56 additions and 1 deletions

View File

@ -68,6 +68,11 @@
configure this value.
* Fix issue where notifications reappear after they have been dismissed by
the user ([#2302](https://github.com/androidx/media/issues/2302)).
* Fix a bug where the `PlayerWrapper` returned a single-item timeline when
the wrapped player is actually empty. This happened when the wrapped
player doesn't have `COMMAND_GET_TIMELINE` available while
`COMMAND_GET_CURRENT_MEDIA_ITEM` is available and the wrapped player is
empty ([#2320](https://github.com/androidx/media/issues/2320)).
* UI:
* Enable `PlayerSurface` to work with `ExoPlayer.setVideoEffects` and
`CompositionPlayer`.

View File

@ -670,7 +670,9 @@ import java.util.List;
if (isCommandAvailable(COMMAND_GET_TIMELINE)) {
return getCurrentTimeline();
} else if (isCommandAvailable(COMMAND_GET_CURRENT_MEDIA_ITEM)) {
return new CurrentMediaItemOnlyTimeline(this);
return getCurrentTimeline().isEmpty()
? Timeline.EMPTY
: new CurrentMediaItemOnlyTimeline(this);
}
return Timeline.EMPTY;
}

View File

@ -22,6 +22,8 @@ import static org.mockito.Mockito.when;
import android.os.Bundle;
import android.os.Looper;
import androidx.media3.common.Player;
import androidx.media3.common.Timeline;
import androidx.media3.test.utils.FakeTimeline;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.collect.ImmutableList;
import org.junit.Before;
@ -57,6 +59,52 @@ public class PlayerWrapperTest {
when(player.getApplicationLooper()).thenReturn(Looper.myLooper());
}
@Test
public void
getCurrentTimelineWithCommandCheck_withoutCommandGetTimelineAndGetCurrentMediaItem_isEmpty() {
when(player.isCommandAvailable(Player.COMMAND_GET_TIMELINE)).thenReturn(false);
when(player.isCommandAvailable(Player.COMMAND_GET_CURRENT_MEDIA_ITEM)).thenReturn(false);
when(player.getCurrentTimeline()).thenReturn(new FakeTimeline(/* windowCount= */ 3));
Timeline currentTimeline = playerWrapper.getCurrentTimelineWithCommandCheck();
assertThat(currentTimeline.isEmpty()).isTrue();
}
@Test
public void getCurrentTimelineWithCommandCheck_withoutCommandGetTimelineWhenEmpty_isEmpty() {
when(player.isCommandAvailable(Player.COMMAND_GET_TIMELINE)).thenReturn(false);
when(player.isCommandAvailable(Player.COMMAND_GET_CURRENT_MEDIA_ITEM)).thenReturn(true);
when(player.getCurrentTimeline()).thenReturn(Timeline.EMPTY);
Timeline currentTimeline = playerWrapper.getCurrentTimelineWithCommandCheck();
assertThat(currentTimeline.isEmpty()).isTrue();
}
@Test
public void
getCurrentTimelineWithCommandCheck_withoutCommandGetTimelineWhenMultipleItems_hasSingleItemTimeline() {
when(player.isCommandAvailable(Player.COMMAND_GET_TIMELINE)).thenReturn(false);
when(player.isCommandAvailable(Player.COMMAND_GET_CURRENT_MEDIA_ITEM)).thenReturn(true);
when(player.getCurrentTimeline()).thenReturn(new FakeTimeline(/* windowCount= */ 3));
Timeline currentTimeline = playerWrapper.getCurrentTimelineWithCommandCheck();
assertThat(currentTimeline.getWindowCount()).isEqualTo(1);
}
@Test
public void getCurrentTimelineWithCommandCheck_withCommandGetTimeline_returnOriginalTimeline() {
when(player.isCommandAvailable(Player.COMMAND_GET_TIMELINE)).thenReturn(true);
when(player.isCommandAvailable(Player.COMMAND_GET_CURRENT_MEDIA_ITEM)).thenReturn(false);
when(player.getCurrentTimeline()).thenReturn(new FakeTimeline(/* windowCount= */ 3));
Timeline currentTimeline = playerWrapper.getCurrentTimelineWithCommandCheck();
assertThat(currentTimeline.getWindowCount()).isEqualTo(3);
}
@Test
public void createSessionPositionInfoForBundling() {
int testAdGroupIndex = 12;