Migrate test repeatModeChanges() to TestExoPlayer

PiperOrigin-RevId: 328918314
This commit is contained in:
christosts 2020-08-28 12:45:45 +01:00 committed by Oliver Woodman
parent 0045d20d2c
commit 3dbb4c4da9
2 changed files with 94 additions and 43 deletions

View File

@ -17,6 +17,7 @@ package com.google.android.exoplayer2;
import static com.google.android.exoplayer2.testutil.FakeSampleStream.FakeSampleStreamItem.END_OF_STREAM_ITEM; import static com.google.android.exoplayer2.testutil.FakeSampleStream.FakeSampleStreamItem.END_OF_STREAM_ITEM;
import static com.google.android.exoplayer2.testutil.FakeSampleStream.FakeSampleStreamItem.oneByteSample; import static com.google.android.exoplayer2.testutil.FakeSampleStream.FakeSampleStreamItem.oneByteSample;
import static com.google.android.exoplayer2.testutil.TestExoPlayer.playUntilStartOfWindow;
import static com.google.android.exoplayer2.testutil.TestExoPlayer.runUntilPlaybackState; import static com.google.android.exoplayer2.testutil.TestExoPlayer.runUntilPlaybackState;
import static com.google.android.exoplayer2.testutil.TestExoPlayer.runUntilTimelineChanged; import static com.google.android.exoplayer2.testutil.TestExoPlayer.runUntilTimelineChanged;
import static com.google.android.exoplayer2.testutil.TestUtil.runMainLooperUntil; import static com.google.android.exoplayer2.testutil.TestUtil.runMainLooperUntil;
@ -114,9 +115,11 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatcher; import org.mockito.ArgumentMatcher;
import org.mockito.InOrder; import org.mockito.InOrder;
import org.mockito.Mockito; import org.mockito.Mockito;
@ -439,49 +442,41 @@ public final class ExoPlayerTest {
public void repeatModeChanges() throws Exception { public void repeatModeChanges() throws Exception {
Timeline timeline = new FakeTimeline(/* windowCount= */ 3); Timeline timeline = new FakeTimeline(/* windowCount= */ 3);
FakeRenderer renderer = new FakeRenderer(C.TRACK_TYPE_VIDEO); FakeRenderer renderer = new FakeRenderer(C.TRACK_TYPE_VIDEO);
ActionSchedule actionSchedule = SimpleExoPlayer player = new TestExoPlayer.Builder(context).setRenderers(renderer).build();
new ActionSchedule.Builder(TAG) AnalyticsListener mockAnalyticsListener = mock(AnalyticsListener.class);
.pause() player.addAnalyticsListener(mockAnalyticsListener);
.waitForTimelineChanged(
timeline, /* expectedReason */ Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE) player.setMediaSource(new FakeMediaSource(timeline, ExoPlayerTestRunner.VIDEO_FORMAT));
.playUntilStartOfWindow(/* windowIndex= */ 1) player.prepare();
.setRepeatMode(Player.REPEAT_MODE_ONE) runUntilTimelineChanged(player);
.playUntilStartOfWindow(/* windowIndex= */ 1) playUntilStartOfWindow(player, /* windowIndex= */ 1);
.setRepeatMode(Player.REPEAT_MODE_OFF) player.setRepeatMode(Player.REPEAT_MODE_ONE);
.playUntilStartOfWindow(/* windowIndex= */ 2) playUntilStartOfWindow(player, /* windowIndex= */ 1);
.setRepeatMode(Player.REPEAT_MODE_ONE) player.setRepeatMode(Player.REPEAT_MODE_OFF);
.playUntilStartOfWindow(/* windowIndex= */ 2) playUntilStartOfWindow(player, /* windowIndex= */ 2);
.setRepeatMode(Player.REPEAT_MODE_ALL) player.setRepeatMode(Player.REPEAT_MODE_ONE);
.playUntilStartOfWindow(/* windowIndex= */ 0) playUntilStartOfWindow(player, /* windowIndex= */ 2);
.setRepeatMode(Player.REPEAT_MODE_ONE) player.setRepeatMode(Player.REPEAT_MODE_ALL);
.playUntilStartOfWindow(/* windowIndex= */ 0) playUntilStartOfWindow(player, /* windowIndex= */ 0);
.playUntilStartOfWindow(/* windowIndex= */ 0) player.setRepeatMode(Player.REPEAT_MODE_ONE);
.setRepeatMode(Player.REPEAT_MODE_OFF) playUntilStartOfWindow(player, /* windowIndex= */ 0);
.play() playUntilStartOfWindow(player, /* windowIndex= */ 0);
.build(); player.setRepeatMode(Player.REPEAT_MODE_OFF);
ExoPlayerTestRunner testRunner = playUntilStartOfWindow(player, /* windowIndex= */ 1);
new ExoPlayerTestRunner.Builder(context) playUntilStartOfWindow(player, /* windowIndex= */ 2);
.setTimeline(timeline) player.play();
.setRenderers(renderer) runUntilPlaybackState(player, Player.STATE_ENDED);
.setActionSchedule(actionSchedule)
.build() ArgumentCaptor<AnalyticsListener.EventTime> eventTimes =
.start() ArgumentCaptor.forClass(AnalyticsListener.EventTime.class);
.blockUntilEnded(TIMEOUT_MS); verify(mockAnalyticsListener, times(10))
testRunner.assertPlayedPeriodIndices(0, 1, 1, 2, 2, 0, 0, 0, 1, 2); .onMediaItemTransition(eventTimes.capture(), any(), anyInt());
testRunner.assertPositionDiscontinuityReasonsEqual( assertThat(
Player.DISCONTINUITY_REASON_PERIOD_TRANSITION, eventTimes.getAllValues().stream()
Player.DISCONTINUITY_REASON_PERIOD_TRANSITION, .map(eventTime -> eventTime.currentWindowIndex)
Player.DISCONTINUITY_REASON_PERIOD_TRANSITION, .collect(Collectors.toList()))
Player.DISCONTINUITY_REASON_PERIOD_TRANSITION, .containsExactly(0, 1, 1, 2, 2, 0, 0, 0, 1, 2)
Player.DISCONTINUITY_REASON_PERIOD_TRANSITION, .inOrder();
Player.DISCONTINUITY_REASON_PERIOD_TRANSITION,
Player.DISCONTINUITY_REASON_PERIOD_TRANSITION,
Player.DISCONTINUITY_REASON_PERIOD_TRANSITION,
Player.DISCONTINUITY_REASON_PERIOD_TRANSITION);
testRunner.assertTimelinesSame(new FakeMediaSource.InitialTimeline(timeline), timeline);
testRunner.assertTimelineChangeReasonsEqual(
Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED,
Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE);
assertThat(renderer.isEnded).isTrue(); assertThat(renderer.isEnded).isTrue();
} }

View File

@ -20,6 +20,7 @@ import static com.google.android.exoplayer2.testutil.TestUtil.runMainLooperUntil
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import android.content.Context; import android.content.Context;
import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.DefaultLoadControl; import com.google.android.exoplayer2.DefaultLoadControl;
@ -37,6 +38,7 @@ import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter; import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Clock; import com.google.android.exoplayer2.util.Clock;
import com.google.android.exoplayer2.util.ConditionVariable;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.video.VideoListener; import com.google.android.exoplayer2.video.VideoListener;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
@ -396,6 +398,7 @@ public class TestExoPlayer {
*/ */
public static void runUntilPositionDiscontinuity( public static void runUntilPositionDiscontinuity(
Player player, @Player.DiscontinuityReason int expectedReason) throws TimeoutException { Player player, @Player.DiscontinuityReason int expectedReason) throws TimeoutException {
verifyMainTestThread(player);
AtomicBoolean receivedCallback = new AtomicBoolean(false); AtomicBoolean receivedCallback = new AtomicBoolean(false);
Player.EventListener listener = Player.EventListener listener =
new Player.EventListener() { new Player.EventListener() {
@ -458,6 +461,59 @@ public class TestExoPlayer {
runMainLooperUntil(receivedCallback::get); runMainLooperUntil(receivedCallback::get);
} }
/**
* Calls {@link Player#play()}, runs tasks of the main {@link Looper} until the {@code player}
* reaches the specified position and then pauses the {@code player}.
*
* @param player The {@link Player}.
* @param windowIndex The window.
* @param positionMs The position within the window, in milliseconds.
* @throws TimeoutException If the {@link TestUtil#DEFAULT_TIMEOUT_MS default timeout} is
* exceeded.
*/
public static void playUntilPosition(ExoPlayer player, int windowIndex, long positionMs)
throws TimeoutException {
verifyMainTestThread(player);
Handler testHandler = Util.createHandlerForCurrentOrMainLooper();
AtomicBoolean messageHandled = new AtomicBoolean();
player
.createMessage(
(messageType, payload) -> {
// Block playback thread until pause command has been sent from test thread.
ConditionVariable blockPlaybackThreadCondition = new ConditionVariable();
testHandler.post(
() -> {
player.pause();
messageHandled.set(true);
blockPlaybackThreadCondition.open();
});
try {
blockPlaybackThreadCondition.block();
} catch (InterruptedException e) {
// Ignore.
}
})
.setPosition(windowIndex, positionMs)
.send();
player.play();
runMainLooperUntil(messageHandled::get);
}
/**
* Calls {@link Player#play()}, runs tasks of the main {@link Looper} until the {@code player}
* reaches the specified window and then pauses the {@code player}.
*
* @param player The {@link Player}.
* @param windowIndex The window.
* @throws TimeoutException If the {@link TestUtil#DEFAULT_TIMEOUT_MS default timeout} is
* exceeded.
*/
public static void playUntilStartOfWindow(ExoPlayer player, int windowIndex)
throws TimeoutException {
playUntilPosition(player, windowIndex, /* positionMs= */ 0);
}
/** /**
* Runs tasks of the main {@link Looper} until the player completely handled all previously issued * Runs tasks of the main {@link Looper} until the player completely handled all previously issued
* commands on the internal playback thread. * commands on the internal playback thread.