diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 09597ece58..176d11da3e 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -98,6 +98,8 @@ * MP4: Store the Android capture frame rate only in `Format.metadata`. `Format.frameRate` now stores the calculated frame rate. * Testing + * Add `TestExoPlayer`, a utility class with APIs to create + `SimpleExoPlayer` instances with fake components for testing. * Upgrade Truth dependency from 0.44 to 1.0. * Upgrade to JUnit 4.13-rc-2. * UI diff --git a/library/common/src/main/java/com/google/android/exoplayer2/util/Supplier.java b/library/common/src/main/java/com/google/android/exoplayer2/util/Supplier.java new file mode 100644 index 0000000000..723047b1ed --- /dev/null +++ b/library/common/src/main/java/com/google/android/exoplayer2/util/Supplier.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2020 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.util; + +/** + * A functional interface representing a supplier of results. + * + * @param The type of results supplied by this supplier. + */ +public interface Supplier { + + /** Gets a result. */ + T get(); +} diff --git a/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java b/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java index c2d61dd800..b4101dca64 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java @@ -53,7 +53,6 @@ import com.google.android.exoplayer2.testutil.ActionSchedule.PlayerRunnable; import com.google.android.exoplayer2.testutil.ActionSchedule.PlayerTarget; import com.google.android.exoplayer2.testutil.AutoAdvancingFakeClock; import com.google.android.exoplayer2.testutil.ExoPlayerTestRunner; -import com.google.android.exoplayer2.testutil.ExoPlayerTestRunner.Builder; import com.google.android.exoplayer2.testutil.FakeAdaptiveDataSet; import com.google.android.exoplayer2.testutil.FakeAdaptiveMediaSource; import com.google.android.exoplayer2.testutil.FakeChunkSource; @@ -127,10 +126,10 @@ public final class ExoPlayerTest { Timeline expectedMaskingTimeline = new MaskingMediaSource.DummyTimeline(/* tag= */ null); FakeRenderer renderer = new FakeRenderer(C.TRACK_TYPE_UNKNOWN); ExoPlayerTestRunner testRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setRenderers(renderer) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); testRunner.assertNoPositionDiscontinuities(); @@ -150,11 +149,11 @@ public final class ExoPlayerTest { Timeline timeline = new FakeTimeline(/* windowCount= */ 1, manifest); FakeRenderer renderer = new FakeRenderer(C.TRACK_TYPE_VIDEO); ExoPlayerTestRunner testRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setManifest(manifest) .setRenderers(renderer) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); testRunner.assertNoPositionDiscontinuities(); @@ -162,8 +161,9 @@ public final class ExoPlayerTest { testRunner.assertTimelineChangeReasonsEqual( Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED, Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE); - testRunner.assertTrackGroupsEqual(new TrackGroupArray(new TrackGroup(Builder.VIDEO_FORMAT))); - assertThat(renderer.getFormatsRead()).containsExactly(Builder.VIDEO_FORMAT); + testRunner.assertTrackGroupsEqual( + new TrackGroupArray(new TrackGroup(ExoPlayerTestRunner.VIDEO_FORMAT))); + assertThat(renderer.getFormatsRead()).containsExactly(ExoPlayerTestRunner.VIDEO_FORMAT); assertThat(renderer.sampleBufferReadCount).isEqualTo(1); assertThat(renderer.isEnded).isTrue(); } @@ -174,10 +174,10 @@ public final class ExoPlayerTest { Timeline timeline = new FakeTimeline(/* windowCount= */ 3); FakeRenderer renderer = new FakeRenderer(C.TRACK_TYPE_VIDEO); ExoPlayerTestRunner testRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setRenderers(renderer) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); testRunner.assertPositionDiscontinuityReasonsEqual( @@ -188,7 +188,10 @@ public final class ExoPlayerTest { Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED, Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE); assertThat(renderer.getFormatsRead()) - .containsExactly(Builder.VIDEO_FORMAT, Builder.VIDEO_FORMAT, Builder.VIDEO_FORMAT); + .containsExactly( + ExoPlayerTestRunner.VIDEO_FORMAT, + ExoPlayerTestRunner.VIDEO_FORMAT, + ExoPlayerTestRunner.VIDEO_FORMAT); assertThat(renderer.sampleBufferReadCount).isEqualTo(3); assertThat(renderer.isEnded).isTrue(); } @@ -201,10 +204,10 @@ public final class ExoPlayerTest { new FakeTimeline(new TimelineWindowDefinition(/* periodCount= */ 100, /* id= */ 0)); FakeRenderer renderer = new FakeRenderer(C.TRACK_TYPE_VIDEO); ExoPlayerTestRunner testRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setRenderers(renderer) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); Integer[] expectedReasons = new Integer[99]; @@ -275,11 +278,11 @@ public final class ExoPlayerTest { } }; ExoPlayerTestRunner testRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setRenderers(videoRenderer, audioRenderer) - .setSupportedFormats(Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT) - .build(context) + .setSupportedFormats(ExoPlayerTestRunner.VIDEO_FORMAT, ExoPlayerTestRunner.AUDIO_FORMAT) + .build() .start() .blockUntilEnded(TIMEOUT_MS); testRunner.assertPositionDiscontinuityReasonsEqual( @@ -301,13 +304,13 @@ public final class ExoPlayerTest { new FakeTimeline( new TimelineWindowDefinition( /* isSeekable= */ true, /* isDynamic= */ false, 1000_000_000)); - MediaSource firstSource = new FakeMediaSource(firstTimeline, Builder.VIDEO_FORMAT); + MediaSource firstSource = new FakeMediaSource(firstTimeline, ExoPlayerTestRunner.VIDEO_FORMAT); final CountDownLatch queuedSourceInfoCountDownLatch = new CountDownLatch(1); final CountDownLatch completePreparationCountDownLatch = new CountDownLatch(1); Timeline secondTimeline = new FakeTimeline(/* windowCount= */ 1); MediaSource secondSource = - new FakeMediaSource(secondTimeline, Builder.VIDEO_FORMAT) { + new FakeMediaSource(secondTimeline, ExoPlayerTestRunner.VIDEO_FORMAT) { @Override public synchronized void prepareSourceInternal( @Nullable TransferListener mediaTransferListener) { @@ -325,7 +328,7 @@ public final class ExoPlayerTest { }; Object thirdSourceManifest = new Object(); Timeline thirdTimeline = new FakeTimeline(/* windowCount= */ 1, thirdSourceManifest); - MediaSource thirdSource = new FakeMediaSource(thirdTimeline, Builder.VIDEO_FORMAT); + MediaSource thirdSource = new FakeMediaSource(thirdTimeline, ExoPlayerTestRunner.VIDEO_FORMAT); // Prepare the player with a source with the first manifest and a non-empty timeline. Prepare // the player again with a source and a new manifest, which will never be exposed. Allow the @@ -348,11 +351,11 @@ public final class ExoPlayerTest { .executeRunnable(completePreparationCountDownLatch::countDown) .build(); ExoPlayerTestRunner testRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(firstSource) .setRenderers(renderer) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -369,7 +372,8 @@ public final class ExoPlayerTest { Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED, Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED, Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE); - testRunner.assertTrackGroupsEqual(new TrackGroupArray(new TrackGroup(Builder.VIDEO_FORMAT))); + testRunner.assertTrackGroupsEqual( + new TrackGroupArray(new TrackGroup(ExoPlayerTestRunner.VIDEO_FORMAT))); assertThat(renderer.isEnded).isTrue(); } @@ -398,11 +402,11 @@ public final class ExoPlayerTest { .play() .build(); ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setRenderers(renderer) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); testRunner.assertPlayedPeriodIndices(0, 1, 1, 2, 2, 0, 0, 0, 1, 2); @@ -427,9 +431,9 @@ public final class ExoPlayerTest { public void shuffleModeEnabledChanges() throws Exception { Timeline fakeTimeline = new FakeTimeline(/* windowCount= */ 1); MediaSource[] fakeMediaSources = { - new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT), - new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT), - new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT) + new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT), + new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT), + new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT) }; ConcatenatingMediaSource mediaSource = new ConcatenatingMediaSource(false, new FakeShuffleOrder(3), fakeMediaSources); @@ -447,11 +451,11 @@ public final class ExoPlayerTest { .play() .build(); ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(mediaSource) .setRenderers(renderer) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); testRunner.assertPlayedPeriodIndices(0, 1, 0, 2, 1, 2); @@ -490,7 +494,8 @@ public final class ExoPlayerTest { /* isDynamic= */ false, /* durationUs= */ C.MICROS_PER_SECOND, errorAdPlaybackState)); - final FakeMediaSource fakeMediaSource = new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT); + final FakeMediaSource fakeMediaSource = + new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT); ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) .pause() @@ -501,10 +506,10 @@ public final class ExoPlayerTest { .play() .build(); ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(fakeMediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); // There is still one discontinuity from content to content for the failed ad insertion. @@ -522,10 +527,10 @@ public final class ExoPlayerTest { .waitForPositionDiscontinuity() .setRepeatMode(Player.REPEAT_MODE_OFF) // Turn off repeat so that playback can finish. .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setRenderers(renderer) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); assertThat(renderer.isEnded).isTrue(); @@ -550,9 +555,9 @@ public final class ExoPlayerTest { }) .waitForPlaybackState(Player.STATE_ENDED) .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -564,10 +569,10 @@ public final class ExoPlayerTest { FakeTimeline timeline = new FakeTimeline(1); ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG).seek(10).build(); ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); testRunner.assertPositionDiscontinuityReasonsEqual(Player.DISCONTINUITY_REASON_SEEK); @@ -577,7 +582,7 @@ public final class ExoPlayerTest { public void seekDiscontinuityWithAdjustment() throws Exception { FakeTimeline timeline = new FakeTimeline(1); FakeMediaSource mediaSource = - new FakeMediaSource(timeline, Builder.VIDEO_FORMAT) { + new FakeMediaSource(timeline, ExoPlayerTestRunner.VIDEO_FORMAT) { @Override protected FakeMediaPeriod createFakeMediaPeriod( MediaPeriodId id, @@ -598,10 +603,10 @@ public final class ExoPlayerTest { .play() .build(); ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(mediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); testRunner.assertPositionDiscontinuityReasonsEqual( @@ -612,7 +617,7 @@ public final class ExoPlayerTest { public void internalDiscontinuityAtNewPosition() throws Exception { FakeTimeline timeline = new FakeTimeline(1); FakeMediaSource mediaSource = - new FakeMediaSource(timeline, Builder.VIDEO_FORMAT) { + new FakeMediaSource(timeline, ExoPlayerTestRunner.VIDEO_FORMAT) { @Override protected FakeMediaPeriod createFakeMediaPeriod( MediaPeriodId id, @@ -626,9 +631,9 @@ public final class ExoPlayerTest { } }; ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(mediaSource) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); testRunner.assertPositionDiscontinuityReasonsEqual(Player.DISCONTINUITY_REASON_INTERNAL); @@ -638,7 +643,7 @@ public final class ExoPlayerTest { public void internalDiscontinuityAtInitialPosition() throws Exception { FakeTimeline timeline = new FakeTimeline(1); FakeMediaSource mediaSource = - new FakeMediaSource(timeline, Builder.VIDEO_FORMAT) { + new FakeMediaSource(timeline, ExoPlayerTestRunner.VIDEO_FORMAT) { @Override protected FakeMediaPeriod createFakeMediaPeriod( MediaPeriodId id, @@ -653,9 +658,9 @@ public final class ExoPlayerTest { } }; ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(mediaSource) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); // If the position is unchanged we do not expect the discontinuity to be reported externally. @@ -666,16 +671,17 @@ public final class ExoPlayerTest { public void allActivatedTrackSelectionAreReleasedForSinglePeriod() throws Exception { Timeline timeline = new FakeTimeline(/* windowCount= */ 1); MediaSource mediaSource = - new FakeMediaSource(timeline, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT); + new FakeMediaSource( + timeline, ExoPlayerTestRunner.VIDEO_FORMAT, ExoPlayerTestRunner.AUDIO_FORMAT); FakeRenderer videoRenderer = new FakeRenderer(C.TRACK_TYPE_VIDEO); FakeRenderer audioRenderer = new FakeRenderer(C.TRACK_TYPE_AUDIO); FakeTrackSelector trackSelector = new FakeTrackSelector(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(mediaSource) .setRenderers(videoRenderer, audioRenderer) .setTrackSelector(trackSelector) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); @@ -695,16 +701,17 @@ public final class ExoPlayerTest { public void allActivatedTrackSelectionAreReleasedForMultiPeriods() throws Exception { Timeline timeline = new FakeTimeline(/* windowCount= */ 2); MediaSource mediaSource = - new FakeMediaSource(timeline, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT); + new FakeMediaSource( + timeline, ExoPlayerTestRunner.VIDEO_FORMAT, ExoPlayerTestRunner.AUDIO_FORMAT); FakeRenderer videoRenderer = new FakeRenderer(C.TRACK_TYPE_VIDEO); FakeRenderer audioRenderer = new FakeRenderer(C.TRACK_TYPE_AUDIO); FakeTrackSelector trackSelector = new FakeTrackSelector(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(mediaSource) .setRenderers(videoRenderer, audioRenderer) .setTrackSelector(trackSelector) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); @@ -724,7 +731,8 @@ public final class ExoPlayerTest { public void allActivatedTrackSelectionAreReleasedWhenTrackSelectionsAreRemade() throws Exception { Timeline timeline = new FakeTimeline(/* windowCount= */ 1); MediaSource mediaSource = - new FakeMediaSource(timeline, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT); + new FakeMediaSource( + timeline, ExoPlayerTestRunner.VIDEO_FORMAT, ExoPlayerTestRunner.AUDIO_FORMAT); FakeRenderer videoRenderer = new FakeRenderer(C.TRACK_TYPE_VIDEO); FakeRenderer audioRenderer = new FakeRenderer(C.TRACK_TYPE_AUDIO); final FakeTrackSelector trackSelector = new FakeTrackSelector(); @@ -736,12 +744,12 @@ public final class ExoPlayerTest { .play() .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(mediaSource) .setRenderers(videoRenderer, audioRenderer) .setTrackSelector(trackSelector) .setActionSchedule(disableTrackAction) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); @@ -762,7 +770,8 @@ public final class ExoPlayerTest { public void allActivatedTrackSelectionAreReleasedWhenTrackSelectionsAreReused() throws Exception { Timeline timeline = new FakeTimeline(/* windowCount= */ 1); MediaSource mediaSource = - new FakeMediaSource(timeline, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT); + new FakeMediaSource( + timeline, ExoPlayerTestRunner.VIDEO_FORMAT, ExoPlayerTestRunner.AUDIO_FORMAT); FakeRenderer videoRenderer = new FakeRenderer(C.TRACK_TYPE_VIDEO); FakeRenderer audioRenderer = new FakeRenderer(C.TRACK_TYPE_AUDIO); final FakeTrackSelector trackSelector = @@ -775,12 +784,12 @@ public final class ExoPlayerTest { .play() .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(mediaSource) .setRenderers(videoRenderer, audioRenderer) .setTrackSelector(trackSelector) .setActionSchedule(disableTrackAction) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); @@ -802,7 +811,8 @@ public final class ExoPlayerTest { public void dynamicTimelineChangeReason() throws Exception { Timeline timeline = new FakeTimeline(new TimelineWindowDefinition(false, false, 100000)); final Timeline timeline2 = new FakeTimeline(new TimelineWindowDefinition(false, false, 20000)); - final FakeMediaSource mediaSource = new FakeMediaSource(timeline, Builder.VIDEO_FORMAT); + final FakeMediaSource mediaSource = + new FakeMediaSource(timeline, ExoPlayerTestRunner.VIDEO_FORMAT); ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) .pause() @@ -814,10 +824,10 @@ public final class ExoPlayerTest { .play() .build(); ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(mediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); testRunner.assertTimelinesSame(dummyTimeline, timeline, timeline2); @@ -837,14 +847,14 @@ public final class ExoPlayerTest { new ConcatenatingMediaSource( /* isAtomic= */ false, new FakeShuffleOrder(/* length= */ 2), - new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT), - new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT)); + new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT), + new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT)); ConcatenatingMediaSource secondMediaSource = new ConcatenatingMediaSource( /* isAtomic= */ false, new FakeShuffleOrder(/* length= */ 2), - new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT), - new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT)); + new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT), + new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT)); ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) // Wait for first preparation and enable shuffling. Plays period 0. @@ -858,10 +868,10 @@ public final class ExoPlayerTest { .waitForPositionDiscontinuity() .build(); ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(firstMediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -875,7 +885,8 @@ public final class ExoPlayerTest { final CountDownLatch createPeriodCalledCountDownLatch = new CountDownLatch(1); final FakeMediaPeriod[] fakeMediaPeriodHolder = new FakeMediaPeriod[1]; MediaSource mediaSource = - new FakeMediaSource(new FakeTimeline(/* windowCount= */ 1), Builder.VIDEO_FORMAT) { + new FakeMediaSource( + new FakeTimeline(/* windowCount= */ 1), ExoPlayerTestRunner.VIDEO_FORMAT) { @Override protected FakeMediaPeriod createFakeMediaPeriod( MediaPeriodId id, @@ -907,10 +918,10 @@ public final class ExoPlayerTest { // Complete preparation of the fake media period. .executeRunnable(() -> fakeMediaPeriodHolder[0].setPreparationComplete()) .build(); - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(mediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); } @@ -921,7 +932,7 @@ public final class ExoPlayerTest { FakeMediaPeriod[] fakeMediaPeriodHolder = new FakeMediaPeriod[1]; Timeline timeline = new FakeTimeline(/* windowCount= */ 1); FakeMediaSource mediaSource = - new FakeMediaSource(/* timeline= */ null, Builder.VIDEO_FORMAT) { + new FakeMediaSource(/* timeline= */ null, ExoPlayerTestRunner.VIDEO_FORMAT) { @Override protected FakeMediaPeriod createFakeMediaPeriod( MediaPeriodId id, @@ -968,11 +979,11 @@ public final class ExoPlayerTest { }) .play() .build(); - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .initialSeek(/* windowIndex= */ 0, /* positionMs= */ 2000) .setMediaSources(mediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); @@ -998,10 +1009,10 @@ public final class ExoPlayerTest { }) .build(); ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -1032,10 +1043,10 @@ public final class ExoPlayerTest { }) .build(); ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -1066,10 +1077,10 @@ public final class ExoPlayerTest { }) .build(); ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -1085,17 +1096,18 @@ public final class ExoPlayerTest { @Test public void stopWithoutResetReleasesMediaSource() throws Exception { Timeline timeline = new FakeTimeline(/* windowCount= */ 1); - final FakeMediaSource mediaSource = new FakeMediaSource(timeline, Builder.VIDEO_FORMAT); + final FakeMediaSource mediaSource = + new FakeMediaSource(timeline, ExoPlayerTestRunner.VIDEO_FORMAT); ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) .waitForPlaybackState(Player.STATE_READY) .stop(/* reset= */ false) .build(); ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS); mediaSource.assertReleased(); @@ -1105,17 +1117,18 @@ public final class ExoPlayerTest { @Test public void stopWithResetReleasesMediaSource() throws Exception { Timeline timeline = new FakeTimeline(/* windowCount= */ 1); - final FakeMediaSource mediaSource = new FakeMediaSource(timeline, Builder.VIDEO_FORMAT); + final FakeMediaSource mediaSource = + new FakeMediaSource(timeline, ExoPlayerTestRunner.VIDEO_FORMAT); ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) .waitForPlaybackState(Player.STATE_READY) .stop(/* reset= */ true) .build(); ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS); mediaSource.assertReleased(); @@ -1126,7 +1139,8 @@ public final class ExoPlayerTest { public void settingNewStartPositionPossibleAfterStopWithReset() throws Exception { Timeline timeline = new FakeTimeline(/* windowCount= */ 1); Timeline secondTimeline = new FakeTimeline(/* windowCount= */ 2); - MediaSource secondSource = new FakeMediaSource(secondTimeline, Builder.VIDEO_FORMAT); + MediaSource secondSource = + new FakeMediaSource(secondTimeline, ExoPlayerTestRunner.VIDEO_FORMAT); AtomicInteger windowIndexAfterStop = new AtomicInteger(); AtomicLong positionAfterStop = new AtomicLong(); ActionSchedule actionSchedule = @@ -1148,11 +1162,11 @@ public final class ExoPlayerTest { .waitForPlaybackState(Player.STATE_READY) .build(); ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) .setExpectedPlayerEndedCount(2) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); testRunner.assertPlaybackStatesEqual( @@ -1213,10 +1227,10 @@ public final class ExoPlayerTest { .play() .build(); ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -1265,10 +1279,10 @@ public final class ExoPlayerTest { .play() .build(); ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -1317,10 +1331,10 @@ public final class ExoPlayerTest { .play() .build(); ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -1345,10 +1359,10 @@ public final class ExoPlayerTest { .waitForPendingPlayerCommands() .build(); ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -1371,10 +1385,10 @@ public final class ExoPlayerTest { .waitForPendingPlayerCommands() .build(); ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -1396,10 +1410,10 @@ public final class ExoPlayerTest { .waitForPlaybackState(Player.STATE_BUFFERING) .build(); ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context); + .build(); try { testRunner.start().blockUntilActionScheduleFinished(TIMEOUT_MS).blockUntilEnded(TIMEOUT_MS); fail(); @@ -1443,10 +1457,10 @@ public final class ExoPlayerTest { .play() .build(); ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context); + .build(); assertThrows( ExoPlaybackException.class, @@ -1487,10 +1501,10 @@ public final class ExoPlayerTest { } }) .build(); - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(mediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -1526,10 +1540,10 @@ public final class ExoPlayerTest { } }) .build(); - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(concatenatingMediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -1581,10 +1595,10 @@ public final class ExoPlayerTest { .play() .build(); ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(firstMediaSource) .setActionSchedule(actionSchedule) - .build(context); + .build(); try { testRunner.start().blockUntilActionScheduleFinished(TIMEOUT_MS).blockUntilEnded(TIMEOUT_MS); fail(); @@ -1645,10 +1659,10 @@ public final class ExoPlayerTest { .play() .build(); ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(firstMediaSource) .setActionSchedule(actionSchedule) - .build(context); + .build(); assertThrows( ExoPlaybackException.class, @@ -1692,11 +1706,11 @@ public final class ExoPlayerTest { } }; ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(mediaSource) .setActionSchedule(actionSchedule) .setAnalyticsListener(listener) - .build(context); + .build(); try { testRunner.start().blockUntilActionScheduleFinished(TIMEOUT_MS).blockUntilEnded(TIMEOUT_MS); fail(); @@ -1724,10 +1738,10 @@ public final class ExoPlayerTest { .waitForPlaybackState(Player.STATE_IDLE) .build(); ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context); + .build(); try { testRunner.start().blockUntilActionScheduleFinished(TIMEOUT_MS).blockUntilEnded(TIMEOUT_MS); fail(); @@ -1753,10 +1767,10 @@ public final class ExoPlayerTest { .sendMessage(target, /* positionMs= */ 50) .play() .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); assertThat(target.positionMs).isAtLeast(50L); @@ -1774,10 +1788,10 @@ public final class ExoPlayerTest { .sendMessage(target, /* positionMs= */ 50) .play() .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); assertThat(target.positionMs).isAtLeast(50L); @@ -1796,10 +1810,10 @@ public final class ExoPlayerTest { .sendMessage(target50, /* positionMs= */ 50) .play() .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); assertThat(target50.positionMs).isAtLeast(50L); @@ -1826,10 +1840,10 @@ public final class ExoPlayerTest { .delay(/* delayMs= */ 2000) .play() .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -1849,10 +1863,10 @@ public final class ExoPlayerTest { .sendMessage(target2, /* positionMs= */ 50) .play() .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); assertThat(target1.positionMs).isAtLeast(50L); @@ -1871,10 +1885,10 @@ public final class ExoPlayerTest { .sendMessage(target, /* positionMs= */ 50) .play() .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); assertThat(target.positionMs).isAtLeast(50L); @@ -1916,10 +1930,10 @@ public final class ExoPlayerTest { /* positionMs= */ C.TIME_END_OF_SOURCE) .waitForMessage(targetEndLastPeriodUnresolved) .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -1951,10 +1965,10 @@ public final class ExoPlayerTest { .sendMessage(target, /* positionMs= */ 50) .seek(/* positionMs= */ 50) .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); assertThat(target.positionMs).isAtLeast(50L); @@ -1972,10 +1986,10 @@ public final class ExoPlayerTest { timeline, /* expectedReason */ Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE) .seek(/* positionMs= */ 50) .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); assertThat(target.positionMs).isAtLeast(50L); @@ -1993,10 +2007,10 @@ public final class ExoPlayerTest { .seek(/* positionMs= */ 51) .play() .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); assertThat(target.positionMs).isEqualTo(C.POSITION_UNSET); @@ -2015,10 +2029,10 @@ public final class ExoPlayerTest { .seek(/* positionMs= */ 51) .play() .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); assertThat(target.positionMs).isEqualTo(C.POSITION_UNSET); @@ -2038,10 +2052,10 @@ public final class ExoPlayerTest { .waitForPositionDiscontinuity() .setRepeatMode(Player.REPEAT_MODE_OFF) .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); assertThat(target.messageCount).isEqualTo(1); @@ -2067,10 +2081,10 @@ public final class ExoPlayerTest { .setRepeatMode(Player.REPEAT_MODE_OFF) .play() .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); assertThat(target.messageCount).isEqualTo(2); @@ -2085,7 +2099,8 @@ public final class ExoPlayerTest { new FakeTimeline( new TimelineWindowDefinition(/* periodCount= */ 1, /* id= */ 1), new TimelineWindowDefinition(/* periodCount= */ 1, /* id= */ 0)); - final FakeMediaSource mediaSource = new FakeMediaSource(timeline, Builder.VIDEO_FORMAT); + final FakeMediaSource mediaSource = + new FakeMediaSource(timeline, ExoPlayerTestRunner.VIDEO_FORMAT); PositionGrabbingMessageTarget target = new PositionGrabbingMessageTarget(); ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) @@ -2098,10 +2113,10 @@ public final class ExoPlayerTest { secondTimeline, /* expectedReason */ Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE) .play() .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(mediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); assertThat(target.positionMs).isAtLeast(50L); @@ -2119,10 +2134,10 @@ public final class ExoPlayerTest { .sendMessage(target, /* windowIndex = */ 2, /* positionMs= */ 50) .play() .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); assertThat(target.windowIndex).isEqualTo(2); @@ -2141,10 +2156,10 @@ public final class ExoPlayerTest { .sendMessage(target, /* windowIndex = */ 2, /* positionMs= */ 50) .play() .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); assertThat(target.windowIndex).isEqualTo(2); @@ -2161,7 +2176,8 @@ public final class ExoPlayerTest { new FakeTimeline( new TimelineWindowDefinition(/* periodCount= */ 1, /* id= */ 1), new TimelineWindowDefinition(/* periodCount= */ 1, /* id= */ 0)); - final FakeMediaSource mediaSource = new FakeMediaSource(timeline, Builder.VIDEO_FORMAT); + final FakeMediaSource mediaSource = + new FakeMediaSource(timeline, ExoPlayerTestRunner.VIDEO_FORMAT); PositionGrabbingMessageTarget target = new PositionGrabbingMessageTarget(); ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) @@ -2175,10 +2191,10 @@ public final class ExoPlayerTest { .seek(/* windowIndex= */ 0, /* positionMs= */ 0) .play() .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(mediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); assertThat(target.positionMs).isAtLeast(50L); @@ -2189,9 +2205,9 @@ public final class ExoPlayerTest { public void sendMessagesNonLinearPeriodOrder() throws Exception { Timeline fakeTimeline = new FakeTimeline(/* windowCount= */ 1); MediaSource[] fakeMediaSources = { - new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT), - new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT), - new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT) + new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT), + new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT), + new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT) }; ConcatenatingMediaSource mediaSource = new ConcatenatingMediaSource(false, new FakeShuffleOrder(3), fakeMediaSources); @@ -2209,10 +2225,10 @@ public final class ExoPlayerTest { .seek(/* windowIndex= */ 2, /* positionMs= */ 0) .play() .build(); - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(mediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); assertThat(target1.windowIndex).isEqualTo(0); @@ -2242,10 +2258,10 @@ public final class ExoPlayerTest { .executeRunnable(() -> message.get().cancel()) .play() .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); assertThat(message.get().isCanceled()).isTrue(); @@ -2280,10 +2296,10 @@ public final class ExoPlayerTest { .executeRunnable(() -> message.get().cancel()) .play() .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); assertThat(message.get().isCanceled()).isTrue(); @@ -2302,10 +2318,10 @@ public final class ExoPlayerTest { } }; ActionSchedule actionSchedule = addSurfaceSwitch(new ActionSchedule.Builder(TAG)).build(); - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setRenderers(videoRenderer) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -2317,10 +2333,10 @@ public final class ExoPlayerTest { ActionSchedule.Builder scheduleBuilder = new ActionSchedule.Builder(TAG).waitForPlaybackState(Player.STATE_ENDED); ActionSchedule waitForEndedAndSwitchSchedule = addSurfaceSwitch(scheduleBuilder).build(); - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(Timeline.EMPTY) .setActionSchedule(waitForEndedAndSwitchSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -2336,7 +2352,8 @@ public final class ExoPlayerTest { new FakeTimeline( new TimelineWindowDefinition(/* periodCount= */ 1, /* id= */ 1), new TimelineWindowDefinition(/* periodCount= */ 1, /* id= */ 3)); - final FakeMediaSource mediaSource = new FakeMediaSource(timeline1, Builder.VIDEO_FORMAT); + final FakeMediaSource mediaSource = + new FakeMediaSource(timeline1, ExoPlayerTestRunner.VIDEO_FORMAT); ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) .pause() @@ -2351,10 +2368,10 @@ public final class ExoPlayerTest { .play() .build(); ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(mediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); testRunner.assertTimelineChangeReasonsEqual( @@ -2402,10 +2419,10 @@ public final class ExoPlayerTest { .play() .build(); ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(mediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); @@ -2472,10 +2489,10 @@ public final class ExoPlayerTest { }) .play() .build(); - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(mediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -2522,9 +2539,9 @@ public final class ExoPlayerTest { } }) .build(); - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); @@ -2582,9 +2599,9 @@ public final class ExoPlayerTest { } }) .build(); - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); @@ -2628,10 +2645,10 @@ public final class ExoPlayerTest { .waitForPlaybackState(Player.STATE_ENDED) .build(); ExoPlayerTestRunner exoPlayerTestRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .setActionSchedule(actionSchedule) .setTimeline(firstTimeline) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -2699,11 +2716,11 @@ public final class ExoPlayerTest { .setRepeatMode(Player.REPEAT_MODE_OFF) .play() .build(); - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setClock(clock) .setMediaSources(mediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); @@ -2723,8 +2740,8 @@ public final class ExoPlayerTest { Timeline timelineSetDuration = new FakeTimeline(/* windowCount= */ 1); MediaSource mediaSource = new ConcatenatingMediaSource( - new FakeMediaSource(timelineUnsetDuration, Builder.VIDEO_FORMAT), - new FakeMediaSource(timelineSetDuration, Builder.AUDIO_FORMAT)); + new FakeMediaSource(timelineUnsetDuration, ExoPlayerTestRunner.VIDEO_FORMAT), + new FakeMediaSource(timelineSetDuration, ExoPlayerTestRunner.AUDIO_FORMAT)); ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) .pause() @@ -2735,9 +2752,9 @@ public final class ExoPlayerTest { .build(); List trackGroupsList = new ArrayList<>(); List trackSelectionsList = new ArrayList<>(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(mediaSource) - .setSupportedFormats(Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT) + .setSupportedFormats(ExoPlayerTestRunner.VIDEO_FORMAT, ExoPlayerTestRunner.AUDIO_FORMAT) .setActionSchedule(actionSchedule) .setEventListener( new EventListener() { @@ -2748,7 +2765,7 @@ public final class ExoPlayerTest { trackSelectionsList.add(trackSelections); } }) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); assertThat(trackGroupsList).hasSize(3); @@ -2756,10 +2773,12 @@ public final class ExoPlayerTest { // Then the seek to an unprepared period will result in empty track groups and selections being // returned. // Then the track groups of the 2nd period are reported. - assertThat(trackGroupsList.get(0).get(0).getFormat(0)).isEqualTo(Builder.VIDEO_FORMAT); + assertThat(trackGroupsList.get(0).get(0).getFormat(0)) + .isEqualTo(ExoPlayerTestRunner.VIDEO_FORMAT); assertThat(trackGroupsList.get(1)).isEqualTo(TrackGroupArray.EMPTY); assertThat(trackSelectionsList.get(1).get(0)).isNull(); - assertThat(trackGroupsList.get(2).get(0).getFormat(0)).isEqualTo(Builder.AUDIO_FORMAT); + assertThat(trackGroupsList.get(2).get(0).getFormat(0)) + .isEqualTo(ExoPlayerTestRunner.AUDIO_FORMAT); } @Test @@ -2771,9 +2790,10 @@ public final class ExoPlayerTest { /* isSeekable= */ true, /* isDynamic= */ false, /* durationUs= */ 10 * C.MICROS_PER_SECOND)); - MediaSource workingMediaSource = new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT); + MediaSource workingMediaSource = + new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT); MediaSource failingMediaSource = - new FakeMediaSource(/* timeline= */ null, Builder.VIDEO_FORMAT) { + new FakeMediaSource(/* timeline= */ null, ExoPlayerTestRunner.VIDEO_FORMAT) { @Override public void maybeThrowSourceInfoRefreshError() throws IOException { throw new IOException(); @@ -2783,10 +2803,10 @@ public final class ExoPlayerTest { new ConcatenatingMediaSource(workingMediaSource, failingMediaSource); FakeRenderer renderer = new FakeRenderer(C.TRACK_TYPE_VIDEO); ExoPlayerTestRunner testRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(concatenatingMediaSource) .setRenderers(renderer) - .build(context); + .build(); try { testRunner.start().blockUntilEnded(TIMEOUT_MS); fail(); @@ -2807,9 +2827,10 @@ public final class ExoPlayerTest { /* isSeekable= */ true, /* isDynamic= */ false, /* durationUs= */ 10 * C.MICROS_PER_SECOND)); - MediaSource workingMediaSource = new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT); + MediaSource workingMediaSource = + new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT); MediaSource failingMediaSource = - new FakeMediaSource(/* timeline= */ null, Builder.VIDEO_FORMAT) { + new FakeMediaSource(/* timeline= */ null, ExoPlayerTestRunner.VIDEO_FORMAT) { @Override public void maybeThrowSourceInfoRefreshError() throws IOException { throw new IOException(); @@ -2826,11 +2847,11 @@ public final class ExoPlayerTest { .build(); FakeRenderer renderer = new FakeRenderer(C.TRACK_TYPE_VIDEO); ExoPlayerTestRunner testRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(concatenatingMediaSource) .setActionSchedule(actionSchedule) .setRenderers(renderer) - .build(context); + .build(); try { testRunner.start().blockUntilEnded(TIMEOUT_MS); fail(); @@ -2860,10 +2881,10 @@ public final class ExoPlayerTest { // Remove the media source. .executeRunnable(concatenatingMediaSource::clear) .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(concatenatingMediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); } @@ -2900,10 +2921,10 @@ public final class ExoPlayerTest { }) .play() .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(concatenatedMediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); @@ -2945,10 +2966,10 @@ public final class ExoPlayerTest { }) .play() .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(concatenatedMediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); @@ -2999,10 +3020,10 @@ public final class ExoPlayerTest { .waitForIsLoading(/* targetIsLoading= */ false) .play() .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); @@ -3048,10 +3069,10 @@ public final class ExoPlayerTest { .waitForPlaybackState(Player.STATE_BUFFERING) .executeRunnable(() -> fakeMediaSource.setNewSourceInfo(fakeTimeline)) .build(); - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(fakeMediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); @@ -3100,10 +3121,10 @@ public final class ExoPlayerTest { .waitForPlaybackState(Player.STATE_BUFFERING) .executeRunnable(() -> fakeMediaSource.setNewSourceInfo(fakeTimeline)) .build(); - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(fakeMediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); @@ -3130,10 +3151,10 @@ public final class ExoPlayerTest { reportedPlaybackSpeeds.add(playbackSpeed); } }; - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setActionSchedule(actionSchedule) .setEventListener(listener) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); @@ -3176,12 +3197,12 @@ public final class ExoPlayerTest { reportedPlaybackParameters.add(playbackSpeed); } }; - new ExoPlayerTestRunner.Builder() - .setSupportedFormats(Builder.AUDIO_FORMAT) + new ExoPlayerTestRunner.Builder(context) + .setSupportedFormats(ExoPlayerTestRunner.AUDIO_FORMAT) .setRenderers(renderer) .setActionSchedule(actionSchedule) .setEventListener(listener) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); @@ -3208,10 +3229,10 @@ public final class ExoPlayerTest { seenPlaybackSuppression.set(true); } }; - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setActionSchedule(actionSchedule) .setEventListener(listener) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); @@ -3240,10 +3261,10 @@ public final class ExoPlayerTest { seenPlaybackSuppression.set(true); } }; - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setActionSchedule(actionSchedule) .setEventListener(listener) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS); @@ -3264,9 +3285,9 @@ public final class ExoPlayerTest { public void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) { super.prepareSourceInternal(mediaTransferListener); underlyingSource.addMediaSource( - new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT)); + new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT)); underlyingSource.addMediaSource( - new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT)); + new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT)); prepareChildSource(null, underlyingSource); } @@ -3318,10 +3339,10 @@ public final class ExoPlayerTest { }) .build(); ExoPlayerTestRunner exoPlayerTestRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(delegatingMediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -3362,10 +3383,10 @@ public final class ExoPlayerTest { } }) .build(); - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(loopingMediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS); @@ -3402,10 +3423,10 @@ public final class ExoPlayerTest { } }) .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(loopingMediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS); @@ -3440,7 +3461,7 @@ public final class ExoPlayerTest { .build(); ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder().setActionSchedule(actionSchedule).build(context).start(); + new ExoPlayerTestRunner.Builder(context).setActionSchedule(actionSchedule).build().start(); becomingNoisyHandlingDisabled.await(); deliverBroadcast(new Intent(AudioManager.ACTION_AUDIO_BECOMING_NOISY)); becomingNoisyDelivered.countDown(); @@ -3467,7 +3488,7 @@ public final class ExoPlayerTest { .build(); ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder().setActionSchedule(actionSchedule).build(context).start(); + new ExoPlayerTestRunner.Builder(context).setActionSchedule(actionSchedule).build().start(); becomingNoisyHandlingEnabled.await(); deliverBroadcast(new Intent(AudioManager.ACTION_AUDIO_BECOMING_NOISY)); @@ -3501,17 +3522,17 @@ public final class ExoPlayerTest { MediaSource chunkedMediaSource = new FakeAdaptiveMediaSource( new FakeTimeline(/* windowCount= */ 1), - new TrackGroupArray(new TrackGroup(Builder.VIDEO_FORMAT)), + new TrackGroupArray(new TrackGroup(ExoPlayerTestRunner.VIDEO_FORMAT)), new FakeChunkSource.Factory(dataSetFactory, new FakeDataSource.Factory())); ExoPlaybackException exception = assertThrows( ExoPlaybackException.class, () -> - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setLoadControl(neverLoadingLoadControl) .setMediaSources(chunkedMediaSource) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS)); assertThat(exception.type).isEqualTo(ExoPlaybackException.TYPE_UNEXPECTED); @@ -3541,13 +3562,13 @@ public final class ExoPlayerTest { MediaSource chunkedMediaSource = new FakeAdaptiveMediaSource( new FakeTimeline(/* windowCount= */ 1), - new TrackGroupArray(new TrackGroup(Builder.VIDEO_FORMAT)), + new TrackGroupArray(new TrackGroup(ExoPlayerTestRunner.VIDEO_FORMAT)), new FakeChunkSource.Factory(dataSetFactory, new FakeDataSource.Factory())); - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setLoadControl(neverLoadingOrPlayingLoadControl) .setMediaSources(chunkedMediaSource) - .build(context) + .build() .start() // This throws if playback doesn't finish within timeout. .blockUntilEnded(TIMEOUT_MS); @@ -3584,10 +3605,10 @@ public final class ExoPlayerTest { .moveMediaItem(/* currentIndex= */ 0, /* newIndex= */ 1) .build(); ExoPlayerTestRunner exoPlayerTestRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(mediaSource1, mediaSource2) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -3638,10 +3659,10 @@ public final class ExoPlayerTest { .removeMediaItem(/* index= */ 0) .build(); ExoPlayerTestRunner exoPlayerTestRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(mediaSource1, mediaSource2, mediaSource3) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -3698,10 +3719,10 @@ public final class ExoPlayerTest { .removeMediaItems(/* fromIndex= */ 1, /* toIndex= */ 3) .build(); ExoPlayerTestRunner exoPlayerTestRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(mediaSource1, mediaSource2, mediaSource3) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -3733,10 +3754,10 @@ public final class ExoPlayerTest { .waitForPlaybackState(Player.STATE_ENDED) .build(); ExoPlayerTestRunner exoPlayerTestRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -3764,10 +3785,10 @@ public final class ExoPlayerTest { .waitForTimelineChanged() .build(); ExoPlayerTestRunner exoPlayerTestRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(mediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -3824,10 +3845,10 @@ public final class ExoPlayerTest { .waitForPlaybackState(Player.STATE_ENDED) .build(); ExoPlayerTestRunner exoPlayerTestRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(firstMediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start(/* doPrepare= */ false) .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -3895,11 +3916,11 @@ public final class ExoPlayerTest { .waitForPlaybackState(Player.STATE_ENDED) .build(); ExoPlayerTestRunner exoPlayerTestRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .setExpectedPlayerEndedCount(/* expectedPlayerEndedCount= */ 2) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -3956,10 +3977,10 @@ public final class ExoPlayerTest { .waitForPlaybackState(Player.STATE_ENDED) .build(); ExoPlayerTestRunner exoPlayerTestRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -4000,11 +4021,11 @@ public final class ExoPlayerTest { .prepare() .build(); ExoPlayerTestRunner exoPlayerTestRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .skipSettingMediaSources() .initialSeek(/* windowIndex= */ 1, C.TIME_UNSET) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -4021,10 +4042,10 @@ public final class ExoPlayerTest { ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG).waitForPlaybackState(Player.STATE_READY).prepare().build(); ExoPlayerTestRunner exoPlayerTestRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .setTimeline(timeline) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -4046,8 +4067,8 @@ public final class ExoPlayerTest { ConcatenatingMediaSource concatenatingMediaSource = new ConcatenatingMediaSource( /* isAtomic= */ false, - new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT), - new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT)); + new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT), + new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT)); int[] currentWindowIndices = new int[1]; long[] currentPlaybackPositions = new long[1]; int seekToWindowIndex = 1; @@ -4064,11 +4085,11 @@ public final class ExoPlayerTest { } }) .build(); - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(concatenatingMediaSource) .initialSeek(seekToWindowIndex, 5000) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -4104,8 +4125,8 @@ public final class ExoPlayerTest { () -> concatenatingMediaSource.addMediaSources( Arrays.asList( - new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT), - new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT)))) + new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT), + new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT)))) .waitForTimelineChanged() .executeRunnable( new PlayerRunnable() { @@ -4117,11 +4138,11 @@ public final class ExoPlayerTest { } }) .build(); - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(concatenatingMediaSource) .initialSeek(seekToWindowIndex, 5000) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -4137,10 +4158,10 @@ public final class ExoPlayerTest { ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG).waitForPlaybackState(Player.STATE_ENDED).build(); ExoPlayerTestRunner exoPlayerTestRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(concatenatingMediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -4175,8 +4196,8 @@ public final class ExoPlayerTest { () -> concatenatingMediaSource.addMediaSources( Arrays.asList( - new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT), - new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT)))) + new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT), + new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT)))) .waitForTimelineChanged() .executeRunnable( new PlayerRunnable() { @@ -4188,12 +4209,12 @@ public final class ExoPlayerTest { } }) .build(); - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(concatenatingMediaSource) .setUseLazyPreparation(/* useLazyPreparation= */ true) .initialSeek(seekToWindowIndex, 5000) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -4224,10 +4245,10 @@ public final class ExoPlayerTest { .waitForTimelineChanged() .stop() .build(); - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(mediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -4250,9 +4271,9 @@ public final class ExoPlayerTest { } }) .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); @@ -4275,9 +4296,9 @@ public final class ExoPlayerTest { }) .play() .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); @@ -4313,10 +4334,10 @@ public final class ExoPlayerTest { } }) .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(new ConcatenatingMediaSource()) .setActionSchedule(actionSchedule) - .build(context) + .build() .start(/* doPrepare= */ false) .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -4356,11 +4377,11 @@ public final class ExoPlayerTest { } }) .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .initialSeek(/* windowIndex= */ 1, C.TIME_UNSET) .setMediaSources(new ConcatenatingMediaSource()) .setActionSchedule(actionSchedule) - .build(context) + .build() .start(/* doPrepare= */ false) .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -4400,11 +4421,11 @@ public final class ExoPlayerTest { } }) .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .initialSeek(/* windowIndex= */ 4, C.TIME_UNSET) .setMediaSources(new ConcatenatingMediaSource()) .setActionSchedule(actionSchedule) - .build(context) + .build() .start(/* doPrepare= */ false) .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -4464,10 +4485,10 @@ public final class ExoPlayerTest { } }) .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(firstMediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -4507,11 +4528,11 @@ public final class ExoPlayerTest { } }) .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .initialSeek(/* windowIndex= */ 1, C.TIME_UNSET) .setMediaSources(firstMediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start(/* doPrepare= */ false) .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -4552,11 +4573,11 @@ public final class ExoPlayerTest { }) .waitForPlaybackState(Player.STATE_ENDED) .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .initialSeek(/* windowIndex= */ 1, C.TIME_UNSET) .setMediaSources(firstMediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start(/* doPrepare= */ false) .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -4592,10 +4613,10 @@ public final class ExoPlayerTest { } }) .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(firstMediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -4652,10 +4673,10 @@ public final class ExoPlayerTest { .prepare() .build(); ExoPlayerTestRunner exoPlayerTestRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .skipSettingMediaSources() .setActionSchedule(actionSchedule) - .build(context) + .build() .start(/* doPrepare= */ false) .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -4694,11 +4715,11 @@ public final class ExoPlayerTest { .waitForPlaybackState(Player.STATE_READY) .build(); ExoPlayerTestRunner exoPlayerTestRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .initialSeek(/* windowIndex= */ 1, /* positionMs= */ C.TIME_UNSET) .setMediaSources(new ConcatenatingMediaSource()) .setActionSchedule(actionSchedule) - .build(context) + .build() .start(/* doPrepare= */ false) .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -4731,10 +4752,10 @@ public final class ExoPlayerTest { .waitForPlaybackState(Player.STATE_READY) .build(); ExoPlayerTestRunner exoPlayerTestRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .skipSettingMediaSources() .setActionSchedule(actionSchedule) - .build(context) + .build() .start(/* doPrepare= */ false) .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -4767,10 +4788,10 @@ public final class ExoPlayerTest { .waitForPlaybackState(Player.STATE_READY) .build(); ExoPlayerTestRunner exoPlayerTestRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .skipSettingMediaSources() .setActionSchedule(actionSchedule) - .build(context) + .build() .start(/* doPrepare= */ false) .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -4838,11 +4859,11 @@ public final class ExoPlayerTest { .waitForPlaybackState(Player.STATE_ENDED) .build(); ExoPlayerTestRunner exoPlayerTestRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .setExpectedPlayerEndedCount(/* expectedPlayerEndedCount= */ 3) .setMediaSources(new ConcatenatingMediaSource()) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -4890,11 +4911,11 @@ public final class ExoPlayerTest { .waitForPlaybackState(Player.STATE_ENDED) .build(); ExoPlayerTestRunner exoPlayerTestRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .initialSeek(/* windowIndex= */ 1, /* positionMs= */ C.TIME_UNSET) .setMediaSources(new ConcatenatingMediaSource()) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -4930,9 +4951,9 @@ public final class ExoPlayerTest { .waitForPlaybackState(Player.STATE_ENDED) .build(); ExoPlayerTestRunner exoPlayerTestRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -4969,9 +4990,9 @@ public final class ExoPlayerTest { .waitForPlaybackState(Player.STATE_ENDED) .build(); ExoPlayerTestRunner exoPlayerTestRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -5052,11 +5073,11 @@ public final class ExoPlayerTest { .waitForPlaybackState(Player.STATE_READY) .build(); ExoPlayerTestRunner exoPlayerTestRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .setExpectedPlayerEndedCount(/* expectedPlayerEndedCount= */ 3) .setMediaSources(firstMediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -5127,12 +5148,12 @@ public final class ExoPlayerTest { .waitForPlaybackState(Player.STATE_ENDED) .build(); ExoPlayerTestRunner exoPlayerTestRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .setExpectedPlayerEndedCount(/* expectedPlayerEndedCount= */ 2) .initialSeek(/* windowIndex= */ 1, /* positionMs= */ C.TIME_UNSET) .setMediaSources(new ConcatenatingMediaSource()) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -5186,11 +5207,11 @@ public final class ExoPlayerTest { } }) .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .skipSettingMediaSources() .initialSeek(/* windowIndex= */ 1, C.TIME_UNSET) .setActionSchedule(actionSchedule) - .build(context) + .build() .start(/* doPrepare= */ false) .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -5228,11 +5249,11 @@ public final class ExoPlayerTest { } }) .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .skipSettingMediaSources() .initialSeek(/* windowIndex= */ 1, C.TIME_UNSET) .setActionSchedule(actionSchedule) - .build(context) + .build() .start(/* doPrepare= */ false) .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -5310,10 +5331,10 @@ public final class ExoPlayerTest { } }) .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(firstMediaSource, secondMediaSource, thirdMediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -5350,10 +5371,10 @@ public final class ExoPlayerTest { } }) .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(firstMediaSource, secondMediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start(/* doPrepare= */ false) .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -5381,11 +5402,11 @@ public final class ExoPlayerTest { } }) .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .initialSeek(/* windowIndex= */ 1, /* positionMs= */ C.TIME_UNSET) .setMediaSources(firstMediaSource, secondMediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -5416,11 +5437,11 @@ public final class ExoPlayerTest { } }) .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .initialSeek(/* windowIndex= */ 1, /* positionMs= */ 5000) .setMediaSources(firstMediaSource, secondMediaSource, firstMediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -5515,12 +5536,12 @@ public final class ExoPlayerTest { }) .build(); ExoPlayerTestRunner exoPlayerTestRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .initialSeek(/* windowIndex= */ 2, /* positionMs= */ C.TIME_UNSET) .setExpectedPlayerEndedCount(2) .setMediaSources(firstMediaSource, secondMediaSource, thirdMediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -5559,10 +5580,10 @@ public final class ExoPlayerTest { .waitForPlaybackState(Player.STATE_ENDED) .build(); ExoPlayerTestRunner exoPlayerTestRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(firstMediaSource, secondMediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start(/* doPrepare= */ false) .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -5592,11 +5613,11 @@ public final class ExoPlayerTest { } }) .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .initialSeek(/* windowIndex= */ 1, /* positionMs= */ C.TIME_UNSET) .setMediaSources(firstMediaSource, secondMediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -5638,11 +5659,11 @@ public final class ExoPlayerTest { } }) .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .initialSeek(/* windowIndex= */ 1, /* positionMs= */ C.TIME_UNSET) .setMediaSources(firstMediaSource, secondMediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start(/* doPrepare= */ false) .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -5656,9 +5677,11 @@ public final class ExoPlayerTest { @Test public void errorThrownDuringRendererEnableAtPeriodTransition_isReportedForNewPeriod() { FakeMediaSource source1 = - new FakeMediaSource(new FakeTimeline(/* windowCount= */ 1), Builder.VIDEO_FORMAT); + new FakeMediaSource( + new FakeTimeline(/* windowCount= */ 1), ExoPlayerTestRunner.VIDEO_FORMAT); FakeMediaSource source2 = - new FakeMediaSource(new FakeTimeline(/* windowCount= */ 1), Builder.AUDIO_FORMAT); + new FakeMediaSource( + new FakeTimeline(/* windowCount= */ 1), ExoPlayerTestRunner.AUDIO_FORMAT); FakeRenderer videoRenderer = new FakeRenderer(C.TRACK_TYPE_VIDEO); FakeRenderer audioRenderer = new FakeRenderer(C.TRACK_TYPE_AUDIO) { @@ -5666,7 +5689,8 @@ public final class ExoPlayerTest { protected void onEnabled(boolean joining, boolean mayRenderStartOfStream) throws ExoPlaybackException { // Fail when enabling the renderer. This will happen during the period transition. - throw createRendererException(new IllegalStateException(), Builder.AUDIO_FORMAT); + throw createRendererException( + new IllegalStateException(), ExoPlayerTestRunner.AUDIO_FORMAT); } }; AtomicReference trackGroupsAfterError = new AtomicReference<>(); @@ -5692,11 +5716,11 @@ public final class ExoPlayerTest { }) .build(); ExoPlayerTestRunner testRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(source1, source2) .setActionSchedule(actionSchedule) .setRenderers(videoRenderer, audioRenderer) - .build(context); + .build(); assertThrows( ExoPlaybackException.class, @@ -5708,7 +5732,8 @@ public final class ExoPlayerTest { assertThat(windowIndexAfterError.get()).isEqualTo(1); assertThat(trackGroupsAfterError.get().length).isEqualTo(1); - assertThat(trackGroupsAfterError.get().get(0).getFormat(0)).isEqualTo(Builder.AUDIO_FORMAT); + assertThat(trackGroupsAfterError.get().get(0).getFormat(0)) + .isEqualTo(ExoPlayerTestRunner.AUDIO_FORMAT); assertThat(trackSelectionsAfterError.get().get(0)).isNull(); // Video renderer. assertThat(trackSelectionsAfterError.get().get(1)).isNotNull(); // Audio renderer. } @@ -5716,15 +5741,18 @@ public final class ExoPlayerTest { @Test public void errorThrownDuringRendererDisableAtPeriodTransition_isReportedForCurrentPeriod() { FakeMediaSource source1 = - new FakeMediaSource(new FakeTimeline(/* windowCount= */ 1), Builder.VIDEO_FORMAT); + new FakeMediaSource( + new FakeTimeline(/* windowCount= */ 1), ExoPlayerTestRunner.VIDEO_FORMAT); FakeMediaSource source2 = - new FakeMediaSource(new FakeTimeline(/* windowCount= */ 1), Builder.AUDIO_FORMAT); + new FakeMediaSource( + new FakeTimeline(/* windowCount= */ 1), ExoPlayerTestRunner.AUDIO_FORMAT); FakeRenderer videoRenderer = new FakeRenderer(C.TRACK_TYPE_VIDEO) { @Override protected void onStopped() throws ExoPlaybackException { // Fail when stopping the renderer. This will happen during the period transition. - throw createRendererException(new IllegalStateException(), Builder.VIDEO_FORMAT); + throw createRendererException( + new IllegalStateException(), ExoPlayerTestRunner.VIDEO_FORMAT); } }; FakeRenderer audioRenderer = new FakeRenderer(C.TRACK_TYPE_AUDIO); @@ -5751,11 +5779,11 @@ public final class ExoPlayerTest { }) .build(); ExoPlayerTestRunner testRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(source1, source2) .setActionSchedule(actionSchedule) .setRenderers(videoRenderer, audioRenderer) - .build(context); + .build(); assertThrows( ExoPlaybackException.class, @@ -5767,7 +5795,8 @@ public final class ExoPlayerTest { assertThat(windowIndexAfterError.get()).isEqualTo(0); assertThat(trackGroupsAfterError.get().length).isEqualTo(1); - assertThat(trackGroupsAfterError.get().get(0).getFormat(0)).isEqualTo(Builder.VIDEO_FORMAT); + assertThat(trackGroupsAfterError.get().get(0).getFormat(0)) + .isEqualTo(ExoPlayerTestRunner.VIDEO_FORMAT); assertThat(trackSelectionsAfterError.get().get(0)).isNotNull(); // Video renderer. assertThat(trackSelectionsAfterError.get().get(1)).isNull(); // Audio renderer. } @@ -5778,9 +5807,12 @@ public final class ExoPlayerTest { public void errorThrownDuringRendererReplaceStreamAtPeriodTransition_isReportedForNewPeriod() { FakeMediaSource source1 = new FakeMediaSource( - new FakeTimeline(/* windowCount= */ 1), Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT); + new FakeTimeline(/* windowCount= */ 1), + ExoPlayerTestRunner.VIDEO_FORMAT, + ExoPlayerTestRunner.AUDIO_FORMAT); FakeMediaSource source2 = - new FakeMediaSource(new FakeTimeline(/* windowCount= */ 1), Builder.AUDIO_FORMAT); + new FakeMediaSource( + new FakeTimeline(/* windowCount= */ 1), ExoPlayerTestRunner.AUDIO_FORMAT); FakeRenderer videoRenderer = new FakeRenderer(C.TRACK_TYPE_VIDEO); FakeRenderer audioRenderer = new FakeRenderer(C.TRACK_TYPE_AUDIO) { @@ -5788,7 +5820,8 @@ public final class ExoPlayerTest { protected void onStreamChanged(Format[] formats, long offsetUs) throws ExoPlaybackException { // Fail when changing streams. This will happen during the period transition. - throw createRendererException(new IllegalStateException(), Builder.AUDIO_FORMAT); + throw createRendererException( + new IllegalStateException(), ExoPlayerTestRunner.AUDIO_FORMAT); } }; AtomicReference trackGroupsAfterError = new AtomicReference<>(); @@ -5814,11 +5847,11 @@ public final class ExoPlayerTest { }) .build(); ExoPlayerTestRunner testRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(source1, source2) .setActionSchedule(actionSchedule) .setRenderers(videoRenderer, audioRenderer) - .build(context); + .build(); assertThrows( ExoPlaybackException.class, @@ -5830,7 +5863,8 @@ public final class ExoPlayerTest { assertThat(windowIndexAfterError.get()).isEqualTo(1); assertThat(trackGroupsAfterError.get().length).isEqualTo(1); - assertThat(trackGroupsAfterError.get().get(0).getFormat(0)).isEqualTo(Builder.AUDIO_FORMAT); + assertThat(trackGroupsAfterError.get().get(0).getFormat(0)) + .isEqualTo(ExoPlayerTestRunner.AUDIO_FORMAT); assertThat(trackSelectionsAfterError.get().get(0)).isNull(); // Video renderer. assertThat(trackSelectionsAfterError.get().get(1)).isNotNull(); // Audio renderer. } @@ -5839,9 +5873,12 @@ public final class ExoPlayerTest { public void errorThrownDuringPlaylistUpdate_keepsConsistentPlayerState() { FakeMediaSource source1 = new FakeMediaSource( - new FakeTimeline(/* windowCount= */ 1), Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT); + new FakeTimeline(/* windowCount= */ 1), + ExoPlayerTestRunner.VIDEO_FORMAT, + ExoPlayerTestRunner.AUDIO_FORMAT); FakeMediaSource source2 = - new FakeMediaSource(new FakeTimeline(/* windowCount= */ 1), Builder.AUDIO_FORMAT); + new FakeMediaSource( + new FakeTimeline(/* windowCount= */ 1), ExoPlayerTestRunner.AUDIO_FORMAT); AtomicInteger audioRendererEnableCount = new AtomicInteger(0); FakeRenderer videoRenderer = new FakeRenderer(C.TRACK_TYPE_VIDEO); FakeRenderer audioRenderer = @@ -5851,7 +5888,8 @@ public final class ExoPlayerTest { throws ExoPlaybackException { if (audioRendererEnableCount.incrementAndGet() == 2) { // Fail when enabling the renderer for the second time during the playlist update. - throw createRendererException(new IllegalStateException(), Builder.AUDIO_FORMAT); + throw createRendererException( + new IllegalStateException(), ExoPlayerTestRunner.AUDIO_FORMAT); } } }; @@ -5887,11 +5925,11 @@ public final class ExoPlayerTest { .removeMediaItem(0) .build(); ExoPlayerTestRunner testRunner = - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(source1, source2) .setActionSchedule(actionSchedule) .setRenderers(videoRenderer, audioRenderer) - .build(context); + .build(); assertThrows( ExoPlaybackException.class, @@ -5904,7 +5942,8 @@ public final class ExoPlayerTest { assertThat(timelineAfterError.get().getWindowCount()).isEqualTo(1); assertThat(windowIndexAfterError.get()).isEqualTo(0); assertThat(trackGroupsAfterError.get().length).isEqualTo(1); - assertThat(trackGroupsAfterError.get().get(0).getFormat(0)).isEqualTo(Builder.AUDIO_FORMAT); + assertThat(trackGroupsAfterError.get().get(0).getFormat(0)) + .isEqualTo(ExoPlayerTestRunner.AUDIO_FORMAT); assertThat(trackSelectionsAfterError.get().get(0)).isNull(); // Video renderer. assertThat(trackSelectionsAfterError.get().get(1)).isNotNull(); // Audio renderer. } @@ -5935,10 +5974,10 @@ public final class ExoPlayerTest { } }) .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(mediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -5973,11 +6012,11 @@ public final class ExoPlayerTest { }) .play() .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setPauseAtEndOfMediaItems(true) .setMediaSources(mediaSource, mediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilEnded(TIMEOUT_MS); @@ -6011,11 +6050,11 @@ public final class ExoPlayerTest { } }) .build(); - new Builder() + new ExoPlayerTestRunner.Builder(context) .setPauseAtEndOfMediaItems(true) .setMediaSources(mediaSource) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -6031,7 +6070,8 @@ public final class ExoPlayerTest { public void infiniteLoading_withSmallAllocations_oomIsPreventedByLoadControl_andThrowsStuckBufferingIllegalStateException() { MediaSource continuouslyAllocatingMediaSource = - new FakeMediaSource(new FakeTimeline(/* windowCount= */ 1), Builder.VIDEO_FORMAT) { + new FakeMediaSource( + new FakeTimeline(/* windowCount= */ 1), ExoPlayerTestRunner.VIDEO_FORMAT) { @Override protected FakeMediaPeriod createFakeMediaPeriod( MediaPeriodId id, @@ -6078,10 +6118,10 @@ public final class ExoPlayerTest { .setRepeatMode(Player.REPEAT_MODE_ALL) .build(); ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setActionSchedule(actionSchedule) .setMediaSources(continuouslyAllocatingMediaSource) - .build(context); + .build(); ExoPlaybackException exception = assertThrows( @@ -6105,7 +6145,8 @@ public final class ExoPlayerTest { public void cancelLoad() {} }; MediaSource largeBufferAllocatingMediaSource = - new FakeMediaSource(new FakeTimeline(/* windowCount= */ 1), Builder.VIDEO_FORMAT) { + new FakeMediaSource( + new FakeTimeline(/* windowCount= */ 1), ExoPlayerTestRunner.VIDEO_FORMAT) { @Override protected FakeMediaPeriod createFakeMediaPeriod( MediaPeriodId id, @@ -6148,10 +6189,10 @@ public final class ExoPlayerTest { }; FakeRenderer renderer = new FakeRenderer(C.TRACK_TYPE_VIDEO); ExoPlayerTestRunner testRunner = - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setMediaSources(largeBufferAllocatingMediaSource) .setRenderers(renderer) - .build(context); + .build(); ExoPlaybackException exception = assertThrows( @@ -6179,10 +6220,10 @@ public final class ExoPlayerTest { onIsPlayingChanges.add(isPlaying); } }; - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setEventListener(eventListener) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -6236,9 +6277,9 @@ public final class ExoPlayerTest { .play() .waitForPlaybackState(Player.STATE_ENDED) .build(); - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(context) .setActionSchedule(actionSchedule) - .build(context) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); diff --git a/library/core/src/test/java/com/google/android/exoplayer2/analytics/AnalyticsCollectorTest.java b/library/core/src/test/java/com/google/android/exoplayer2/analytics/AnalyticsCollectorTest.java index f9f7f15abc..1d22984f84 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/analytics/AnalyticsCollectorTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/analytics/AnalyticsCollectorTest.java @@ -17,8 +17,6 @@ package com.google.android.exoplayer2.analytics; import static com.google.common.truth.Truth.assertThat; -import android.os.Handler; -import android.os.SystemClock; import android.view.Surface; import androidx.annotation.Nullable; import androidx.test.core.app.ApplicationProvider; @@ -32,7 +30,6 @@ import com.google.android.exoplayer2.RenderersFactory; import com.google.android.exoplayer2.SimpleExoPlayer; import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline.Window; -import com.google.android.exoplayer2.audio.AudioRendererEventListener; import com.google.android.exoplayer2.decoder.DecoderCounters; import com.google.android.exoplayer2.metadata.Metadata; import com.google.android.exoplayer2.source.ConcatenatingMediaSource; @@ -45,13 +42,13 @@ import com.google.android.exoplayer2.source.ads.AdPlaybackState; import com.google.android.exoplayer2.testutil.ActionSchedule; import com.google.android.exoplayer2.testutil.ActionSchedule.PlayerRunnable; import com.google.android.exoplayer2.testutil.ExoPlayerTestRunner; +import com.google.android.exoplayer2.testutil.FakeAudioRenderer; import com.google.android.exoplayer2.testutil.FakeMediaSource; -import com.google.android.exoplayer2.testutil.FakeRenderer; import com.google.android.exoplayer2.testutil.FakeTimeline; import com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinition; +import com.google.android.exoplayer2.testutil.FakeVideoRenderer; import com.google.android.exoplayer2.trackselection.TrackSelectionArray; import com.google.android.exoplayer2.util.Util; -import com.google.android.exoplayer2.video.VideoRendererEventListener; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; @@ -131,9 +128,7 @@ public final class AnalyticsCollectorTest { public void emptyTimeline() throws Exception { FakeMediaSource mediaSource = new FakeMediaSource( - Timeline.EMPTY, - ExoPlayerTestRunner.Builder.VIDEO_FORMAT, - ExoPlayerTestRunner.Builder.AUDIO_FORMAT); + Timeline.EMPTY, ExoPlayerTestRunner.VIDEO_FORMAT, ExoPlayerTestRunner.AUDIO_FORMAT); TestAnalyticsListener listener = runAnalyticsTest(mediaSource); assertThat(listener.getEvents(EVENT_PLAYER_STATE_CHANGED)) @@ -149,8 +144,8 @@ public final class AnalyticsCollectorTest { FakeMediaSource mediaSource = new FakeMediaSource( SINGLE_PERIOD_TIMELINE, - ExoPlayerTestRunner.Builder.VIDEO_FORMAT, - ExoPlayerTestRunner.Builder.AUDIO_FORMAT); + ExoPlayerTestRunner.VIDEO_FORMAT, + ExoPlayerTestRunner.AUDIO_FORMAT); TestAnalyticsListener listener = runAnalyticsTest(mediaSource); populateEventIds(listener.lastReportedTimeline); @@ -193,12 +188,12 @@ public final class AnalyticsCollectorTest { new ConcatenatingMediaSource( new FakeMediaSource( SINGLE_PERIOD_TIMELINE, - ExoPlayerTestRunner.Builder.VIDEO_FORMAT, - ExoPlayerTestRunner.Builder.AUDIO_FORMAT), + ExoPlayerTestRunner.VIDEO_FORMAT, + ExoPlayerTestRunner.AUDIO_FORMAT), new FakeMediaSource( SINGLE_PERIOD_TIMELINE, - ExoPlayerTestRunner.Builder.VIDEO_FORMAT, - ExoPlayerTestRunner.Builder.AUDIO_FORMAT)); + ExoPlayerTestRunner.VIDEO_FORMAT, + ExoPlayerTestRunner.AUDIO_FORMAT)); TestAnalyticsListener listener = runAnalyticsTest(mediaSource); populateEventIds(listener.lastReportedTimeline); @@ -252,8 +247,8 @@ public final class AnalyticsCollectorTest { public void periodTransitionWithRendererChange() throws Exception { MediaSource mediaSource = new ConcatenatingMediaSource( - new FakeMediaSource(SINGLE_PERIOD_TIMELINE, ExoPlayerTestRunner.Builder.VIDEO_FORMAT), - new FakeMediaSource(SINGLE_PERIOD_TIMELINE, ExoPlayerTestRunner.Builder.AUDIO_FORMAT)); + new FakeMediaSource(SINGLE_PERIOD_TIMELINE, ExoPlayerTestRunner.VIDEO_FORMAT), + new FakeMediaSource(SINGLE_PERIOD_TIMELINE, ExoPlayerTestRunner.AUDIO_FORMAT)); TestAnalyticsListener listener = runAnalyticsTest(mediaSource); populateEventIds(listener.lastReportedTimeline); @@ -307,9 +302,9 @@ public final class AnalyticsCollectorTest { new ConcatenatingMediaSource( new FakeMediaSource( SINGLE_PERIOD_TIMELINE, - ExoPlayerTestRunner.Builder.VIDEO_FORMAT, - ExoPlayerTestRunner.Builder.AUDIO_FORMAT), - new FakeMediaSource(SINGLE_PERIOD_TIMELINE, ExoPlayerTestRunner.Builder.AUDIO_FORMAT)); + ExoPlayerTestRunner.VIDEO_FORMAT, + ExoPlayerTestRunner.AUDIO_FORMAT), + new FakeMediaSource(SINGLE_PERIOD_TIMELINE, ExoPlayerTestRunner.AUDIO_FORMAT)); ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) .pause() @@ -378,11 +373,11 @@ public final class AnalyticsCollectorTest { public void seekBackAfterReadingAhead() throws Exception { MediaSource mediaSource = new ConcatenatingMediaSource( - new FakeMediaSource(SINGLE_PERIOD_TIMELINE, ExoPlayerTestRunner.Builder.VIDEO_FORMAT), + new FakeMediaSource(SINGLE_PERIOD_TIMELINE, ExoPlayerTestRunner.VIDEO_FORMAT), new FakeMediaSource( SINGLE_PERIOD_TIMELINE, - ExoPlayerTestRunner.Builder.VIDEO_FORMAT, - ExoPlayerTestRunner.Builder.AUDIO_FORMAT)); + ExoPlayerTestRunner.VIDEO_FORMAT, + ExoPlayerTestRunner.AUDIO_FORMAT)); long periodDurationMs = SINGLE_PERIOD_TIMELINE.getWindow(/* windowIndex= */ 0, new Window()).getDurationMs(); ActionSchedule actionSchedule = @@ -462,9 +457,9 @@ public final class AnalyticsCollectorTest { @Test public void prepareNewSource() throws Exception { MediaSource mediaSource1 = - new FakeMediaSource(SINGLE_PERIOD_TIMELINE, ExoPlayerTestRunner.Builder.VIDEO_FORMAT); + new FakeMediaSource(SINGLE_PERIOD_TIMELINE, ExoPlayerTestRunner.VIDEO_FORMAT); MediaSource mediaSource2 = - new FakeMediaSource(SINGLE_PERIOD_TIMELINE, ExoPlayerTestRunner.Builder.VIDEO_FORMAT); + new FakeMediaSource(SINGLE_PERIOD_TIMELINE, ExoPlayerTestRunner.VIDEO_FORMAT); ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) .pause() @@ -543,7 +538,7 @@ public final class AnalyticsCollectorTest { @Test public void reprepareAfterError() throws Exception { MediaSource mediaSource = - new FakeMediaSource(SINGLE_PERIOD_TIMELINE, ExoPlayerTestRunner.Builder.VIDEO_FORMAT); + new FakeMediaSource(SINGLE_PERIOD_TIMELINE, ExoPlayerTestRunner.VIDEO_FORMAT); ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) .pause() @@ -616,7 +611,7 @@ public final class AnalyticsCollectorTest { @Test public void dynamicTimelineChange() throws Exception { MediaSource childMediaSource = - new FakeMediaSource(SINGLE_PERIOD_TIMELINE, ExoPlayerTestRunner.Builder.VIDEO_FORMAT); + new FakeMediaSource(SINGLE_PERIOD_TIMELINE, ExoPlayerTestRunner.VIDEO_FORMAT); final ConcatenatingMediaSource concatenatedMediaSource = new ConcatenatingMediaSource(childMediaSource, childMediaSource); long periodDurationMs = @@ -697,7 +692,7 @@ public final class AnalyticsCollectorTest { @Test public void playlistOperations() throws Exception { MediaSource fakeMediaSource = - new FakeMediaSource(SINGLE_PERIOD_TIMELINE, ExoPlayerTestRunner.Builder.VIDEO_FORMAT); + new FakeMediaSource(SINGLE_PERIOD_TIMELINE, ExoPlayerTestRunner.VIDEO_FORMAT); ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) .pause() @@ -792,7 +787,7 @@ public final class AnalyticsCollectorTest { contentDurationsUs, adPlaybackState.get())); FakeMediaSource fakeMediaSource = - new FakeMediaSource(adTimeline, ExoPlayerTestRunner.Builder.VIDEO_FORMAT); + new FakeMediaSource(adTimeline, ExoPlayerTestRunner.VIDEO_FORMAT); ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) .executeRunnable( @@ -1031,7 +1026,7 @@ public final class AnalyticsCollectorTest { TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US + 5 * C.MICROS_PER_SECOND))); FakeMediaSource fakeMediaSource = - new FakeMediaSource(adTimeline, ExoPlayerTestRunner.Builder.VIDEO_FORMAT); + new FakeMediaSource(adTimeline, ExoPlayerTestRunner.VIDEO_FORMAT); ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG) .pause() @@ -1223,12 +1218,12 @@ public final class AnalyticsCollectorTest { }; TestAnalyticsListener listener = new TestAnalyticsListener(); try { - new ExoPlayerTestRunner.Builder() + new ExoPlayerTestRunner.Builder(ApplicationProvider.getApplicationContext()) .setMediaSources(mediaSource) .setRenderersFactory(renderersFactory) .setAnalyticsListener(listener) .setActionSchedule(actionSchedule) - .build(ApplicationProvider.getApplicationContext()) + .build() .start() .blockUntilActionScheduleFinished(TIMEOUT_MS) .blockUntilEnded(TIMEOUT_MS); @@ -1238,140 +1233,6 @@ public final class AnalyticsCollectorTest { return listener; } - private static final class FakeVideoRenderer extends FakeRenderer { - - private final VideoRendererEventListener.EventDispatcher eventDispatcher; - private final DecoderCounters decoderCounters; - private Format format; - private long streamOffsetUs; - private boolean renderedFirstFrameAfterReset; - private boolean mayRenderFirstFrameAfterEnableIfNotStarted; - private boolean renderedFirstFrameAfterEnable; - - public FakeVideoRenderer(Handler handler, VideoRendererEventListener eventListener) { - super(C.TRACK_TYPE_VIDEO); - eventDispatcher = new VideoRendererEventListener.EventDispatcher(handler, eventListener); - decoderCounters = new DecoderCounters(); - } - - @Override - protected void onEnabled(boolean joining, boolean mayRenderStartOfStream) - throws ExoPlaybackException { - super.onEnabled(joining, mayRenderStartOfStream); - eventDispatcher.enabled(decoderCounters); - mayRenderFirstFrameAfterEnableIfNotStarted = mayRenderStartOfStream; - renderedFirstFrameAfterEnable = false; - } - - @Override - protected void onStreamChanged(Format[] formats, long offsetUs) throws ExoPlaybackException { - super.onStreamChanged(formats, offsetUs); - streamOffsetUs = offsetUs; - if (renderedFirstFrameAfterReset) { - renderedFirstFrameAfterReset = false; - } - } - - @Override - protected void onStopped() throws ExoPlaybackException { - super.onStopped(); - eventDispatcher.droppedFrames(/* droppedFrameCount= */ 0, /* elapsedMs= */ 0); - eventDispatcher.reportVideoFrameProcessingOffset( - /* totalProcessingOffsetUs= */ 400000, /* frameCount= */ 10, this.format); - } - - @Override - protected void onDisabled() { - super.onDisabled(); - eventDispatcher.disabled(decoderCounters); - } - - @Override - protected void onPositionReset(long positionUs, boolean joining) throws ExoPlaybackException { - super.onPositionReset(positionUs, joining); - renderedFirstFrameAfterReset = false; - } - - @Override - protected void onFormatChanged(Format format) { - eventDispatcher.inputFormatChanged(format); - eventDispatcher.decoderInitialized( - /* decoderName= */ "fake.video.decoder", - /* initializedTimestampMs= */ SystemClock.elapsedRealtime(), - /* initializationDurationMs= */ 0); - this.format = format; - } - - @Override - protected boolean shouldProcessBuffer(long bufferTimeUs, long playbackPositionUs) { - boolean shouldProcess = super.shouldProcessBuffer(bufferTimeUs, playbackPositionUs); - boolean shouldRenderFirstFrame = - !renderedFirstFrameAfterEnable - ? (getState() == Renderer.STATE_STARTED || mayRenderFirstFrameAfterEnableIfNotStarted) - : !renderedFirstFrameAfterReset; - shouldProcess |= shouldRenderFirstFrame && playbackPositionUs >= streamOffsetUs; - if (shouldProcess && !renderedFirstFrameAfterReset) { - eventDispatcher.videoSizeChanged( - format.width, format.height, format.rotationDegrees, format.pixelWidthHeightRatio); - eventDispatcher.renderedFirstFrame(/* surface= */ null); - renderedFirstFrameAfterReset = true; - renderedFirstFrameAfterEnable = true; - } - return shouldProcess; - } - } - - private static final class FakeAudioRenderer extends FakeRenderer { - - private final AudioRendererEventListener.EventDispatcher eventDispatcher; - private final DecoderCounters decoderCounters; - private boolean notifiedAudioSessionId; - - public FakeAudioRenderer(Handler handler, AudioRendererEventListener eventListener) { - super(C.TRACK_TYPE_AUDIO); - eventDispatcher = new AudioRendererEventListener.EventDispatcher(handler, eventListener); - decoderCounters = new DecoderCounters(); - } - - @Override - protected void onEnabled(boolean joining, boolean mayRenderStartOfStream) - throws ExoPlaybackException { - super.onEnabled(joining, mayRenderStartOfStream); - eventDispatcher.enabled(decoderCounters); - notifiedAudioSessionId = false; - } - - @Override - protected void onDisabled() { - super.onDisabled(); - eventDispatcher.disabled(decoderCounters); - } - - @Override - protected void onPositionReset(long positionUs, boolean joining) throws ExoPlaybackException { - super.onPositionReset(positionUs, joining); - } - - @Override - protected void onFormatChanged(Format format) { - eventDispatcher.inputFormatChanged(format); - eventDispatcher.decoderInitialized( - /* decoderName= */ "fake.audio.decoder", - /* initializedTimestampMs= */ SystemClock.elapsedRealtime(), - /* initializationDurationMs= */ 0); - } - - @Override - protected boolean shouldProcessBuffer(long bufferTimeUs, long playbackPositionUs) { - boolean shouldProcess = super.shouldProcessBuffer(bufferTimeUs, playbackPositionUs); - if (shouldProcess && !notifiedAudioSessionId) { - eventDispatcher.audioSessionId(/* audioSessionId= */ 1); - notifiedAudioSessionId = true; - } - return shouldProcess; - } - } - private static final class EventWindowAndPeriodId { private final int windowIndex; diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/ExoPlayerTestRunner.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/ExoPlayerTestRunner.java index 6b3dbb0fbf..2869c5b0f2 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/ExoPlayerTestRunner.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/ExoPlayerTestRunner.java @@ -17,14 +17,12 @@ package com.google.android.exoplayer2.testutil; import static com.google.common.truth.Truth.assertThat; import static junit.framework.TestCase.assertFalse; -import static junit.framework.TestCase.assertTrue; import android.content.Context; import android.os.HandlerThread; import android.os.Looper; import androidx.annotation.Nullable; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.DefaultLoadControl; import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.LoadControl; @@ -33,22 +31,18 @@ import com.google.android.exoplayer2.Renderer; import com.google.android.exoplayer2.RenderersFactory; import com.google.android.exoplayer2.SimpleExoPlayer; import com.google.android.exoplayer2.Timeline; -import com.google.android.exoplayer2.analytics.AnalyticsCollector; import com.google.android.exoplayer2.analytics.AnalyticsListener; import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; import com.google.android.exoplayer2.trackselection.TrackSelectionArray; import com.google.android.exoplayer2.upstream.BandwidthMeter; -import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter; import com.google.android.exoplayer2.util.Clock; import com.google.android.exoplayer2.util.HandlerWrapper; import com.google.android.exoplayer2.util.MimeTypes; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashSet; import java.util.List; -import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -56,52 +50,47 @@ import java.util.concurrent.TimeoutException; /** Helper class to run an ExoPlayer test. */ public final class ExoPlayerTestRunner implements Player.EventListener, ActionSchedule.Callback { + /** A generic video {@link Format} which can be used to set up a {@link FakeMediaSource}. */ + public static final Format VIDEO_FORMAT = + new Format.Builder() + .setSampleMimeType(MimeTypes.VIDEO_H264) + .setAverageBitrate(800_000) + .setWidth(1280) + .setHeight(720) + .build(); + + /** A generic audio {@link Format} which can be used to set up a {@link FakeMediaSource}. */ + public static final Format AUDIO_FORMAT = + new Format.Builder() + .setSampleMimeType(MimeTypes.AUDIO_AAC) + .setAverageBitrate(100_000) + .setChannelCount(2) + .setSampleRate(44100) + .build(); + /** * Builder to set-up a {@link ExoPlayerTestRunner}. Default fake implementations will be used for * unset test properties. */ public static final class Builder { - - /** A generic video {@link Format} which can be used to set up media sources and renderers. */ - public static final Format VIDEO_FORMAT = - new Format.Builder() - .setSampleMimeType(MimeTypes.VIDEO_H264) - .setAverageBitrate(800_000) - .setWidth(1280) - .setHeight(720) - .build(); - - /** A generic audio {@link Format} which can be used to set up media sources and renderers. */ - public static final Format AUDIO_FORMAT = - new Format.Builder() - .setSampleMimeType(MimeTypes.AUDIO_AAC) - .setAverageBitrate(100_000) - .setChannelCount(2) - .setSampleRate(44100) - .build(); - - private Clock clock; + private final TestExoPlayer.Builder testPlayerBuilder; private Timeline timeline; private List mediaSources; - private Object manifest; - private DefaultTrackSelector trackSelector; - private LoadControl loadControl; - private BandwidthMeter bandwidthMeter; private Format[] supportedFormats; - private Renderer[] renderers; - private RenderersFactory renderersFactory; + private Object manifest; private ActionSchedule actionSchedule; private Player.EventListener eventListener; private AnalyticsListener analyticsListener; private Integer expectedPlayerEndedCount; - private boolean useLazyPreparation; private boolean pauseAtEndOfMediaItems; private int initialWindowIndex; private long initialPositionMs; private boolean skipSettingMediaSources; - public Builder() { + public Builder(Context context) { + testPlayerBuilder = new TestExoPlayer.Builder(context); mediaSources = new ArrayList<>(); + supportedFormats = new Format[] {VIDEO_FORMAT}; initialWindowIndex = C.INDEX_UNSET; initialPositionMs = C.TIME_UNSET; } @@ -170,6 +159,20 @@ public final class ExoPlayerTestRunner implements Player.EventListener, ActionSc return this; } + /** + * Sets a list of {@link Format}s to be used by a {@link FakeMediaSource} to create media + * periods. The default value is a single {@link #VIDEO_FORMAT}. Note that this parameter + * doesn't have any influence if a media source with {@link #setMediaSources(MediaSource...)} is + * set. + * + * @param supportedFormats A list of supported {@link Format}s. + * @return This builder. + */ + public Builder setSupportedFormats(Format... supportedFormats) { + this.supportedFormats = supportedFormats; + return this; + } + /** * Skips calling {@link com.google.android.exoplayer2.ExoPlayer#setMediaSources(List)} before * preparing. Calling this method is not allowed after calls to {@link @@ -181,19 +184,17 @@ public final class ExoPlayerTestRunner implements Player.EventListener, ActionSc public Builder skipSettingMediaSources() { assertThat(timeline).isNull(); assertThat(manifest).isNull(); - assertTrue(mediaSources.isEmpty()); + assertThat(mediaSources).isEmpty(); skipSettingMediaSources = true; return this; } /** - * Sets whether to use lazy preparation. - * - * @param useLazyPreparation Whether to use lazy preparation. + * @see TestExoPlayer.Builder#setUseLazyPreparation(boolean) * @return This builder. */ public Builder setUseLazyPreparation(boolean useLazyPreparation) { - this.useLazyPreparation = useLazyPreparation; + testPlayerBuilder.setUseLazyPreparation(useLazyPreparation); return this; } @@ -209,94 +210,56 @@ public final class ExoPlayerTestRunner implements Player.EventListener, ActionSc } /** - * Sets a {@link DefaultTrackSelector} to be used by the test runner. The default value is a - * {@link DefaultTrackSelector} in its initial configuration. - * - * @param trackSelector A {@link DefaultTrackSelector} to be used by the test runner. + * @see TestExoPlayer.Builder#setTrackSelector(DefaultTrackSelector) * @return This builder. */ public Builder setTrackSelector(DefaultTrackSelector trackSelector) { - this.trackSelector = trackSelector; + testPlayerBuilder.setTrackSelector(trackSelector); return this; } /** - * Sets a {@link LoadControl} to be used by the test runner. The default value is a - * {@link DefaultLoadControl}. - * - * @param loadControl A {@link LoadControl} to be used by the test runner. + * @see TestExoPlayer.Builder#setLoadControl(LoadControl) * @return This builder. */ public Builder setLoadControl(LoadControl loadControl) { - this.loadControl = loadControl; + testPlayerBuilder.setLoadControl(loadControl); return this; } /** - * Sets the {@link BandwidthMeter} to be used by the test runner. The default value is a {@link - * DefaultBandwidthMeter} in its default configuration. - * - * @param bandwidthMeter The {@link BandwidthMeter} to be used by the test runner. + * @see TestExoPlayer.Builder#setBandwidthMeter(BandwidthMeter) * @return This builder. */ public Builder setBandwidthMeter(BandwidthMeter bandwidthMeter) { - this.bandwidthMeter = bandwidthMeter; + this.testPlayerBuilder.setBandwidthMeter(bandwidthMeter); return this; } /** - * Sets a list of {@link Format}s to be used by a {@link FakeMediaSource} to create media - * periods and for setting up a {@link FakeRenderer}. The default value is a single {@link - * #VIDEO_FORMAT}. Note that this parameter doesn't have any influence if both a media source - * with {@link #setMediaSources(MediaSource...)} and renderers with {@link - * #setRenderers(Renderer...)} or {@link #setRenderersFactory(RenderersFactory)} are set. - * - * @param supportedFormats A list of supported {@link Format}s. - * @return This builder. - */ - public Builder setSupportedFormats(Format... supportedFormats) { - this.supportedFormats = supportedFormats; - return this; - } - - /** - * Sets the {@link Renderer}s to be used by the test runner. The default value is a single - * {@link FakeRenderer} supporting the formats set by {@link #setSupportedFormats(Format...)}. - * Setting the renderers is not allowed after a call to - * {@link #setRenderersFactory(RenderersFactory)}. - * - * @param renderers A list of {@link Renderer}s to be used by the test runner. + * @see TestExoPlayer.Builder#setRenderers(Renderer...) * @return This builder. */ public Builder setRenderers(Renderer... renderers) { - assertThat(renderersFactory).isNull(); - this.renderers = renderers; + testPlayerBuilder.setRenderers(renderers); return this; } /** - * Sets the {@link RenderersFactory} to be used by the test runner. The default factory creates - * all renderers set by {@link #setRenderers(Renderer...)}. Setting the renderer factory is not - * allowed after a call to {@link #setRenderers(Renderer...)}. - * - * @param renderersFactory A {@link RenderersFactory} to be used by the test runner. + * @see TestExoPlayer.Builder#setRenderersFactory(RenderersFactory) * @return This builder. */ public Builder setRenderersFactory(RenderersFactory renderersFactory) { - assertThat(renderers).isNull(); - this.renderersFactory = renderersFactory; + testPlayerBuilder.setRenderersFactory(renderersFactory); return this; } /** - * Sets the {@link Clock} to be used by the test runner. The default value is a {@link - * AutoAdvancingFakeClock}. - * - * @param clock A {@link Clock} to be used by the test runner. + * @see TestExoPlayer.Builder#setClock(Clock) * @return This builder. */ public Builder setClock(Clock clock) { - this.clock = clock; + testPlayerBuilder.setClock(clock); return this; } @@ -352,45 +315,9 @@ public final class ExoPlayerTestRunner implements Player.EventListener, ActionSc /** * Builds an {@link ExoPlayerTestRunner} using the provided values or their defaults. * - * @param context The context. * @return The built {@link ExoPlayerTestRunner}. */ - public ExoPlayerTestRunner build(Context context) { - if (supportedFormats == null) { - supportedFormats = new Format[] {VIDEO_FORMAT}; - } - if (trackSelector == null) { - trackSelector = new DefaultTrackSelector(context); - } - if (bandwidthMeter == null) { - bandwidthMeter = new DefaultBandwidthMeter.Builder(context).build(); - } - if (renderersFactory == null) { - if (renderers == null) { - Set trackTypes = new HashSet<>(); - for (Format format : supportedFormats) { - trackTypes.add(MimeTypes.getTrackType(format.sampleMimeType)); - } - renderers = new Renderer[trackTypes.size()]; - int i = 0; - for (int trackType : trackTypes) { - renderers[i] = new FakeRenderer(trackType); - i++; - } - } - renderersFactory = - (eventHandler, - videoRendererEventListener, - audioRendererEventListener, - textRendererOutput, - metadataRendererOutput) -> renderers; - } - if (loadControl == null) { - loadControl = new DefaultLoadControl(); - } - if (clock == null) { - clock = new AutoAdvancingFakeClock(); - } + public ExoPlayerTestRunner build() { if (mediaSources.isEmpty() && !skipSettingMediaSources) { if (timeline == null) { timeline = new FakeTimeline(/* windowCount= */ 1, manifest); @@ -401,34 +328,24 @@ public final class ExoPlayerTestRunner implements Player.EventListener, ActionSc expectedPlayerEndedCount = 1; } return new ExoPlayerTestRunner( - context, - clock, - initialWindowIndex, - initialPositionMs, + testPlayerBuilder, mediaSources, skipSettingMediaSources, - useLazyPreparation, - pauseAtEndOfMediaItems, - renderersFactory, - trackSelector, - loadControl, - bandwidthMeter, + initialWindowIndex, + initialPositionMs, actionSchedule, eventListener, analyticsListener, - expectedPlayerEndedCount); + expectedPlayerEndedCount, + pauseAtEndOfMediaItems); } } - private final Context context; - private final Clock clock; + private final TestExoPlayer.Builder playerBuilder; + private final List mediaSources; + private final boolean skipSettingMediaSources; private final int initialWindowIndex; private final long initialPositionMs; - private final List mediaSources; - private final RenderersFactory renderersFactory; - private final DefaultTrackSelector trackSelector; - private final LoadControl loadControl; - private final BandwidthMeter bandwidthMeter; @Nullable private final ActionSchedule actionSchedule; @Nullable private final Player.EventListener eventListener; @Nullable private final AnalyticsListener analyticsListener; @@ -442,8 +359,6 @@ public final class ExoPlayerTestRunner implements Player.EventListener, ActionSc private final ArrayList periodIndices; private final ArrayList discontinuityReasons; private final ArrayList playbackStates; - private final boolean skipSettingMediaSources; - private final boolean useLazyPreparation; private final boolean pauseAtEndOfMediaItems; private SimpleExoPlayer player; @@ -452,47 +367,36 @@ public final class ExoPlayerTestRunner implements Player.EventListener, ActionSc private boolean playerWasPrepared; private ExoPlayerTestRunner( - Context context, - Clock clock, - int initialWindowIndex, - long initialPositionMs, + TestExoPlayer.Builder playerBuilder, List mediaSources, boolean skipSettingMediaSources, - boolean useLazyPreparation, - boolean pauseAtEndOfMediaItems, - RenderersFactory renderersFactory, - DefaultTrackSelector trackSelector, - LoadControl loadControl, - BandwidthMeter bandwidthMeter, + int initialWindowIndex, + long initialPositionMs, @Nullable ActionSchedule actionSchedule, @Nullable Player.EventListener eventListener, @Nullable AnalyticsListener analyticsListener, - int expectedPlayerEndedCount) { - this.context = context; - this.clock = clock; - this.initialWindowIndex = initialWindowIndex; - this.initialPositionMs = initialPositionMs; + int expectedPlayerEndedCount, + boolean pauseAtEndOfMediaItems) { + this.playerBuilder = playerBuilder; this.mediaSources = mediaSources; this.skipSettingMediaSources = skipSettingMediaSources; - this.useLazyPreparation = useLazyPreparation; - this.pauseAtEndOfMediaItems = pauseAtEndOfMediaItems; - this.renderersFactory = renderersFactory; - this.trackSelector = trackSelector; - this.loadControl = loadControl; - this.bandwidthMeter = bandwidthMeter; + this.initialWindowIndex = initialWindowIndex; + this.initialPositionMs = initialPositionMs; this.actionSchedule = actionSchedule; this.eventListener = eventListener; this.analyticsListener = analyticsListener; - this.timelines = new ArrayList<>(); - this.timelineChangeReasons = new ArrayList<>(); - this.periodIndices = new ArrayList<>(); - this.discontinuityReasons = new ArrayList<>(); - this.playbackStates = new ArrayList<>(); - this.endedCountDownLatch = new CountDownLatch(expectedPlayerEndedCount); - this.actionScheduleFinishedCountDownLatch = new CountDownLatch(actionSchedule != null ? 1 : 0); - this.playerThread = new HandlerThread("ExoPlayerTest thread"); + timelines = new ArrayList<>(); + timelineChangeReasons = new ArrayList<>(); + periodIndices = new ArrayList<>(); + discontinuityReasons = new ArrayList<>(); + playbackStates = new ArrayList<>(); + endedCountDownLatch = new CountDownLatch(expectedPlayerEndedCount); + actionScheduleFinishedCountDownLatch = new CountDownLatch(actionSchedule != null ? 1 : 0); + playerThread = new HandlerThread("ExoPlayerTest thread"); playerThread.start(); - this.handler = clock.createHandler(playerThread.getLooper(), /* callback= */ null); + handler = + playerBuilder.getClock().createHandler(playerThread.getLooper(), /* callback= */ null); + this.pauseAtEndOfMediaItems = pauseAtEndOfMediaItems; } // Called on the test thread to run the test. @@ -519,16 +423,7 @@ public final class ExoPlayerTestRunner implements Player.EventListener, ActionSc handler.post( () -> { try { - player = - new SimpleExoPlayer.Builder(context, renderersFactory) - .setTrackSelector(trackSelector) - .setLoadControl(loadControl) - .setBandwidthMeter(bandwidthMeter) - .setAnalyticsCollector(new AnalyticsCollector(clock)) - .setClock(clock) - .setUseLazyPreparation(useLazyPreparation) - .setLooper(Looper.myLooper()) - .build(); + player = playerBuilder.setLooper(Looper.myLooper()).build(); player.addListener(ExoPlayerTestRunner.this); if (eventListener != null) { player.addListener(eventListener); @@ -541,7 +436,12 @@ public final class ExoPlayerTestRunner implements Player.EventListener, ActionSc } player.play(); if (actionSchedule != null) { - actionSchedule.start(player, trackSelector, null, handler, ExoPlayerTestRunner.this); + actionSchedule.start( + player, + playerBuilder.getTrackSelector(), + /* surface= */ null, + handler, + /* callback= */ ExoPlayerTestRunner.this); } if (initialWindowIndex != C.INDEX_UNSET) { player.seekTo(initialWindowIndex, initialPositionMs); diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeAudioRenderer.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeAudioRenderer.java new file mode 100644 index 0000000000..5ed4e5bf5f --- /dev/null +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeAudioRenderer.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2020 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 android.os.Handler; +import android.os.SystemClock; +import com.google.android.exoplayer2.C; +import com.google.android.exoplayer2.ExoPlaybackException; +import com.google.android.exoplayer2.Format; +import com.google.android.exoplayer2.audio.AudioRendererEventListener; +import com.google.android.exoplayer2.decoder.DecoderCounters; + +/** A {@link FakeRenderer} that supports {@link C#TRACK_TYPE_AUDIO}. */ +public class FakeAudioRenderer extends FakeRenderer { + + private final AudioRendererEventListener.EventDispatcher eventDispatcher; + private final DecoderCounters decoderCounters; + private boolean notifiedAudioSessionId; + + public FakeAudioRenderer(Handler handler, AudioRendererEventListener eventListener) { + super(C.TRACK_TYPE_AUDIO); + eventDispatcher = new AudioRendererEventListener.EventDispatcher(handler, eventListener); + decoderCounters = new DecoderCounters(); + } + + @Override + protected void onEnabled(boolean joining, boolean mayRenderStartOfStream) + throws ExoPlaybackException { + super.onEnabled(joining, mayRenderStartOfStream); + eventDispatcher.enabled(decoderCounters); + notifiedAudioSessionId = false; + } + + @Override + protected void onDisabled() { + super.onDisabled(); + eventDispatcher.disabled(decoderCounters); + } + + @Override + protected void onFormatChanged(Format format) { + eventDispatcher.inputFormatChanged(format); + eventDispatcher.decoderInitialized( + /* decoderName= */ "fake.audio.decoder", + /* initializedTimestampMs= */ SystemClock.elapsedRealtime(), + /* initializationDurationMs= */ 0); + } + + @Override + protected boolean shouldProcessBuffer(long bufferTimeUs, long playbackPositionUs) { + boolean shouldProcess = super.shouldProcessBuffer(bufferTimeUs, playbackPositionUs); + if (shouldProcess && !notifiedAudioSessionId) { + eventDispatcher.audioSessionId(/* audioSessionId= */ 1); + notifiedAudioSessionId = true; + } + return shouldProcess; + } +} diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeVideoRenderer.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeVideoRenderer.java new file mode 100644 index 0000000000..2016f9d000 --- /dev/null +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeVideoRenderer.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2020 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 android.os.Handler; +import android.os.SystemClock; +import com.google.android.exoplayer2.C; +import com.google.android.exoplayer2.ExoPlaybackException; +import com.google.android.exoplayer2.Format; +import com.google.android.exoplayer2.Renderer; +import com.google.android.exoplayer2.decoder.DecoderCounters; +import com.google.android.exoplayer2.util.Assertions; +import com.google.android.exoplayer2.video.VideoRendererEventListener; +import org.checkerframework.checker.nullness.qual.MonotonicNonNull; + +/** A {@link FakeRenderer} that supports {@link C#TRACK_TYPE_VIDEO}. */ +public class FakeVideoRenderer extends FakeRenderer { + + private final VideoRendererEventListener.EventDispatcher eventDispatcher; + private final DecoderCounters decoderCounters; + private @MonotonicNonNull Format format; + private long streamOffsetUs; + private boolean renderedFirstFrameAfterReset; + private boolean mayRenderFirstFrameAfterEnableIfNotStarted; + private boolean renderedFirstFrameAfterEnable; + + public FakeVideoRenderer(Handler handler, VideoRendererEventListener eventListener) { + super(C.TRACK_TYPE_VIDEO); + eventDispatcher = new VideoRendererEventListener.EventDispatcher(handler, eventListener); + decoderCounters = new DecoderCounters(); + } + + @Override + protected void onEnabled(boolean joining, boolean mayRenderStartOfStream) + throws ExoPlaybackException { + super.onEnabled(joining, mayRenderStartOfStream); + eventDispatcher.enabled(decoderCounters); + mayRenderFirstFrameAfterEnableIfNotStarted = mayRenderStartOfStream; + renderedFirstFrameAfterEnable = false; + } + + @Override + protected void onStreamChanged(Format[] formats, long offsetUs) throws ExoPlaybackException { + super.onStreamChanged(formats, offsetUs); + streamOffsetUs = offsetUs; + if (renderedFirstFrameAfterReset) { + renderedFirstFrameAfterReset = false; + } + } + + @Override + protected void onStopped() throws ExoPlaybackException { + super.onStopped(); + eventDispatcher.droppedFrames(/* droppedFrameCount= */ 0, /* elapsedMs= */ 0); + eventDispatcher.reportVideoFrameProcessingOffset( + /* totalProcessingOffsetUs= */ 400000, + /* frameCount= */ 10, + Assertions.checkNotNull(format)); + } + + @Override + protected void onDisabled() { + super.onDisabled(); + eventDispatcher.disabled(decoderCounters); + } + + @Override + protected void onPositionReset(long positionUs, boolean joining) throws ExoPlaybackException { + super.onPositionReset(positionUs, joining); + renderedFirstFrameAfterReset = false; + } + + @Override + protected void onFormatChanged(Format format) { + eventDispatcher.inputFormatChanged(format); + eventDispatcher.decoderInitialized( + /* decoderName= */ "fake.video.decoder", + /* initializedTimestampMs= */ SystemClock.elapsedRealtime(), + /* initializationDurationMs= */ 0); + this.format = format; + } + + @Override + protected boolean shouldProcessBuffer(long bufferTimeUs, long playbackPositionUs) { + boolean shouldProcess = super.shouldProcessBuffer(bufferTimeUs, playbackPositionUs); + boolean shouldRenderFirstFrame = + !renderedFirstFrameAfterEnable + ? (getState() == Renderer.STATE_STARTED || mayRenderFirstFrameAfterEnableIfNotStarted) + : !renderedFirstFrameAfterReset; + shouldProcess |= shouldRenderFirstFrame && playbackPositionUs >= streamOffsetUs; + if (shouldProcess && !renderedFirstFrameAfterReset) { + @MonotonicNonNull Format format = Assertions.checkNotNull(this.format); + eventDispatcher.videoSizeChanged( + format.width, format.height, format.rotationDegrees, format.pixelWidthHeightRatio); + eventDispatcher.renderedFirstFrame(/* surface= */ null); + renderedFirstFrameAfterReset = true; + renderedFirstFrameAfterEnable = true; + } + return shouldProcess; + } +} diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/TestExoPlayer.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/TestExoPlayer.java new file mode 100644 index 0000000000..d0dc1dfac4 --- /dev/null +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/TestExoPlayer.java @@ -0,0 +1,456 @@ +/* + * Copyright (C) 2020 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 com.google.common.truth.Truth.assertThat; + +import android.content.Context; +import android.os.Looper; +import androidx.annotation.Nullable; +import com.google.android.exoplayer2.DefaultLoadControl; +import com.google.android.exoplayer2.ExoPlaybackException; +import com.google.android.exoplayer2.LoadControl; +import com.google.android.exoplayer2.Player; +import com.google.android.exoplayer2.Renderer; +import com.google.android.exoplayer2.RenderersFactory; +import com.google.android.exoplayer2.SimpleExoPlayer; +import com.google.android.exoplayer2.Timeline; +import com.google.android.exoplayer2.analytics.AnalyticsCollector; +import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; +import com.google.android.exoplayer2.upstream.BandwidthMeter; +import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter; +import com.google.android.exoplayer2.util.Assertions; +import com.google.android.exoplayer2.util.Clock; +import com.google.android.exoplayer2.util.Supplier; +import com.google.android.exoplayer2.video.VideoListener; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; + +/** + * Utilities to write unit/integration tests with a SimpleExoPlayer instance that uses fake + * components. + */ +public class TestExoPlayer { + + /** Reflectively call Robolectric ShadowLooper#runOneTask. */ + private static final Object shadowLooper; + + private static final Method runOneTaskMethod; + + static { + try { + Class clazz = Class.forName("org.robolectric.Shadows"); + Method shadowOfMethod = + Assertions.checkNotNull(clazz.getDeclaredMethod("shadowOf", Looper.class)); + shadowLooper = + Assertions.checkNotNull(shadowOfMethod.invoke(new Object(), Looper.getMainLooper())); + runOneTaskMethod = shadowLooper.getClass().getDeclaredMethod("runOneTask"); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** A builder of {@link SimpleExoPlayer} instances for testing. */ + public static class Builder { + + private final Context context; + private Clock clock; + private DefaultTrackSelector trackSelector; + private LoadControl loadControl; + private BandwidthMeter bandwidthMeter; + @Nullable private Renderer[] renderers; + @Nullable private RenderersFactory renderersFactory; + private boolean useLazyPreparation; + private Looper looper; + + public Builder(Context context) { + this.context = context; + clock = new AutoAdvancingFakeClock(); + trackSelector = new DefaultTrackSelector(context); + loadControl = new DefaultLoadControl(); + bandwidthMeter = new DefaultBandwidthMeter.Builder(context).build(); + looper = Assertions.checkNotNull(Looper.myLooper()); + } + + /** + * Sets whether to use lazy preparation. + * + * @param useLazyPreparation Whether to use lazy preparation. + * @return This builder. + */ + public Builder setUseLazyPreparation(boolean useLazyPreparation) { + this.useLazyPreparation = useLazyPreparation; + return this; + } + + /** Returns whether the player will use lazy preparation. */ + public boolean getUseLazyPreparation() { + return useLazyPreparation; + } + + /** + * Sets a {@link DefaultTrackSelector}. The default value is a {@link DefaultTrackSelector} in + * its initial configuration. + * + * @param trackSelector The {@link DefaultTrackSelector} to be used by the player. + * @return This builder. + */ + public Builder setTrackSelector(DefaultTrackSelector trackSelector) { + Assertions.checkNotNull(trackSelector); + this.trackSelector = trackSelector; + return this; + } + + /** Returns the track selector used by the player. */ + public DefaultTrackSelector getTrackSelector() { + return trackSelector; + } + + /** + * Sets a {@link LoadControl} to be used by the player. The default value is a {@link + * DefaultLoadControl}. + * + * @param loadControl The {@link LoadControl} to be used by the player. + * @return This builder. + */ + public Builder setLoadControl(LoadControl loadControl) { + this.loadControl = loadControl; + return this; + } + + /** Returns the {@link LoadControl} that will be used by the player. */ + public LoadControl getLoadControl() { + return loadControl; + } + + /** + * Sets the {@link BandwidthMeter}. The default value is a {@link DefaultBandwidthMeter} in its + * default configuration. + * + * @param bandwidthMeter The {@link BandwidthMeter} to be used by the player. + * @return This builder. + */ + public Builder setBandwidthMeter(BandwidthMeter bandwidthMeter) { + Assertions.checkNotNull(bandwidthMeter); + this.bandwidthMeter = bandwidthMeter; + return this; + } + + /** Returns the bandwidth meter used by the player. */ + public BandwidthMeter getBandwidthMeter() { + return bandwidthMeter; + } + + /** + * Sets the {@link Renderer}s. If not set, the player will use a {@link FakeVideoRenderer} and a + * {@link FakeAudioRenderer}. Setting the renderers is not allowed after a call to {@link + * #setRenderersFactory(RenderersFactory)}. + * + * @param renderers A list of {@link Renderer}s to be used by the player. + * @return This builder. + */ + public Builder setRenderers(Renderer... renderers) { + assertThat(renderersFactory).isNull(); + this.renderers = renderers; + return this; + } + + /** + * Returns the {@link Renderer Renderers} that have been set with {@link #setRenderers} or null + * if no {@link Renderer Renderers} have been explicitly set. Note that these renderers may not + * be the ones used by the built player, for example if a {@link #setRenderersFactory Renderer + * factory} has been set. + */ + @Nullable + public Renderer[] getRenderers() { + return renderers; + } + + /** + * Sets the {@link RenderersFactory}. The default factory creates all renderers set by {@link + * #setRenderers(Renderer...)}. Setting the renderer factory is not allowed after a call to + * {@link #setRenderers(Renderer...)}. + * + * @param renderersFactory A {@link RenderersFactory} to be used by the player. + * @return This builder. + */ + public Builder setRenderersFactory(RenderersFactory renderersFactory) { + assertThat(renderers).isNull(); + this.renderersFactory = renderersFactory; + return this; + } + + /** + * Returns the {@link RenderersFactory} that has been set with {@link #setRenderersFactory} or + * null if no factory has been explicitly set. + */ + @Nullable + public RenderersFactory getRenderersFactory() { + return renderersFactory; + } + + /** + * Sets the {@link Clock} to be used by the player. The default value is a {@link + * AutoAdvancingFakeClock}. + * + * @param clock A {@link Clock} to be used by the player. + * @return This builder. + */ + public Builder setClock(Clock clock) { + assertThat(clock).isNotNull(); + this.clock = clock; + return this; + } + + /** Returns the clock used by the player. */ + public Clock getClock() { + return clock; + } + + /** + * Sets the {@link Looper} to be used by the player. + * + * @param looper The {@link Looper} to be used by the player. + * @return This builder. + */ + public Builder setLooper(Looper looper) { + this.looper = looper; + return this; + } + + /** Returns the {@link Looper} that will be used by the player. */ + public Looper getLooper() { + return looper; + } + + /** + * Builds an {@link SimpleExoPlayer} using the provided values or their defaults. + * + * @return The built {@link ExoPlayerTestRunner}. + */ + public SimpleExoPlayer build() { + // Do not update renderersFactory and renderers here, otherwise their getters may + // return different values before and after build() is called, making them confusing. + RenderersFactory playerRenderersFactory = renderersFactory; + if (playerRenderersFactory == null) { + playerRenderersFactory = + (eventHandler, + videoRendererEventListener, + audioRendererEventListener, + textRendererOutput, + metadataRendererOutput) -> + renderers != null + ? renderers + : new Renderer[] { + new FakeVideoRenderer(eventHandler, videoRendererEventListener), + new FakeAudioRenderer(eventHandler, audioRendererEventListener) + }; + } + + return new SimpleExoPlayer.Builder(context, playerRenderersFactory) + .setTrackSelector(trackSelector) + .setLoadControl(loadControl) + .setBandwidthMeter(bandwidthMeter) + .setAnalyticsCollector(new AnalyticsCollector(clock)) + .setClock(clock) + .setUseLazyPreparation(useLazyPreparation) + .setLooper(looper) + .build(); + } + } + + private TestExoPlayer() {} + + /** + * Run tasks of the main {@link Looper} until the {@code player}'s state reaches the {@code + * expectedState}. + */ + public static void runUntilPlaybackState( + SimpleExoPlayer player, @Player.State int expectedState) { + verifyMainTestThread(player); + if (player.getPlaybackState() == expectedState) { + return; + } + + AtomicBoolean receivedExpectedState = new AtomicBoolean(false); + Player.EventListener listener = + new Player.EventListener() { + @Override + public void onPlaybackStateChanged(int state) { + if (state == expectedState) { + receivedExpectedState.set(true); + } + } + }; + player.addListener(listener); + runUntil(() -> receivedExpectedState.get()); + player.removeListener(listener); + } + + /** + * Run tasks of the main {@link Looper} until the {@code player} calls the {@link + * Player.EventListener#onPlaybackSpeedChanged} callback with that matches {@code + * expectedPlayWhenReady}. + */ + public static void runUntilPlayWhenReady(SimpleExoPlayer player, boolean expectedPlayWhenReady) { + verifyMainTestThread(player); + if (player.getPlayWhenReady() == expectedPlayWhenReady) { + return; + } + + AtomicBoolean receivedExpectedPlayWhenReady = new AtomicBoolean(false); + Player.EventListener listener = + new Player.EventListener() { + @Override + public void onPlayWhenReadyChanged(boolean playWhenReady, int reason) { + if (playWhenReady == expectedPlayWhenReady) { + receivedExpectedPlayWhenReady.set(true); + } + player.removeListener(this); + } + }; + player.addListener(listener); + runUntil(() -> receivedExpectedPlayWhenReady.get()); + } + + /** + * Run tasks of the main {@link Looper} until the {@code player} calls the {@link + * Player.EventListener#onTimelineChanged} callback. + * + * @param player The {@link SimpleExoPlayer}. + * @param expectedTimeline A specific {@link Timeline} to wait for, or null if any timeline is + * accepted. + * @return The received {@link Timeline}. + */ + public static Timeline runUntilTimelineChanged( + SimpleExoPlayer player, @Nullable Timeline expectedTimeline) { + verifyMainTestThread(player); + + if (expectedTimeline != null && expectedTimeline.equals(player.getCurrentTimeline())) { + return expectedTimeline; + } + + AtomicReference receivedTimeline = new AtomicReference<>(); + Player.EventListener listener = + new Player.EventListener() { + @Override + public void onTimelineChanged(Timeline timeline, int reason) { + if (expectedTimeline == null || expectedTimeline.equals(timeline)) { + receivedTimeline.set(timeline); + } + player.removeListener(this); + } + }; + player.addListener(listener); + runUntil(() -> receivedTimeline.get() != null); + return receivedTimeline.get(); + } + + /** + * Run tasks of the main {@link Looper} until the {@code player} calls the {@link + * Player.EventListener#onPositionDiscontinuity} callback with the specified {@link + * Player.DiscontinuityReason}. + */ + public static void runUntilPositionDiscontinuity( + SimpleExoPlayer player, @Player.DiscontinuityReason int expectedReason) { + AtomicBoolean receivedCallback = new AtomicBoolean(false); + Player.EventListener listener = + new Player.EventListener() { + @Override + public void onPositionDiscontinuity(int reason) { + if (reason == expectedReason) { + receivedCallback.set(true); + player.removeListener(this); + } + } + }; + player.addListener(listener); + runUntil(() -> receivedCallback.get()); + } + + /** + * Run tasks of the main {@link Looper} until the {@code player} calls the {@link + * Player.EventListener#onPlayerError} callback. + * + * @param player The {@link SimpleExoPlayer}. + * @return The raised error. + */ + public static ExoPlaybackException runUntilError(SimpleExoPlayer player) { + verifyMainTestThread(player); + AtomicReference receivedError = new AtomicReference<>(); + Player.EventListener listener = + new Player.EventListener() { + @Override + public void onPlayerError(ExoPlaybackException error) { + receivedError.set(error); + player.removeListener(this); + } + }; + player.addListener(listener); + runUntil(() -> receivedError.get() != null); + return receivedError.get(); + } + + /** + * Run tasks of the main {@link Looper} until the {@code player} calls the {@link + * com.google.android.exoplayer2.video.VideoRendererEventListener#onRenderedFirstFrame} callback. + */ + public static void runUntilRenderedFirstFrame(SimpleExoPlayer player) { + verifyMainTestThread(player); + AtomicBoolean receivedCallback = new AtomicBoolean(false); + VideoListener listener = + new VideoListener() { + @Override + public void onRenderedFirstFrame() { + receivedCallback.set(true); + player.removeVideoListener(this); + } + }; + player.addVideoListener(listener); + runUntil(() -> receivedCallback.get()); + } + + /** Run tasks of the main {@link Looper} until the {@code condition} returns {@code true}. */ + public static void runUntil(Supplier condition) { + verifyMainTestThread(); + + try { + while (!condition.get()) { + runOneTaskMethod.invoke(shadowLooper); + } + } catch (IllegalAccessException e) { + throw new IllegalStateException(e); + } catch (InvocationTargetException e) { + throw new IllegalStateException(e); + } + } + + private static void verifyMainTestThread(SimpleExoPlayer player) { + if (Looper.myLooper() != Looper.getMainLooper() + || player.getApplicationLooper() != Looper.getMainLooper()) { + throw new IllegalStateException(); + } + } + + private static void verifyMainTestThread() { + if (Looper.myLooper() != Looper.getMainLooper()) { + throw new IllegalStateException(); + } + } +}