diff --git a/library/core/src/androidTest/java/com/google/android/exoplayer2/TimelineTest.java b/library/core/src/androidTest/java/com/google/android/exoplayer2/TimelineTest.java index 699c620da9..bf6ee31165 100644 --- a/library/core/src/androidTest/java/com/google/android/exoplayer2/TimelineTest.java +++ b/library/core/src/androidTest/java/com/google/android/exoplayer2/TimelineTest.java @@ -15,14 +15,8 @@ */ package com.google.android.exoplayer2; -import com.google.android.exoplayer2.ExoPlayer.RepeatMode; -import com.google.android.exoplayer2.Timeline.Period; -import com.google.android.exoplayer2.Timeline.Window; -import com.google.android.exoplayer2.source.MediaPeriod; -import com.google.android.exoplayer2.source.MediaSource; -import com.google.android.exoplayer2.source.MediaSource.Listener; -import com.google.android.exoplayer2.upstream.Allocator; -import java.io.IOException; +import com.google.android.exoplayer2.testutil.TimelineAsserts; +import com.google.android.exoplayer2.testutil.TimelineAsserts.FakeTimeline; import junit.framework.TestCase; /** @@ -30,255 +24,31 @@ import junit.framework.TestCase; */ public class TimelineTest extends TestCase { - /** - * Fake timeline with multiple periods and user-defined window id. - */ - public static final class FakeTimeline extends Timeline { - - private static final int WINDOW_DURATION_US = 1000000; - - private final int periodCount; - private final int id; - - public FakeTimeline(int periodCount, int id) { - this.periodCount = periodCount; - this.id = id; - } - - @Override - public int getWindowCount() { - return 1; - } - - @Override - public Window getWindow(int windowIndex, Window window, boolean setIds, - long defaultPositionProjectionUs) { - return window.set(id, 0, 0, true, false, 0, WINDOW_DURATION_US, 0, periodCount - 1, 0); - } - - @Override - public int getPeriodCount() { - return periodCount; - } - - @Override - public Period getPeriod(int periodIndex, Period period, boolean setIds) { - return period.set(periodIndex, null, 0, WINDOW_DURATION_US, 0); - } - - @Override - public int getIndexOfPeriod(Object uid) { - return C.INDEX_UNSET; - } - } - - /** - * Stub media source which returns a provided timeline as source info and keeps track if it is - * prepared and released. - */ - public static class StubMediaSource implements MediaSource { - private final Timeline timeline; - - private boolean isPrepared; - private volatile boolean isReleased; - - public StubMediaSource(Timeline timeline) { - this.timeline = timeline; - } - - @Override - public void prepareSource(ExoPlayer player, boolean isTopLevelSource, Listener listener) { - assertFalse(isPrepared); - listener.onSourceInfoRefreshed(timeline, null); - isPrepared = true; - } - - @Override - public void maybeThrowSourceInfoRefreshError() throws IOException { - } - - @Override - public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator) { - return null; - } - - @Override - public void releasePeriod(MediaPeriod mediaPeriod) { - } - - @Override - public void releaseSource() { - assertTrue(isPrepared); - isReleased = true; - } - - public void assertReleased() { - assertTrue(isReleased); - } - } - - /** - * Extracts the timeline from a media source. - */ - public static Timeline extractTimelineFromMediaSource(MediaSource mediaSource) { - class TimelineListener implements Listener { - private Timeline timeline; - @Override - public void onSourceInfoRefreshed(Timeline timeline, Object manifest) { - this.timeline = timeline; - } - } - TimelineListener listener = new TimelineListener(); - mediaSource.prepareSource(null, true, listener); - return listener.timeline; - } - - /** - * Verify the behaviour of {@link Timeline#getNextWindowIndex(int, int)}, - * {@link Timeline#getPreviousWindowIndex(int, int)}, - * {@link Timeline#getWindow(int, Window, boolean)}, - * {@link Timeline#getNextPeriodIndex(int, Period, Window, int)}, and - * {@link Timeline#getPeriod(int, Period, boolean)}. - */ - public static final class TimelineVerifier { - - private final Timeline timeline; - - public TimelineVerifier(Timeline timeline) { - this.timeline = timeline; - } - - public TimelineVerifier assertEmpty() { - assertWindowIds(); - assertPeriodCounts(); - return this; - } - - /** - * @param expectedWindowIds A list of expected window IDs. If an ID is unknown or not important - * {@code null} can be passed to skip this window. - */ - public TimelineVerifier assertWindowIds(Object... expectedWindowIds) { - Window window = new Window(); - assertEquals(expectedWindowIds.length, timeline.getWindowCount()); - for (int i = 0; i < timeline.getWindowCount(); i++) { - timeline.getWindow(i, window, true); - if (expectedWindowIds[i] != null) { - assertEquals(expectedWindowIds[i], window.id); - } - } - return this; - } - - public TimelineVerifier assertWindowIsDynamic(boolean... windowIsDynamic) { - Window window = new Window(); - for (int i = 0; i < timeline.getWindowCount(); i++) { - timeline.getWindow(i, window, true); - assertEquals(windowIsDynamic[i], window.isDynamic); - } - return this; - } - - public TimelineVerifier assertPreviousWindowIndices(@RepeatMode int repeatMode, - int... expectedPreviousWindowIndices) { - for (int i = 0; i < timeline.getWindowCount(); i++) { - assertEquals(expectedPreviousWindowIndices[i], - timeline.getPreviousWindowIndex(i, repeatMode)); - } - return this; - } - - public TimelineVerifier assertNextWindowIndices(@RepeatMode int repeatMode, - int... expectedNextWindowIndices) { - for (int i = 0; i < timeline.getWindowCount(); i++) { - assertEquals(expectedNextWindowIndices[i], - timeline.getNextWindowIndex(i, repeatMode)); - } - return this; - } - - public TimelineVerifier assertPeriodCounts(int... expectedPeriodCounts) { - int windowCount = timeline.getWindowCount(); - int[] accumulatedPeriodCounts = new int[windowCount + 1]; - accumulatedPeriodCounts[0] = 0; - for (int i = 0; i < windowCount; i++) { - accumulatedPeriodCounts[i + 1] = accumulatedPeriodCounts[i] + expectedPeriodCounts[i]; - } - assertEquals(accumulatedPeriodCounts[accumulatedPeriodCounts.length - 1], - timeline.getPeriodCount()); - Window window = new Window(); - Period period = new Period(); - for (int i = 0; i < windowCount; i++) { - timeline.getWindow(i, window, true); - assertEquals(accumulatedPeriodCounts[i], window.firstPeriodIndex); - assertEquals(accumulatedPeriodCounts[i + 1] - 1, window.lastPeriodIndex); - } - int expectedWindowIndex = 0; - for (int i = 0; i < timeline.getPeriodCount(); i++) { - timeline.getPeriod(i, period, true); - while (i >= accumulatedPeriodCounts[expectedWindowIndex + 1]) { - expectedWindowIndex++; - } - assertEquals(expectedWindowIndex, period.windowIndex); - if (i < accumulatedPeriodCounts[expectedWindowIndex + 1] - 1) { - assertEquals(i + 1, timeline.getNextPeriodIndex(i, period, window, - ExoPlayer.REPEAT_MODE_OFF)); - assertEquals(i + 1, timeline.getNextPeriodIndex(i, period, window, - ExoPlayer.REPEAT_MODE_ONE)); - assertEquals(i + 1, timeline.getNextPeriodIndex(i, period, window, - ExoPlayer.REPEAT_MODE_ALL)); - } else { - int nextWindowOff = timeline.getNextWindowIndex(expectedWindowIndex, - ExoPlayer.REPEAT_MODE_OFF); - int nextWindowOne = timeline.getNextWindowIndex(expectedWindowIndex, - ExoPlayer.REPEAT_MODE_ONE); - int nextWindowAll = timeline.getNextWindowIndex(expectedWindowIndex, - ExoPlayer.REPEAT_MODE_ALL); - int nextPeriodOff = nextWindowOff == C.INDEX_UNSET ? C.INDEX_UNSET - : accumulatedPeriodCounts[nextWindowOff]; - int nextPeriodOne = nextWindowOne == C.INDEX_UNSET ? C.INDEX_UNSET - : accumulatedPeriodCounts[nextWindowOne]; - int nextPeriodAll = nextWindowAll == C.INDEX_UNSET ? C.INDEX_UNSET - : accumulatedPeriodCounts[nextWindowAll]; - assertEquals(nextPeriodOff, timeline.getNextPeriodIndex(i, period, window, - ExoPlayer.REPEAT_MODE_OFF)); - assertEquals(nextPeriodOne, timeline.getNextPeriodIndex(i, period, window, - ExoPlayer.REPEAT_MODE_ONE)); - assertEquals(nextPeriodAll, timeline.getNextPeriodIndex(i, period, window, - ExoPlayer.REPEAT_MODE_ALL)); - } - } - return this; - } - } - public void testEmptyTimeline() { - new TimelineVerifier(Timeline.EMPTY).assertEmpty(); + TimelineAsserts.assertEmpty(Timeline.EMPTY); } public void testSinglePeriodTimeline() { Timeline timeline = new FakeTimeline(1, 111); - new TimelineVerifier(timeline) - .assertWindowIds(111) - .assertPeriodCounts(1) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_OFF, C.INDEX_UNSET) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_ONE, 0) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_ALL, 0) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_OFF, C.INDEX_UNSET) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_ONE, 0) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_ALL, 0); + TimelineAsserts.assertWindowIds(timeline, 111); + TimelineAsserts.assertPeriodCounts(timeline, 1); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_OFF, C.INDEX_UNSET); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ONE, 0); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ALL, 0); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_OFF, C.INDEX_UNSET); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ONE, 0); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ALL, 0); } public void testMultiPeriodTimeline() { Timeline timeline = new FakeTimeline(5, 111); - new TimelineVerifier(timeline) - .assertWindowIds(111) - .assertPeriodCounts(5) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_OFF, C.INDEX_UNSET) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_ONE, 0) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_ALL, 0) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_OFF, C.INDEX_UNSET) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_ONE, 0) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_ALL, 0); + TimelineAsserts.assertWindowIds(timeline, 111); + TimelineAsserts.assertPeriodCounts(timeline, 5); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_OFF, C.INDEX_UNSET); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ONE, 0); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ALL, 0); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_OFF, C.INDEX_UNSET); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ONE, 0); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ALL, 0); } } diff --git a/library/core/src/androidTest/java/com/google/android/exoplayer2/source/ClippingMediaSourceTest.java b/library/core/src/androidTest/java/com/google/android/exoplayer2/source/ClippingMediaSourceTest.java index 145f6fc179..dbfd276b42 100644 --- a/library/core/src/androidTest/java/com/google/android/exoplayer2/source/ClippingMediaSourceTest.java +++ b/library/core/src/androidTest/java/com/google/android/exoplayer2/source/ClippingMediaSourceTest.java @@ -21,10 +21,9 @@ import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline.Period; import com.google.android.exoplayer2.Timeline.Window; -import com.google.android.exoplayer2.TimelineTest; -import com.google.android.exoplayer2.TimelineTest.FakeTimeline; -import com.google.android.exoplayer2.TimelineTest.StubMediaSource; -import com.google.android.exoplayer2.TimelineTest.TimelineVerifier; +import com.google.android.exoplayer2.testutil.TimelineAsserts; +import com.google.android.exoplayer2.testutil.TimelineAsserts.FakeTimeline; +import com.google.android.exoplayer2.testutil.TimelineAsserts.StubMediaSource; /** * Unit tests for {@link ClippingMediaSource}. @@ -105,15 +104,16 @@ public final class ClippingMediaSourceTest extends InstrumentationTestCase { Timeline timeline = new FakeTimeline(1, 111); Timeline clippedTimeline = getClippedTimeline(timeline, TEST_CLIP_AMOUNT_US, TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US); - new TimelineVerifier(clippedTimeline) - .assertWindowIds(111) - .assertPeriodCounts(1) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_OFF, C.INDEX_UNSET) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_ONE, 0) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_ALL, 0) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_OFF, C.INDEX_UNSET) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_ONE, 0) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_ALL, 0); + TimelineAsserts.assertWindowIds(clippedTimeline, 111); + TimelineAsserts.assertPeriodCounts(clippedTimeline, 1); + TimelineAsserts.assertPreviousWindowIndices(clippedTimeline, ExoPlayer.REPEAT_MODE_OFF, + C.INDEX_UNSET); + TimelineAsserts.assertPreviousWindowIndices(clippedTimeline, ExoPlayer.REPEAT_MODE_ONE, 0); + TimelineAsserts.assertPreviousWindowIndices(clippedTimeline, ExoPlayer.REPEAT_MODE_ALL, 0); + TimelineAsserts.assertNextWindowIndices(clippedTimeline, ExoPlayer.REPEAT_MODE_OFF, + C.INDEX_UNSET); + TimelineAsserts.assertNextWindowIndices(clippedTimeline, ExoPlayer.REPEAT_MODE_ONE, 0); + TimelineAsserts.assertNextWindowIndices(clippedTimeline, ExoPlayer.REPEAT_MODE_ALL, 0); } /** @@ -121,7 +121,7 @@ public final class ClippingMediaSourceTest extends InstrumentationTestCase { */ private static Timeline getClippedTimeline(Timeline timeline, long startMs, long endMs) { MediaSource mediaSource = new StubMediaSource(timeline); - return TimelineTest.extractTimelineFromMediaSource( + return TimelineAsserts.extractTimelineFromMediaSource( new ClippingMediaSource(mediaSource, startMs, endMs)); } diff --git a/library/core/src/androidTest/java/com/google/android/exoplayer2/source/ConcatenatingMediaSourceTest.java b/library/core/src/androidTest/java/com/google/android/exoplayer2/source/ConcatenatingMediaSourceTest.java index a8a80517f2..c236679d88 100644 --- a/library/core/src/androidTest/java/com/google/android/exoplayer2/source/ConcatenatingMediaSourceTest.java +++ b/library/core/src/androidTest/java/com/google/android/exoplayer2/source/ConcatenatingMediaSourceTest.java @@ -18,10 +18,9 @@ package com.google.android.exoplayer2.source; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.Timeline; -import com.google.android.exoplayer2.TimelineTest; -import com.google.android.exoplayer2.TimelineTest.FakeTimeline; -import com.google.android.exoplayer2.TimelineTest.StubMediaSource; -import com.google.android.exoplayer2.TimelineTest.TimelineVerifier; +import com.google.android.exoplayer2.testutil.TimelineAsserts; +import com.google.android.exoplayer2.testutil.TimelineAsserts.FakeTimeline; +import com.google.android.exoplayer2.testutil.TimelineAsserts.StubMediaSource; import junit.framework.TestCase; /** @@ -31,67 +30,68 @@ public final class ConcatenatingMediaSourceTest extends TestCase { public void testSingleMediaSource() { Timeline timeline = getConcatenatedTimeline(false, new FakeTimeline(3, 111)); - new TimelineVerifier(timeline) - .assertWindowIds(111) - .assertPeriodCounts(3) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_OFF, C.INDEX_UNSET) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_ONE, 0) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_ALL, 0) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_OFF, C.INDEX_UNSET) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_ONE, 0) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_ALL, 0); + TimelineAsserts.assertWindowIds(timeline, 111); + TimelineAsserts.assertPeriodCounts(timeline, 3); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_OFF, C.INDEX_UNSET); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ONE, 0); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ALL, 0); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_OFF, C.INDEX_UNSET); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ONE, 0); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ALL, 0); timeline = getConcatenatedTimeline(true, new FakeTimeline(3, 111)); - new TimelineVerifier(timeline) - .assertWindowIds(111) - .assertPeriodCounts(3) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_OFF, C.INDEX_UNSET) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_ONE, 0) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_ALL, 0) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_OFF, C.INDEX_UNSET) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_ONE, 0) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_ALL, 0); + TimelineAsserts.assertWindowIds(timeline, 111); + TimelineAsserts.assertPeriodCounts(timeline, 3); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_OFF, C.INDEX_UNSET); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ONE, 0); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ALL, 0); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_OFF, C.INDEX_UNSET); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ONE, 0); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ALL, 0); } public void testMultipleMediaSources() { Timeline[] timelines = { new FakeTimeline(3, 111), new FakeTimeline(1, 222), new FakeTimeline(3, 333) }; Timeline timeline = getConcatenatedTimeline(false, timelines); - new TimelineVerifier(timeline) - .assertWindowIds(111, 222, 333) - .assertPeriodCounts(3, 1, 3) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_OFF, C.INDEX_UNSET, 0, 1) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_ONE, 0, 1, 2) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_ALL, 2, 0, 1) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_OFF, 1, 2, C.INDEX_UNSET) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_ONE, 0, 1, 2) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_ALL, 1, 2, 0); + TimelineAsserts.assertWindowIds(timeline, 111, 222, 333); + TimelineAsserts.assertPeriodCounts(timeline, 3, 1, 3); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_OFF, C.INDEX_UNSET, + 0, 1); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ONE, 0, 1, 2); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ALL, 2, 0, 1); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_OFF, + 1, 2, C.INDEX_UNSET); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ONE, 0, 1, 2); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ALL, 1, 2, 0); timeline = getConcatenatedTimeline(true, timelines); - new TimelineVerifier(timeline) - .assertWindowIds(111, 222, 333) - .assertPeriodCounts(3, 1, 3) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_OFF, C.INDEX_UNSET, 0, 1) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_ONE, 2, 0, 1) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_ALL, 2, 0, 1) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_OFF, 1, 2, C.INDEX_UNSET) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_ONE, 1, 2, 0) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_ALL, 1, 2, 0); + TimelineAsserts.assertWindowIds(timeline, 111, 222, 333); + TimelineAsserts.assertPeriodCounts(timeline, 3, 1, 3); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_OFF, + C.INDEX_UNSET, 0, 1); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ONE, 2, 0, 1); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ALL, 2, 0, 1); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_OFF, + 1, 2, C.INDEX_UNSET); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ONE, 1, 2, 0); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ALL, 1, 2, 0); } public void testNestedMediaSources() { Timeline timeline = getConcatenatedTimeline(false, getConcatenatedTimeline(false, new FakeTimeline(1, 111), new FakeTimeline(1, 222)), getConcatenatedTimeline(true, new FakeTimeline(1, 333), new FakeTimeline(1, 444))); - new TimelineVerifier(timeline) - .assertWindowIds(111, 222, 333, 444) - .assertPeriodCounts(1, 1, 1, 1) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_OFF, C.INDEX_UNSET, 0, 1, 2) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_ONE, 0, 1, 3, 2) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_ALL, 3, 0, 1, 2) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_OFF, 1, 2, 3, C.INDEX_UNSET) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_ONE, 0, 1, 3, 2) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_ALL, 1, 2, 3, 0); + TimelineAsserts.assertWindowIds(timeline, 111, 222, 333, 444); + TimelineAsserts.assertPeriodCounts(timeline, 1, 1, 1, 1); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_OFF, + C.INDEX_UNSET, 0, 1, 2); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ONE, 0, 1, 3, 2); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ALL, 3, 0, 1, 2); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_OFF, + 1, 2, 3, C.INDEX_UNSET); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ONE, 0, 1, 3, 2); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ALL, 1, 2, 3, 0); } /** @@ -104,7 +104,7 @@ public final class ConcatenatingMediaSourceTest extends TestCase { for (int i = 0; i < timelines.length; i++) { mediaSources[i] = new StubMediaSource(timelines[i]); } - return TimelineTest.extractTimelineFromMediaSource( + return TimelineAsserts.extractTimelineFromMediaSource( new ConcatenatingMediaSource(isRepeatOneAtomic, mediaSources)); } diff --git a/library/core/src/androidTest/java/com/google/android/exoplayer2/source/DynamicConcatenatingMediaSourceTest.java b/library/core/src/androidTest/java/com/google/android/exoplayer2/source/DynamicConcatenatingMediaSourceTest.java index 0f63201964..a7281d7e21 100644 --- a/library/core/src/androidTest/java/com/google/android/exoplayer2/source/DynamicConcatenatingMediaSourceTest.java +++ b/library/core/src/androidTest/java/com/google/android/exoplayer2/source/DynamicConcatenatingMediaSourceTest.java @@ -19,15 +19,15 @@ import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; +import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.PlaybackParameters; import com.google.android.exoplayer2.Timeline; -import com.google.android.exoplayer2.TimelineTest; -import com.google.android.exoplayer2.TimelineTest.FakeTimeline; -import com.google.android.exoplayer2.TimelineTest.StubMediaSource; -import com.google.android.exoplayer2.TimelineTest.TimelineVerifier; import com.google.android.exoplayer2.source.MediaSource.Listener; +import com.google.android.exoplayer2.testutil.TimelineAsserts; +import com.google.android.exoplayer2.testutil.TimelineAsserts.FakeTimeline; +import com.google.android.exoplayer2.testutil.TimelineAsserts.StubMediaSource; import com.google.android.exoplayer2.trackselection.TrackSelectionArray; import com.google.android.exoplayer2.upstream.Allocator; import java.io.IOException; @@ -46,48 +46,43 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase { public void testPlaylistChangesAfterPreparation() throws InterruptedException { timeline = null; - TimelineTest.StubMediaSource[] childSources = createMediaSources(7); + TimelineAsserts.StubMediaSource[] childSources = createMediaSources(7); DynamicConcatenatingMediaSource mediaSource = new DynamicConcatenatingMediaSource(); prepareAndListenToTimelineUpdates(mediaSource); waitForTimelineUpdate(); - new TimelineVerifier(timeline).assertEmpty(); + TimelineAsserts.assertEmpty(timeline); // Add first source. mediaSource.addMediaSource(childSources[0]); waitForTimelineUpdate(); assertNotNull(timeline); - new TimelineVerifier(timeline) - .assertPeriodCounts(1) - .assertWindowIds(111); + TimelineAsserts.assertPeriodCounts(timeline, 1); + TimelineAsserts.assertWindowIds(timeline, 111); // Add at front of queue. mediaSource.addMediaSource(0, childSources[1]); waitForTimelineUpdate(); - new TimelineVerifier(timeline) - .assertPeriodCounts(2, 1) - .assertWindowIds(222, 111); + TimelineAsserts.assertPeriodCounts(timeline, 2, 1); + TimelineAsserts.assertWindowIds(timeline, 222, 111); // Add at back of queue. mediaSource.addMediaSource(childSources[2]); waitForTimelineUpdate(); - new TimelineVerifier(timeline) - .assertPeriodCounts(2, 1, 3) - .assertWindowIds(222, 111, 333); + TimelineAsserts.assertPeriodCounts(timeline, 2, 1, 3); + TimelineAsserts.assertWindowIds(timeline, 222, 111, 333); // Add in the middle. mediaSource.addMediaSource(1, childSources[3]); waitForTimelineUpdate(); - new TimelineVerifier(timeline) - .assertPeriodCounts(2, 4, 1, 3) - .assertWindowIds(222, 444, 111, 333); + TimelineAsserts.assertPeriodCounts(timeline, 2, 4, 1, 3); + TimelineAsserts.assertWindowIds(timeline, 222, 444, 111, 333); // Add bulk. mediaSource.addMediaSources(3, Arrays.asList((MediaSource) childSources[4], (MediaSource) childSources[5], (MediaSource) childSources[6])); waitForTimelineUpdate(); - new TimelineVerifier(timeline) - .assertPeriodCounts(2, 4, 1, 5, 6, 7, 3) - .assertWindowIds(222, 444, 111, 555, 666, 777, 333); + TimelineAsserts.assertPeriodCounts(timeline, 2, 4, 1, 5, 6, 7, 3); + TimelineAsserts.assertWindowIds(timeline, 222, 444, 111, 555, 666, 777, 333); // Remove in the middle. mediaSource.removeMediaSource(3); @@ -98,41 +93,46 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase { waitForTimelineUpdate(); mediaSource.removeMediaSource(1); waitForTimelineUpdate(); - new TimelineVerifier(timeline) - .assertPeriodCounts(2, 1, 3) - .assertWindowIds(222, 111, 333); + TimelineAsserts.assertPeriodCounts(timeline, 2, 1, 3); + TimelineAsserts.assertWindowIds(timeline, 222, 111, 333); for (int i = 3; i <= 6; i++) { childSources[i].assertReleased(); } + // Assert correct next and previous indices behavior after some insertions and removals. + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_OFF, + 1, 2, C.INDEX_UNSET); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ONE, 0, 1, 2); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ALL, 1, 2, 0); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_OFF, + C.INDEX_UNSET, 0, 1); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ONE, 0, 1, 2); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ALL, 2, 0, 1); + // Remove at front of queue. mediaSource.removeMediaSource(0); waitForTimelineUpdate(); - new TimelineVerifier(timeline) - .assertPeriodCounts(1, 3) - .assertWindowIds(111, 333); + TimelineAsserts.assertPeriodCounts(timeline, 1, 3); + TimelineAsserts.assertWindowIds(timeline, 111, 333); childSources[1].assertReleased(); // Remove at back of queue. mediaSource.removeMediaSource(1); waitForTimelineUpdate(); - new TimelineVerifier(timeline) - .assertPeriodCounts(1) - .assertWindowIds(111); + TimelineAsserts.assertPeriodCounts(timeline, 1); + TimelineAsserts.assertWindowIds(timeline, 111); childSources[2].assertReleased(); // Remove last source. mediaSource.removeMediaSource(0); waitForTimelineUpdate(); - new TimelineVerifier(timeline) - .assertPeriodCounts() - .assertWindowIds(); + TimelineAsserts.assertEmpty(timeline); childSources[3].assertReleased(); } public void testPlaylistChangesBeforePreparation() throws InterruptedException { timeline = null; - TimelineTest.StubMediaSource[] childSources = createMediaSources(4); + TimelineAsserts.StubMediaSource[] childSources = createMediaSources(4); DynamicConcatenatingMediaSource mediaSource = new DynamicConcatenatingMediaSource(); mediaSource.addMediaSource(childSources[0]); mediaSource.addMediaSource(childSources[1]); @@ -144,9 +144,8 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase { prepareAndListenToTimelineUpdates(mediaSource); waitForTimelineUpdate(); assertNotNull(timeline); - new TimelineVerifier(timeline) - .assertPeriodCounts(3, 4, 2) - .assertWindowIds(333, 444, 222); + TimelineAsserts.assertPeriodCounts(timeline, 3, 4, 2); + TimelineAsserts.assertWindowIds(timeline, 333, 444, 222); mediaSource.releaseSource(); for (int i = 1; i < 4; i++) { @@ -156,7 +155,7 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase { public void testPlaylistWithLazyMediaSource() throws InterruptedException { timeline = null; - TimelineTest.StubMediaSource[] childSources = createMediaSources(2); + TimelineAsserts.StubMediaSource[] childSources = createMediaSources(2); LazyMediaSource[] lazySources = new LazyMediaSource[4]; for (int i = 0; i < 4; i++) { lazySources[i] = new LazyMediaSource(); @@ -172,17 +171,15 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase { prepareAndListenToTimelineUpdates(mediaSource); waitForTimelineUpdate(); assertNotNull(timeline); - new TimelineVerifier(timeline) - .assertPeriodCounts(1, 1) - .assertWindowIds(111, null) - .assertWindowIsDynamic(false, true); + TimelineAsserts.assertPeriodCounts(timeline, 1, 1); + TimelineAsserts.assertWindowIds(timeline, 111, null); + TimelineAsserts.assertWindowIsDynamic(timeline, false, true); lazySources[1].triggerTimelineUpdate(new FakeTimeline(9, 999)); waitForTimelineUpdate(); - new TimelineVerifier(timeline) - .assertPeriodCounts(1, 9) - .assertWindowIds(111, 999) - .assertWindowIsDynamic(false, false); + TimelineAsserts.assertPeriodCounts(timeline, 1, 9); + TimelineAsserts.assertWindowIds(timeline, 111, 999); + TimelineAsserts.assertWindowIsDynamic(timeline, false, false); //Add lazy sources after preparation mediaSource.addMediaSource(1, lazySources[2]); @@ -193,17 +190,15 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase { waitForTimelineUpdate(); mediaSource.removeMediaSource(2); waitForTimelineUpdate(); - new TimelineVerifier(timeline) - .assertPeriodCounts(1, 1, 2, 9) - .assertWindowIds(null, 111, 222, 999) - .assertWindowIsDynamic(true, false, false, false); + TimelineAsserts.assertPeriodCounts(timeline, 1, 1, 2, 9); + TimelineAsserts.assertWindowIds(timeline, null, 111, 222, 999); + TimelineAsserts.assertWindowIsDynamic(timeline, true, false, false, false); lazySources[3].triggerTimelineUpdate(new FakeTimeline(8, 888)); waitForTimelineUpdate(); - new TimelineVerifier(timeline) - .assertPeriodCounts(8, 1, 2, 9) - .assertWindowIds(888, 111, 222, 999) - .assertWindowIsDynamic(false, false, false, false); + TimelineAsserts.assertPeriodCounts(timeline, 8, 1, 2, 9); + TimelineAsserts.assertWindowIds(timeline, 888, 111, 222, 999); + TimelineAsserts.assertWindowIsDynamic(timeline, false, false, false, false); mediaSource.releaseSource(); childSources[0].assertReleased(); @@ -272,10 +267,10 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase { timelineUpdated = false; } - private TimelineTest.StubMediaSource[] createMediaSources(int count) { - TimelineTest.StubMediaSource[] sources = new TimelineTest.StubMediaSource[count]; + private TimelineAsserts.StubMediaSource[] createMediaSources(int count) { + TimelineAsserts.StubMediaSource[] sources = new TimelineAsserts.StubMediaSource[count]; for (int i = 0; i < count; i++) { - sources[i] = new TimelineTest.StubMediaSource(new FakeTimeline(i + 1, (i + 1) * 111)); + sources[i] = new TimelineAsserts.StubMediaSource(new FakeTimeline(i + 1, (i + 1) * 111)); } return sources; } diff --git a/library/core/src/androidTest/java/com/google/android/exoplayer2/source/LoopingMediaSourceTest.java b/library/core/src/androidTest/java/com/google/android/exoplayer2/source/LoopingMediaSourceTest.java index dcb0c3d3bf..f9f35d20cf 100644 --- a/library/core/src/androidTest/java/com/google/android/exoplayer2/source/LoopingMediaSourceTest.java +++ b/library/core/src/androidTest/java/com/google/android/exoplayer2/source/LoopingMediaSourceTest.java @@ -18,10 +18,9 @@ package com.google.android.exoplayer2.source; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.Timeline; -import com.google.android.exoplayer2.TimelineTest; -import com.google.android.exoplayer2.TimelineTest.FakeTimeline; -import com.google.android.exoplayer2.TimelineTest.StubMediaSource; -import com.google.android.exoplayer2.TimelineTest.TimelineVerifier; +import com.google.android.exoplayer2.testutil.TimelineAsserts; +import com.google.android.exoplayer2.testutil.TimelineAsserts.FakeTimeline; +import com.google.android.exoplayer2.testutil.TimelineAsserts.StubMediaSource; import junit.framework.TestCase; /** @@ -32,7 +31,7 @@ public class LoopingMediaSourceTest extends TestCase { private final Timeline multiWindowTimeline; public LoopingMediaSourceTest() { - multiWindowTimeline = TimelineTest.extractTimelineFromMediaSource( + multiWindowTimeline = TimelineAsserts.extractTimelineFromMediaSource( new ConcatenatingMediaSource( new StubMediaSource(new FakeTimeline(1, 111)), new StubMediaSource(new FakeTimeline(1, 222)), @@ -41,42 +40,46 @@ public class LoopingMediaSourceTest extends TestCase { public void testSingleLoop() { Timeline timeline = getLoopingTimeline(multiWindowTimeline, 1); - new TimelineVerifier(timeline) - .assertWindowIds(111, 222, 333) - .assertPeriodCounts(1, 1, 1) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_OFF, C.INDEX_UNSET, 0, 1) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_ONE, 0, 1, 2) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_ALL, 2, 0, 1) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_OFF, 1, 2, C.INDEX_UNSET) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_ONE, 0, 1, 2) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_ALL, 1, 2, 0); + TimelineAsserts.assertWindowIds(timeline, 111, 222, 333); + TimelineAsserts.assertPeriodCounts(timeline, 1, 1, 1); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_OFF, + C.INDEX_UNSET, 0, 1); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ONE, 0, 1, 2); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ALL, 2, 0, 1); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_OFF, + 1, 2, C.INDEX_UNSET); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ONE, 0, 1, 2); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ALL, 1, 2, 0); } public void testMultiLoop() { Timeline timeline = getLoopingTimeline(multiWindowTimeline, 3); - new TimelineVerifier(timeline) - .assertWindowIds(111, 222, 333, 111, 222, 333, 111, 222, 333) - .assertPeriodCounts(1, 1, 1, 1, 1, 1, 1, 1, 1) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_OFF, - C.INDEX_UNSET, 0, 1, 2, 3, 4, 5, 6, 7, 8) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_ONE, 0, 1, 2, 3, 4, 5, 6, 7, 8) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_ALL, 8, 0, 1, 2, 3, 4, 5, 6, 7) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_OFF, 1, 2, 3, 4, 5, 6, 7, 8, C.INDEX_UNSET) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_ONE, 0, 1, 2, 3, 4, 5, 6, 7, 8) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_ALL, 1, 2, 3, 4, 5, 6, 7, 8, 0); + TimelineAsserts.assertWindowIds(timeline, 111, 222, 333, 111, 222, 333, 111, 222, 333); + TimelineAsserts.assertPeriodCounts(timeline, 1, 1, 1, 1, 1, 1, 1, 1, 1); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_OFF, + C.INDEX_UNSET, 0, 1, 2, 3, 4, 5, 6, 7, 8); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ONE, + 0, 1, 2, 3, 4, 5, 6, 7, 8); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ALL, + 8, 0, 1, 2, 3, 4, 5, 6, 7); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_OFF, + 1, 2, 3, 4, 5, 6, 7, 8, C.INDEX_UNSET); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ONE, + 0, 1, 2, 3, 4, 5, 6, 7, 8); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ALL, + 1, 2, 3, 4, 5, 6, 7, 8, 0); } public void testInfiniteLoop() { Timeline timeline = getLoopingTimeline(multiWindowTimeline, Integer.MAX_VALUE); - new TimelineVerifier(timeline) - .assertWindowIds(111, 222, 333) - .assertPeriodCounts(1, 1, 1) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_OFF, 2, 0, 1) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_ONE, 0, 1, 2) - .assertPreviousWindowIndices(ExoPlayer.REPEAT_MODE_ALL, 2, 0, 1) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_OFF, 1, 2, 0) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_ONE, 0, 1, 2) - .assertNextWindowIndices(ExoPlayer.REPEAT_MODE_ALL, 1, 2, 0); + TimelineAsserts.assertWindowIds(timeline, 111, 222, 333); + TimelineAsserts.assertPeriodCounts(timeline, 1, 1, 1); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_OFF, 2, 0, 1); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ONE, 0, 1, 2); + TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ALL, 2, 0, 1); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_OFF, 1, 2, 0); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ONE, 0, 1, 2); + TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ALL, 1, 2, 0); } /** @@ -85,7 +88,7 @@ public class LoopingMediaSourceTest extends TestCase { */ private static Timeline getLoopingTimeline(Timeline timeline, int loopCount) { MediaSource mediaSource = new StubMediaSource(timeline); - return TimelineTest.extractTimelineFromMediaSource( + return TimelineAsserts.extractTimelineFromMediaSource( new LoopingMediaSource(mediaSource, loopCount)); } diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/TimelineAsserts.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/TimelineAsserts.java new file mode 100644 index 0000000000..7e7cf58cf3 --- /dev/null +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/TimelineAsserts.java @@ -0,0 +1,261 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.android.exoplayer2.testutil; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertTrue; + +import com.google.android.exoplayer2.C; +import com.google.android.exoplayer2.ExoPlayer; +import com.google.android.exoplayer2.Timeline; +import com.google.android.exoplayer2.Timeline.Period; +import com.google.android.exoplayer2.Timeline.Window; +import com.google.android.exoplayer2.source.MediaPeriod; +import com.google.android.exoplayer2.source.MediaSource; +import com.google.android.exoplayer2.source.MediaSource.Listener; +import com.google.android.exoplayer2.upstream.Allocator; +import java.io.IOException; + +/** + * Unit test for {@link Timeline}. + */ +public final class TimelineAsserts { + + private TimelineAsserts() {} + + /** + * Fake timeline with multiple periods and user-defined window id. + */ + public static final class FakeTimeline extends Timeline { + + private static final int WINDOW_DURATION_US = 1000000; + + private final int periodCount; + private final int id; + + public FakeTimeline(int periodCount, int id) { + this.periodCount = periodCount; + this.id = id; + } + + @Override + public int getWindowCount() { + return 1; + } + + @Override + public Window getWindow(int windowIndex, Window window, boolean setIds, + long defaultPositionProjectionUs) { + return window.set(id, 0, 0, true, false, 0, WINDOW_DURATION_US, 0, periodCount - 1, 0); + } + + @Override + public int getPeriodCount() { + return periodCount; + } + + @Override + public Period getPeriod(int periodIndex, Period period, boolean setIds) { + return period.set(periodIndex, null, 0, WINDOW_DURATION_US, 0); + } + + @Override + public int getIndexOfPeriod(Object uid) { + return C.INDEX_UNSET; + } + } + + /** + * Stub media source which returns a provided timeline as source info and keeps track if it is + * prepared and released. + */ + public static class StubMediaSource implements MediaSource { + private final Timeline timeline; + + private boolean isPrepared; + private volatile boolean isReleased; + + public StubMediaSource(Timeline timeline) { + this.timeline = timeline; + } + + @Override + public void prepareSource(ExoPlayer player, boolean isTopLevelSource, Listener listener) { + assertFalse(isPrepared); + listener.onSourceInfoRefreshed(timeline, null); + isPrepared = true; + } + + @Override + public void maybeThrowSourceInfoRefreshError() throws IOException { + } + + @Override + public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator) { + return null; + } + + @Override + public void releasePeriod(MediaPeriod mediaPeriod) { + } + + @Override + public void releaseSource() { + assertTrue(isPrepared); + isReleased = true; + } + + public void assertReleased() { + assertTrue(isReleased); + } + } + + /** + * Extracts the timeline from a media source. + */ + public static Timeline extractTimelineFromMediaSource(MediaSource mediaSource) { + class TimelineListener implements Listener { + private Timeline timeline; + @Override + public void onSourceInfoRefreshed(Timeline timeline, Object manifest) { + this.timeline = timeline; + } + } + TimelineListener listener = new TimelineListener(); + mediaSource.prepareSource(null, true, listener); + return listener.timeline; + } + + /** + * Assert that timeline is empty (i.e. has no windows or periods). + */ + public static void assertEmpty(Timeline timeline) { + assertWindowIds(timeline); + assertPeriodCounts(timeline); + } + + /** + * Asserts that window IDs are set correctly. + * + * @param expectedWindowIds A list of expected window IDs. If an ID is unknown or not important + * {@code null} can be passed to skip this window. + */ + public static void assertWindowIds(Timeline timeline, Object... expectedWindowIds) { + Window window = new Window(); + assertEquals(expectedWindowIds.length, timeline.getWindowCount()); + for (int i = 0; i < timeline.getWindowCount(); i++) { + timeline.getWindow(i, window, true); + if (expectedWindowIds[i] != null) { + assertEquals(expectedWindowIds[i], window.id); + } + } + } + + /** + * Asserts that window properties {@link Window}.isDynamic are set correctly.. + */ + public static void assertWindowIsDynamic(Timeline timeline, boolean... windowIsDynamic) { + Window window = new Window(); + for (int i = 0; i < timeline.getWindowCount(); i++) { + timeline.getWindow(i, window, true); + assertEquals(windowIsDynamic[i], window.isDynamic); + } + } + + /** + * Asserts that previous window indices for each window are set correctly depending on the repeat + * mode. + */ + public static void assertPreviousWindowIndices(Timeline timeline, + @ExoPlayer.RepeatMode int repeatMode, int... expectedPreviousWindowIndices) { + for (int i = 0; i < timeline.getWindowCount(); i++) { + assertEquals(expectedPreviousWindowIndices[i], + timeline.getPreviousWindowIndex(i, repeatMode)); + } + } + + /** + * Asserts that next window indices for each window are set correctly depending on the repeat + * mode. + */ + public static void assertNextWindowIndices(Timeline timeline, + @ExoPlayer.RepeatMode int repeatMode, int... expectedNextWindowIndices) { + for (int i = 0; i < timeline.getWindowCount(); i++) { + assertEquals(expectedNextWindowIndices[i], + timeline.getNextWindowIndex(i, repeatMode)); + } + } + + /** + * Asserts that period counts for each window are set correctly. Also asserts the correct setting + * of {@link Window}.firstPeriodIndex, {@link Window}.lastPeriodIndex, and the behavior of + * {@link Timeline}.getNextPeriodIndex. + */ + public static void assertPeriodCounts(Timeline timeline, int... expectedPeriodCounts) { + int windowCount = timeline.getWindowCount(); + int[] accumulatedPeriodCounts = new int[windowCount + 1]; + accumulatedPeriodCounts[0] = 0; + for (int i = 0; i < windowCount; i++) { + accumulatedPeriodCounts[i + 1] = accumulatedPeriodCounts[i] + expectedPeriodCounts[i]; + } + assertEquals(accumulatedPeriodCounts[accumulatedPeriodCounts.length - 1], + timeline.getPeriodCount()); + Window window = new Window(); + Period period = new Period(); + for (int i = 0; i < windowCount; i++) { + timeline.getWindow(i, window, true); + assertEquals(accumulatedPeriodCounts[i], window.firstPeriodIndex); + assertEquals(accumulatedPeriodCounts[i + 1] - 1, window.lastPeriodIndex); + } + int expectedWindowIndex = 0; + for (int i = 0; i < timeline.getPeriodCount(); i++) { + timeline.getPeriod(i, period, true); + while (i >= accumulatedPeriodCounts[expectedWindowIndex + 1]) { + expectedWindowIndex++; + } + assertEquals(expectedWindowIndex, period.windowIndex); + if (i < accumulatedPeriodCounts[expectedWindowIndex + 1] - 1) { + assertEquals(i + 1, timeline.getNextPeriodIndex(i, period, window, + ExoPlayer.REPEAT_MODE_OFF)); + assertEquals(i + 1, timeline.getNextPeriodIndex(i, period, window, + ExoPlayer.REPEAT_MODE_ONE)); + assertEquals(i + 1, timeline.getNextPeriodIndex(i, period, window, + ExoPlayer.REPEAT_MODE_ALL)); + } else { + int nextWindowOff = timeline.getNextWindowIndex(expectedWindowIndex, + ExoPlayer.REPEAT_MODE_OFF); + int nextWindowOne = timeline.getNextWindowIndex(expectedWindowIndex, + ExoPlayer.REPEAT_MODE_ONE); + int nextWindowAll = timeline.getNextWindowIndex(expectedWindowIndex, + ExoPlayer.REPEAT_MODE_ALL); + int nextPeriodOff = nextWindowOff == C.INDEX_UNSET ? C.INDEX_UNSET + : accumulatedPeriodCounts[nextWindowOff]; + int nextPeriodOne = nextWindowOne == C.INDEX_UNSET ? C.INDEX_UNSET + : accumulatedPeriodCounts[nextWindowOne]; + int nextPeriodAll = nextWindowAll == C.INDEX_UNSET ? C.INDEX_UNSET + : accumulatedPeriodCounts[nextWindowAll]; + assertEquals(nextPeriodOff, timeline.getNextPeriodIndex(i, period, window, + ExoPlayer.REPEAT_MODE_OFF)); + assertEquals(nextPeriodOne, timeline.getNextPeriodIndex(i, period, window, + ExoPlayer.REPEAT_MODE_ONE)); + assertEquals(nextPeriodAll, timeline.getNextPeriodIndex(i, period, window, + ExoPlayer.REPEAT_MODE_ALL)); + } + } + } + +}