Commit 76d60b91 by bachinger Committed by Christos Tsilopoulos

Migrate media item transition tests to TestExoPlayer

PiperOrigin-RevId: 396313679
parent 71a4b633
...@@ -55,6 +55,7 @@ import static com.google.android.exoplayer2.robolectric.TestPlayerRunHelper.runU ...@@ -55,6 +55,7 @@ import static com.google.android.exoplayer2.robolectric.TestPlayerRunHelper.runU
import static com.google.android.exoplayer2.robolectric.TestPlayerRunHelper.runUntilTimelineChanged; import static com.google.android.exoplayer2.robolectric.TestPlayerRunHelper.runUntilTimelineChanged;
import static com.google.android.exoplayer2.testutil.FakeSampleStream.FakeSampleStreamItem.END_OF_STREAM_ITEM; import static com.google.android.exoplayer2.testutil.FakeSampleStream.FakeSampleStreamItem.END_OF_STREAM_ITEM;
import static com.google.android.exoplayer2.testutil.FakeSampleStream.FakeSampleStreamItem.oneByteSample; import static com.google.android.exoplayer2.testutil.FakeSampleStream.FakeSampleStreamItem.oneByteSample;
import static com.google.android.exoplayer2.testutil.TestUtil.assertTimelinesSame;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertThrows;
...@@ -104,7 +105,6 @@ import com.google.android.exoplayer2.source.MediaPeriod; ...@@ -104,7 +105,6 @@ import com.google.android.exoplayer2.source.MediaPeriod;
import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId; import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.source.MediaSourceEventListener; import com.google.android.exoplayer2.source.MediaSourceEventListener;
import com.google.android.exoplayer2.source.SilenceMediaSource;
import com.google.android.exoplayer2.source.SinglePeriodTimeline; import com.google.android.exoplayer2.source.SinglePeriodTimeline;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
...@@ -7823,298 +7823,292 @@ public final class ExoPlayerTest { ...@@ -7823,298 +7823,292 @@ public final class ExoPlayerTest {
} }
@Test @Test
public void setMediaSources_notifiesMediaItemTransition() throws Exception { public void setMediaSource_notifiesMediaItemTransition() {
SilenceMediaSource.Factory factory = List<MediaItem> reportedMediaItems = new ArrayList<>();
new SilenceMediaSource.Factory().setDurationUs(C.msToUs(100_000)); List<Integer> reportedTransitionReasons = new ArrayList<>();
SilenceMediaSource mediaSource = factory.setTag("1").createMediaSource(); MediaSource mediaSource = FakeMediaSource.createWithWindowId(/* windowId= */ new Object());
ExoPlayer player = new TestExoPlayerBuilder(context).build();
player.addListener(
new Listener() {
@Override
public void onMediaItemTransition(@Nullable MediaItem mediaItem, int reason) {
reportedMediaItems.add(mediaItem);
reportedTransitionReasons.add(reason);
}
});
ExoPlayerTestRunner exoPlayerTestRunner = player.setMediaSource(mediaSource);
new ExoPlayerTestRunner.Builder(context)
.setMediaSources(mediaSource)
.build()
.start()
.blockUntilEnded(TIMEOUT_MS);
exoPlayerTestRunner.assertMediaItemsTransitionedSame(mediaSource.getMediaItem()); assertThat(reportedMediaItems).containsExactly(mediaSource.getMediaItem());
exoPlayerTestRunner.assertMediaItemsTransitionReasonsEqual( assertThat(reportedTransitionReasons)
Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED); .containsExactly(Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED);
player.release();
} }
@Test @Test
public void setMediaSources_replaceWithSameMediaItem_notifiesMediaItemTransition() public void setMediaSource_replaceWithSameMediaItem_notifiesMediaItemTransition()
throws Exception { throws Exception {
SilenceMediaSource.Factory factory = List<MediaItem> reportedMediaItems = new ArrayList<>();
new SilenceMediaSource.Factory().setDurationUs(C.msToUs(100_000)); List<Integer> reportedTransitionReasons = new ArrayList<>();
SilenceMediaSource mediaSource = factory.setTag("1").createMediaSource(); MediaSource mediaSource = FakeMediaSource.createWithWindowId(/* windowId= */ new Object());
ActionSchedule actionSchedule = ExoPlayer player = new TestExoPlayerBuilder(context).build();
new ActionSchedule.Builder(TAG) player.addListener(
.waitForPlaybackState(Player.STATE_READY) new Listener() {
.setMediaSources(mediaSource) @Override
.waitForPlaybackState(Player.STATE_READY) public void onMediaItemTransition(@Nullable MediaItem mediaItem, int reason) {
.build(); reportedMediaItems.add(mediaItem);
reportedTransitionReasons.add(reason);
}
});
ExoPlayerTestRunner exoPlayerTestRunner = player.setMediaSource(mediaSource);
new ExoPlayerTestRunner.Builder(context) player.prepare();
.setMediaSources(mediaSource) runUntilPlaybackState(player, Player.STATE_READY);
.setActionSchedule(actionSchedule) player.setMediaSource(mediaSource);
.build()
.start()
.blockUntilActionScheduleFinished(TIMEOUT_MS)
.blockUntilEnded(TIMEOUT_MS);
exoPlayerTestRunner.assertMediaItemsTransitionedSame( assertThat(reportedMediaItems)
mediaSource.getMediaItem(), mediaSource.getMediaItem()); .containsExactly(mediaSource.getMediaItem(), mediaSource.getMediaItem());
exoPlayerTestRunner.assertMediaItemsTransitionReasonsEqual( assertThat(reportedTransitionReasons)
Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED, .containsExactly(
Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED); Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED,
Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED);
player.release();
} }
@Test @Test
public void automaticWindowTransition_notifiesMediaItemTransition() throws Exception { public void automaticWindowTransition_notifiesMediaItemTransition() throws Exception {
SilenceMediaSource.Factory factory = List<MediaItem> reportedMediaItems = new ArrayList<>();
new SilenceMediaSource.Factory().setDurationUs(C.msToUs(100_000)); List<Integer> reportedTransitionReasons = new ArrayList<>();
SilenceMediaSource mediaSource1 = factory.setTag("1").createMediaSource(); MediaSource mediaSource1 = FakeMediaSource.createWithWindowId(/* windowId= */ new Object());
SilenceMediaSource mediaSource2 = factory.setTag("2").createMediaSource(); MediaSource mediaSource2 = FakeMediaSource.createWithWindowId(/* windowId= */ new Object());
ExoPlayer player = new TestExoPlayerBuilder(context).build();
player.addListener(
new Listener() {
@Override
public void onMediaItemTransition(@Nullable MediaItem mediaItem, int reason) {
reportedMediaItems.add(mediaItem);
reportedTransitionReasons.add(reason);
}
});
player.setMediaSources(ImmutableList.of(mediaSource1, mediaSource2));
player.prepare();
ExoPlayerTestRunner exoPlayerTestRunner = player.play();
new ExoPlayerTestRunner.Builder(context) runUntilPlaybackState(player, Player.STATE_ENDED);
.setMediaSources(mediaSource1, mediaSource2)
.build()
.start()
.blockUntilEnded(TIMEOUT_MS);
exoPlayerTestRunner.assertMediaItemsTransitionedSame( assertThat(reportedMediaItems)
mediaSource1.getMediaItem(), mediaSource2.getMediaItem()); .containsExactly(mediaSource1.getMediaItem(), mediaSource2.getMediaItem())
exoPlayerTestRunner.assertMediaItemsTransitionReasonsEqual( .inOrder();
Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED, assertThat(reportedTransitionReasons)
Player.MEDIA_ITEM_TRANSITION_REASON_AUTO); .containsExactly(
Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED,
Player.MEDIA_ITEM_TRANSITION_REASON_AUTO)
.inOrder();
player.release();
} }
@Test @Test
public void clearMediaItem_notifiesMediaItemTransition() throws Exception { public void clearMediaItems_notifiesMediaItemTransition() throws Exception {
SilenceMediaSource.Factory factory = List<MediaItem> reportedMediaItems = new ArrayList<>();
new SilenceMediaSource.Factory().setDurationUs(C.msToUs(100_000)); List<Integer> reportedTransitionReasons = new ArrayList<>();
SilenceMediaSource mediaSource1 = factory.setTag("1").createMediaSource(); MediaSource mediaSource1 = FakeMediaSource.createWithWindowId(/* windowId= */ new Object());
SilenceMediaSource mediaSource2 = factory.setTag("2").createMediaSource(); MediaSource mediaSource2 = FakeMediaSource.createWithWindowId(/* windowId= */ new Object());
ActionSchedule actionSchedule = ExoPlayer player = new TestExoPlayerBuilder(context).build();
new ActionSchedule.Builder(TAG) player.addListener(
.pause() new Listener() {
.waitForPlaybackState(Player.STATE_READY) @Override
.playUntilPosition(/* windowIndex= */ 1, /* positionMs= */ 2000) public void onMediaItemTransition(@Nullable MediaItem mediaItem, int reason) {
.clearMediaItems() reportedMediaItems.add(mediaItem);
.build(); reportedTransitionReasons.add(reason);
}
});
player.setMediaSources(ImmutableList.of(mediaSource1, mediaSource2));
player.prepare();
player.play();
runUntilPositionDiscontinuity(player, Player.DISCONTINUITY_REASON_AUTO_TRANSITION);
ExoPlayerTestRunner exoPlayerTestRunner = player.clearMediaItems();
new ExoPlayerTestRunner.Builder(context)
.setMediaSources(mediaSource1, mediaSource2)
.setActionSchedule(actionSchedule)
.build()
.start()
.blockUntilActionScheduleFinished(TIMEOUT_MS)
.blockUntilEnded(TIMEOUT_MS);
exoPlayerTestRunner.assertMediaItemsTransitionedSame( assertThat(reportedMediaItems)
mediaSource1.getMediaItem(), mediaSource2.getMediaItem(), null); .containsExactly(mediaSource1.getMediaItem(), mediaSource2.getMediaItem(), null)
exoPlayerTestRunner.assertMediaItemsTransitionReasonsEqual( .inOrder();
Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED, assertThat(reportedTransitionReasons)
Player.MEDIA_ITEM_TRANSITION_REASON_AUTO, .containsExactly(
Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED); Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED,
Player.MEDIA_ITEM_TRANSITION_REASON_AUTO,
Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED)
.inOrder();
player.release();
} }
@Test @Test
public void seekTo_otherWindow_notifiesMediaItemTransition() throws Exception { public void seekTo_otherWindow_notifiesMediaItemTransition() throws Exception {
SilenceMediaSource.Factory factory = List<MediaItem> reportedMediaItems = new ArrayList<>();
new SilenceMediaSource.Factory().setDurationUs(C.msToUs(100_000)); List<Integer> reportedTransitionReasons = new ArrayList<>();
SilenceMediaSource mediaSource1 = factory.setTag("1").createMediaSource(); MediaSource mediaSource1 = FakeMediaSource.createWithWindowId(/* windowId= */ new Object());
SilenceMediaSource mediaSource2 = factory.setTag("2").createMediaSource(); MediaSource mediaSource2 = FakeMediaSource.createWithWindowId(/* windowId= */ new Object());
ActionSchedule actionSchedule = ExoPlayer player = new TestExoPlayerBuilder(context).build();
new ActionSchedule.Builder(TAG) player.addListener(
.waitForPlaybackState(Player.STATE_READY) new Listener() {
.seek(/* windowIndex= */ 1, /* positionMs= */ 2000) @Override
.build(); public void onMediaItemTransition(@Nullable MediaItem mediaItem, int reason) {
reportedMediaItems.add(mediaItem);
reportedTransitionReasons.add(reason);
}
});
player.setMediaSources(ImmutableList.of(mediaSource1, mediaSource2));
player.prepare();
runUntilPlaybackState(player, Player.STATE_READY);
ExoPlayerTestRunner exoPlayerTestRunner = player.seekTo(/* windowIndex= */ 1, /* positionMs= */ 2000);
new ExoPlayerTestRunner.Builder(context)
.setMediaSources(mediaSource1, mediaSource2)
.setActionSchedule(actionSchedule)
.build()
.start()
.blockUntilActionScheduleFinished(TIMEOUT_MS)
.blockUntilEnded(TIMEOUT_MS);
exoPlayerTestRunner.assertMediaItemsTransitionedSame( assertThat(reportedMediaItems)
mediaSource1.getMediaItem(), mediaSource2.getMediaItem()); .containsExactly(mediaSource1.getMediaItem(), mediaSource2.getMediaItem())
exoPlayerTestRunner.assertMediaItemsTransitionReasonsEqual( .inOrder();
Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED, assertThat(reportedTransitionReasons)
Player.MEDIA_ITEM_TRANSITION_REASON_SEEK); .containsExactly(
Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED,
Player.MEDIA_ITEM_TRANSITION_REASON_SEEK)
.inOrder();
player.release();
} }
@Test @Test
public void seekTo_sameWindow_doesNotNotifyMediaItemTransition() throws Exception { public void seekTo_sameWindow_doesNotNotifyMediaItemTransition() throws Exception {
SilenceMediaSource.Factory factory = List<MediaItem> reportedMediaItems = new ArrayList<>();
new SilenceMediaSource.Factory().setDurationUs(C.msToUs(100_000)); List<Integer> reportedTransitionReasons = new ArrayList<>();
SilenceMediaSource mediaSource1 = factory.setTag("1").createMediaSource(); MediaSource mediaSource1 = FakeMediaSource.createWithWindowId(/* windowId= */ new Object());
SilenceMediaSource mediaSource2 = factory.setTag("2").createMediaSource(); MediaSource mediaSource2 = FakeMediaSource.createWithWindowId(/* windowId= */ new Object());
ActionSchedule actionSchedule = ExoPlayer player = new TestExoPlayerBuilder(context).build();
new ActionSchedule.Builder(TAG) player.addListener(
.pause() new Listener() {
.waitForPlaybackState(Player.STATE_READY) @Override
.playUntilPosition(/* windowIndex= */ 0, /* positionMs= */ 2000) public void onMediaItemTransition(@Nullable MediaItem mediaItem, int reason) {
.seek(/* windowIndex= */ 0, /* positionMs= */ 20_000) reportedMediaItems.add(mediaItem);
.stop() reportedTransitionReasons.add(reason);
.build(); }
});
player.setMediaSources(ImmutableList.of(mediaSource1, mediaSource2));
player.prepare();
runUntilPlaybackState(player, Player.STATE_READY);
ExoPlayerTestRunner exoPlayerTestRunner = player.seekTo(/* windowIndex= */ 0, /* positionMs= */ 2000);
new ExoPlayerTestRunner.Builder(context)
.setMediaSources(mediaSource1, mediaSource2)
.setActionSchedule(actionSchedule)
.build()
.start()
.blockUntilActionScheduleFinished(TIMEOUT_MS)
.blockUntilEnded(TIMEOUT_MS);
exoPlayerTestRunner.assertMediaItemsTransitionedSame(mediaSource1.getMediaItem()); assertThat(reportedMediaItems).containsExactly(mediaSource1.getMediaItem()).inOrder();
exoPlayerTestRunner.assertMediaItemsTransitionReasonsEqual( assertThat(reportedTransitionReasons)
Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED); .containsExactly(Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED)
.inOrder();
player.release();
} }
@Test @Test
public void repeat_notifiesMediaItemTransition() throws Exception { public void repeat_notifiesMediaItemTransition() throws Exception {
MediaItem mediaItem1 = MediaItem.fromUri("http://foo.bar/fake1"); List<MediaItem> reportedMediaItems = new ArrayList<>();
TimelineWindowDefinition window1 = List<Integer> reportedTransitionReasons = new ArrayList<>();
new TimelineWindowDefinition( MediaSource mediaSource1 = FakeMediaSource.createWithWindowId(/* windowId= */ new Object());
/* periodCount= */ 1, MediaSource mediaSource2 = FakeMediaSource.createWithWindowId(/* windowId= */ new Object());
/* id= */ 1, ExoPlayer player = new TestExoPlayerBuilder(context).build();
/* isSeekable= */ true, player.setRepeatMode(Player.REPEAT_MODE_ONE);
/* isDynamic= */ false, player.addListener(
/* isLive= */ false, new Listener() {
/* isPlaceholder= */ false, @Override
/* durationUs = */ 100_000, public void onMediaItemTransition(@Nullable MediaItem mediaItem, int reason) {
/* defaultPositionUs = */ 0, reportedMediaItems.add(mediaItem);
/* windowOffsetInFirstPeriodUs= */ 0, reportedTransitionReasons.add(reason);
AdPlaybackState.NONE, }
mediaItem1); });
MediaItem mediaItem2 = MediaItem.fromUri("http://foo.bar/fake2"); player.setMediaSources(ImmutableList.of(mediaSource1, mediaSource2));
TimelineWindowDefinition window2 = player.prepare();
new TimelineWindowDefinition(
/* periodCount= */ 1,
/* id= */ 2,
/* isSeekable= */ true,
/* isDynamic= */ false,
/* isLive= */ false,
/* isPlaceholder= */ false,
/* durationUs = */ 100_000,
/* defaultPositionUs = */ 0,
/* windowOffsetInFirstPeriodUs= */ 0,
AdPlaybackState.NONE,
mediaItem2);
FakeMediaSource mediaSource1 = new FakeMediaSource(new FakeTimeline(window1));
FakeMediaSource mediaSource2 = new FakeMediaSource(new FakeTimeline(window2));
ActionSchedule actionSchedule =
new ActionSchedule.Builder(TAG)
.pause()
.waitForPlaybackState(Player.STATE_READY)
.executeRunnable(
new PlayerRunnable() {
@Override
public void run(SimpleExoPlayer player) {
player.setRepeatMode(Player.REPEAT_MODE_ONE);
}
})
.playUntilPosition(/* windowIndex= */ 0, /* positionMs= */ 90)
.playUntilPosition(/* windowIndex= */ 0, /* positionMs= */ 80)
.playUntilPosition(/* windowIndex= */ 0, /* positionMs= */ 70)
.executeRunnable(
new PlayerRunnable() {
@Override
public void run(SimpleExoPlayer player) {
player.setRepeatMode(Player.REPEAT_MODE_OFF);
}
})
.play()
.build();
ExoPlayerTestRunner exoPlayerTestRunner = player.play();
new ExoPlayerTestRunner.Builder(context) runUntilPositionDiscontinuity(player, Player.DISCONTINUITY_REASON_AUTO_TRANSITION);
.setMediaSources(mediaSource1, mediaSource2) runUntilPositionDiscontinuity(player, Player.DISCONTINUITY_REASON_AUTO_TRANSITION);
.setActionSchedule(actionSchedule) player.setRepeatMode(Player.REPEAT_MODE_OFF);
.build() runUntilPlaybackState(player, Player.STATE_ENDED);
.start()
.blockUntilActionScheduleFinished(TIMEOUT_MS)
.blockUntilEnded(TIMEOUT_MS);
exoPlayerTestRunner.assertMediaItemsTransitionedSame( assertThat(reportedMediaItems)
mediaSource1.getMediaItem(), .containsExactly(
mediaSource1.getMediaItem(), mediaSource1.getMediaItem(),
mediaSource1.getMediaItem(), mediaSource1.getMediaItem(),
mediaSource2.getMediaItem()); mediaSource1.getMediaItem(),
exoPlayerTestRunner.assertMediaItemsTransitionReasonsEqual( mediaSource2.getMediaItem())
Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED, .inOrder();
Player.MEDIA_ITEM_TRANSITION_REASON_REPEAT, assertThat(reportedTransitionReasons)
Player.MEDIA_ITEM_TRANSITION_REASON_REPEAT, .containsExactly(
Player.MEDIA_ITEM_TRANSITION_REASON_AUTO); Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED,
Player.MEDIA_ITEM_TRANSITION_REASON_REPEAT,
Player.MEDIA_ITEM_TRANSITION_REASON_REPEAT,
Player.MEDIA_ITEM_TRANSITION_REASON_AUTO)
.inOrder();
player.release();
} }
// Tests deprecated stop(boolean reset)
@SuppressWarnings("deprecation")
@Test @Test
public void stop_withReset_notifiesMediaItemTransition() throws Exception { public void stop_withReset_notifiesMediaItemTransition() throws Exception {
SilenceMediaSource.Factory factory = List<MediaItem> reportedMediaItems = new ArrayList<>();
new SilenceMediaSource.Factory().setDurationUs(C.msToUs(100_000)); List<Integer> reportedTransitionReasons = new ArrayList<>();
SilenceMediaSource mediaSource1 = factory.setTag("1").createMediaSource(); MediaSource mediaSource1 = FakeMediaSource.createWithWindowId(/* windowId= */ new Object());
SilenceMediaSource mediaSource2 = factory.setTag("2").createMediaSource(); MediaSource mediaSource2 = FakeMediaSource.createWithWindowId(/* windowId= */ new Object());
ActionSchedule actionSchedule = ExoPlayer player = new TestExoPlayerBuilder(context).build();
new ActionSchedule.Builder(TAG) player.addListener(
.pause() new Listener() {
.waitForPlaybackState(Player.STATE_READY) @Override
.playUntilPosition(/* windowIndex= */ 0, /* positionMs= */ 2000) public void onMediaItemTransition(@Nullable MediaItem mediaItem, int reason) {
.stop(/* reset= */ true) reportedMediaItems.add(mediaItem);
.build(); reportedTransitionReasons.add(reason);
}
});
player.setMediaSources(ImmutableList.of(mediaSource1, mediaSource2));
player.prepare();
runUntilPlaybackState(player, Player.STATE_READY);
ExoPlayerTestRunner exoPlayerTestRunner = player.stop(/* reset= */ true);
new ExoPlayerTestRunner.Builder(context)
.setMediaSources(mediaSource1, mediaSource2)
.setActionSchedule(actionSchedule)
.build()
.start()
.blockUntilActionScheduleFinished(TIMEOUT_MS)
.blockUntilEnded(TIMEOUT_MS);
exoPlayerTestRunner.assertMediaItemsTransitionedSame(mediaSource1.getMediaItem(), null); assertThat(reportedMediaItems).containsExactly(mediaSource1.getMediaItem(), null).inOrder();
exoPlayerTestRunner.assertMediaItemsTransitionReasonsEqual( assertThat(reportedTransitionReasons)
Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED, .containsExactly(
Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED); Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED,
Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED)
.inOrder();
player.release();
} }
@Test @Test
public void stop_withoutReset_doesNotNotifyMediaItemTransition() throws Exception { public void stop_withoutReset_doesNotNotifyMediaItemTransition() throws Exception {
SilenceMediaSource.Factory factory = List<MediaItem> reportedMediaItems = new ArrayList<>();
new SilenceMediaSource.Factory().setDurationUs(C.msToUs(100_000)); List<Integer> reportedTransitionReasons = new ArrayList<>();
SilenceMediaSource mediaSource1 = factory.setTag("1").createMediaSource(); MediaSource mediaSource1 = FakeMediaSource.createWithWindowId(/* windowId= */ new Object());
SilenceMediaSource mediaSource2 = factory.setTag("2").createMediaSource(); MediaSource mediaSource2 = FakeMediaSource.createWithWindowId(/* windowId= */ new Object());
ActionSchedule actionSchedule = ExoPlayer player = new TestExoPlayerBuilder(context).build();
new ActionSchedule.Builder(TAG) player.addListener(
.pause() new Listener() {
.waitForPlaybackState(Player.STATE_READY) @Override
.playUntilPosition(/* windowIndex= */ 0, /* positionMs= */ 2000) public void onMediaItemTransition(@Nullable MediaItem mediaItem, int reason) {
.stop(/* reset= */ false) reportedMediaItems.add(mediaItem);
.build(); reportedTransitionReasons.add(reason);
}
});
player.setMediaSources(ImmutableList.of(mediaSource1, mediaSource2));
player.prepare();
runUntilPlaybackState(player, Player.STATE_READY);
ExoPlayerTestRunner exoPlayerTestRunner = player.stop();
new ExoPlayerTestRunner.Builder(context)
.setMediaSources(mediaSource1, mediaSource2)
.setActionSchedule(actionSchedule)
.build()
.start()
.blockUntilActionScheduleFinished(TIMEOUT_MS)
.blockUntilEnded(TIMEOUT_MS);
exoPlayerTestRunner.assertMediaItemsTransitionedSame(mediaSource1.getMediaItem()); assertThat(reportedMediaItems).containsExactly(mediaSource1.getMediaItem()).inOrder();
exoPlayerTestRunner.assertMediaItemsTransitionReasonsEqual( assertThat(reportedTransitionReasons)
Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED); .containsExactly(Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED)
.inOrder();
player.release();
} }
@Test @Test
public void timelineRefresh_withModifiedMediaItem_doesNotNotifyMediaItemTransition() public void timelineRefresh_withModifiedMediaItem_doesNotNotifyMediaItemTransition()
throws Exception { throws Exception {
List<MediaItem> reportedMediaItems = new ArrayList<>();
List<Integer> reportedTransitionReasons = new ArrayList<>();
List<Timeline> reportedTimelines = new ArrayList<>();
MediaItem initialMediaItem = FakeTimeline.FAKE_MEDIA_ITEM.buildUpon().setTag(0).build(); MediaItem initialMediaItem = FakeTimeline.FAKE_MEDIA_ITEM.buildUpon().setTag(0).build();
TimelineWindowDefinition initialWindow = TimelineWindowDefinition initialWindow =
new TimelineWindowDefinition( new TimelineWindowDefinition(
...@@ -8145,32 +8139,35 @@ public final class ExoPlayerTest { ...@@ -8145,32 +8139,35 @@ public final class ExoPlayerTest {
FakeTimeline timeline = new FakeTimeline(initialWindow); FakeTimeline timeline = new FakeTimeline(initialWindow);
FakeTimeline newTimeline = new FakeTimeline(secondWindow); FakeTimeline newTimeline = new FakeTimeline(secondWindow);
FakeMediaSource mediaSource = new FakeMediaSource(timeline); FakeMediaSource mediaSource = new FakeMediaSource(timeline);
ActionSchedule actionSchedule = ExoPlayer player = new TestExoPlayerBuilder(context).build();
new ActionSchedule.Builder(TAG) player.addListener(
.pause() new Listener() {
.waitForPlaybackState(Player.STATE_READY) @Override
.playUntilPosition(/* windowIndex= */ 0, /* positionMs= */ 2000) public void onTimelineChanged(Timeline timeline, int reason) {
.waitForPlayWhenReady(false) reportedTimelines.add(timeline);
.executeRunnable( }
() -> {
mediaSource.setNewSourceInfo(newTimeline);
})
.play()
.build();
ExoPlayerTestRunner exoPlayerTestRunner = @Override
new ExoPlayerTestRunner.Builder(context) public void onMediaItemTransition(@Nullable MediaItem mediaItem, int reason) {
.setMediaSources(mediaSource) reportedMediaItems.add(mediaItem);
.setActionSchedule(actionSchedule) reportedTransitionReasons.add(reason);
.build() }
.start() });
.blockUntilActionScheduleFinished(TIMEOUT_MS) player.setMediaSource(mediaSource);
.blockUntilEnded(TIMEOUT_MS); player.prepare();
player.play();
runUntilPlaybackState(player, Player.STATE_READY);
exoPlayerTestRunner.assertTimelinesSame(placeholderTimeline, timeline, newTimeline); mediaSource.setNewSourceInfo(newTimeline);
exoPlayerTestRunner.assertMediaItemsTransitionReasonsEqual( runUntilPlaybackState(player, Player.STATE_ENDED);
Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED);
exoPlayerTestRunner.assertMediaItemsTransitionedSame(initialMediaItem); assertTimelinesSame(
reportedTimelines, ImmutableList.of(placeholderTimeline, timeline, newTimeline));
assertThat(reportedMediaItems).containsExactly(initialMediaItem).inOrder();
assertThat(reportedTransitionReasons)
.containsExactly(Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED)
.inOrder();
player.release();
} }
@Test @Test
......
...@@ -555,27 +555,6 @@ public final class ExoPlayerTestRunner implements Player.Listener, ActionSchedul ...@@ -555,27 +555,6 @@ public final class ExoPlayerTestRunner implements Player.Listener, ActionSchedul
} }
/** /**
* Asserts that the media items reported by {@link
* Player.Listener#onMediaItemTransition(MediaItem, int)} are the same as the provided media
* items.
*
* @param mediaItems A list of expected {@link MediaItem media items}.
*/
public void assertMediaItemsTransitionedSame(MediaItem... mediaItems) {
assertThat(this.mediaItems).containsExactlyElementsIn(mediaItems).inOrder();
}
/**
* Asserts that the media item transition reasons reported by {@link
* Player.Listener#onMediaItemTransition(MediaItem, int)} are the same as the provided reasons.
*
* @param reasons A list of expected transition reasons.
*/
public void assertMediaItemsTransitionReasonsEqual(Integer... reasons) {
assertThat(this.mediaItemTransitionReasons).containsExactlyElementsIn(reasons).inOrder();
}
/**
* Asserts that the playback states reported by {@link * Asserts that the playback states reported by {@link
* Player.Listener#onPlaybackStateChanged(int)} are equal to the provided playback states. * Player.Listener#onPlaybackStateChanged(int)} are equal to the provided playback states.
*/ */
......
...@@ -73,6 +73,13 @@ public class FakeMediaSource extends BaseMediaSource { ...@@ -73,6 +73,13 @@ public class FakeMediaSource extends BaseMediaSource {
} }
} }
/** Convenience method to create a {@link FakeMediaSource} with the given window id. */
public static FakeMediaSource createWithWindowId(Object windowId) {
return new FakeMediaSource(
new FakeTimeline(
new FakeTimeline.TimelineWindowDefinition(/* periodCount= */ 1, windowId)));
}
/** The media item used by the fake media source. */ /** The media item used by the fake media source. */
public static final MediaItem FAKE_MEDIA_ITEM = public static final MediaItem FAKE_MEDIA_ITEM =
new MediaItem.Builder().setMediaId("FakeMediaSource").setUri("http://manifest.uri").build(); new MediaItem.Builder().setMediaId("FakeMediaSource").setUri("http://manifest.uri").build();
......
...@@ -26,6 +26,7 @@ import android.graphics.Color; ...@@ -26,6 +26,7 @@ import android.graphics.Color;
import android.media.MediaCodec; import android.media.MediaCodec;
import android.net.Uri; import android.net.Uri;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.database.DatabaseProvider; import com.google.android.exoplayer2.database.DatabaseProvider;
import com.google.android.exoplayer2.database.DefaultDatabaseProvider; import com.google.android.exoplayer2.database.DefaultDatabaseProvider;
import com.google.android.exoplayer2.extractor.DefaultExtractorInput; import com.google.android.exoplayer2.extractor.DefaultExtractorInput;
...@@ -45,6 +46,7 @@ import java.io.FileOutputStream; ...@@ -45,6 +46,7 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.List;
import java.util.Random; import java.util.Random;
/** Utility methods for tests. */ /** Utility methods for tests. */
...@@ -184,6 +186,23 @@ public class TestUtil { ...@@ -184,6 +186,23 @@ public class TestUtil {
} }
/** /**
* Asserts that the actual timelines are the same to the expected timelines. This assert differs
* from testing equality by not comparing period ids which may be different due to id mapping of
* child source period ids.
*
* @param actualTimelines A list of actual {@link Timeline timelines}.
* @param expectedTimelines A list of expected {@link Timeline timelines}.
*/
public static void assertTimelinesSame(
List<Timeline> actualTimelines, List<Timeline> expectedTimelines) {
assertThat(actualTimelines).hasSize(expectedTimelines.size());
for (int i = 0; i < actualTimelines.size(); i++) {
assertThat(new NoUidTimeline(actualTimelines.get(i)))
.isEqualTo(new NoUidTimeline(expectedTimelines.get(i)));
}
}
/**
* Asserts that data read from a {@link DataSource} matches {@code expected}. * Asserts that data read from a {@link DataSource} matches {@code expected}.
* *
* @param dataSource The {@link DataSource} through which to read. * @param dataSource The {@link DataSource} through which to read.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment