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 ea3080a49e..bf8ce6aa6f 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 @@ -1715,7 +1715,7 @@ public final class ExoPlayerTest { throw ExoPlaybackException.createForSource(new IOException()); }) .send(); - runUntilPlaybackState(player, Player.STATE_IDLE); + TestPlayerRunHelper.runUntilError(player); player.seekTo(/* positionMs= */ 50); runUntilPendingCommandsAreFullyHandled(player); long positionAfterSeekHandled = player.getCurrentPosition(); @@ -9426,7 +9426,7 @@ public final class ExoPlayerTest { TestPlayerRunHelper.runUntilPlaybackState(player, Player.STATE_READY); player.play(); player.setMediaItem(MediaItem.fromUri("http://this-will-throw-an-exception.mp4")); - TestPlayerRunHelper.runUntilPlaybackState(player, Player.STATE_IDLE); + TestPlayerRunHelper.runUntilError(player); runUntilPendingCommandsAreFullyHandled(player); player.release(); 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 06e7d8445f..635b21f6f7 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 @@ -1662,7 +1662,7 @@ public final class AnalyticsCollectorTest { TestPlayerRunHelper.runUntilPositionDiscontinuity( player, Player.DISCONTINUITY_REASON_AUTO_TRANSITION); player.setMediaItem(MediaItem.fromUri("http://this-will-throw-an-exception.mp4")); - TestPlayerRunHelper.runUntilPlaybackState(player, Player.STATE_IDLE); + TestPlayerRunHelper.runUntilError(player); ShadowLooper.runMainLooperToNextTask(); player.release(); surface.release(); diff --git a/robolectricutils/src/main/java/com/google/android/exoplayer2/robolectric/TestPlayerRunHelper.java b/robolectricutils/src/main/java/com/google/android/exoplayer2/robolectric/TestPlayerRunHelper.java index 50ad8b475c..a58af6b55b 100644 --- a/robolectricutils/src/main/java/com/google/android/exoplayer2/robolectric/TestPlayerRunHelper.java +++ b/robolectricutils/src/main/java/com/google/android/exoplayer2/robolectric/TestPlayerRunHelper.java @@ -17,15 +17,14 @@ package com.google.android.exoplayer2.robolectric; import static com.google.android.exoplayer2.robolectric.RobolectricUtil.runMainLooperUntil; +import static com.google.android.exoplayer2.util.Assertions.checkNotNull; import android.os.Looper; import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlayer; -import com.google.android.exoplayer2.PlaybackException; import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.SimpleExoPlayer; import com.google.android.exoplayer2.Timeline; -import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.ConditionVariable; import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.video.VideoListener; @@ -44,7 +43,9 @@ public class TestPlayerRunHelper { /** * Runs tasks of the main {@link Looper} until {@link Player#getPlaybackState()} matches the - * expected state. + * expected state or a playback error occurs. + * + *
If a playback error occurs it will be thrown wrapped in an {@link IllegalStateException}. * * @param player The {@link Player}. * @param expectedState The expected {@link Player.State}. @@ -54,27 +55,18 @@ public class TestPlayerRunHelper { public static void runUntilPlaybackState(Player player, @Player.State int expectedState) throws TimeoutException { verifyMainTestThread(player); - if (player.getPlaybackState() == expectedState) { - return; + runMainLooperUntil( + () -> player.getPlaybackState() == expectedState || player.getPlayerError() != null); + if (player.getPlayerError() != null) { + throw new IllegalStateException(player.getPlayerError()); } - AtomicBoolean receivedExpectedState = new AtomicBoolean(false); - Player.Listener listener = - new Player.Listener() { - @Override - public void onPlaybackStateChanged(int state) { - if (state == expectedState) { - receivedExpectedState.set(true); - } - } - }; - player.addListener(listener); - runMainLooperUntil(receivedExpectedState::get); - player.removeListener(listener); } /** * Runs tasks of the main {@link Looper} until {@link Player#getPlayWhenReady()} matches the - * expected value. + * expected value or a playback error occurs. + * + *
If a playback error occurs it will be thrown wrapped in an {@link IllegalStateException}. * * @param player The {@link Player}. * @param expectedPlayWhenReady The expected value for {@link Player#getPlayWhenReady()}. @@ -84,27 +76,19 @@ public class TestPlayerRunHelper { public static void runUntilPlayWhenReady(Player player, boolean expectedPlayWhenReady) throws TimeoutException { verifyMainTestThread(player); - if (player.getPlayWhenReady() == expectedPlayWhenReady) { - return; + runMainLooperUntil( + () -> + player.getPlayWhenReady() == expectedPlayWhenReady || player.getPlayerError() != null); + if (player.getPlayerError() != null) { + throw new IllegalStateException(player.getPlayerError()); } - AtomicBoolean receivedExpectedPlayWhenReady = new AtomicBoolean(false); - Player.Listener listener = - new Player.Listener() { - @Override - public void onPlayWhenReadyChanged(boolean playWhenReady, int reason) { - if (playWhenReady == expectedPlayWhenReady) { - receivedExpectedPlayWhenReady.set(true); - } - player.removeListener(this); - } - }; - player.addListener(listener); - runMainLooperUntil(receivedExpectedPlayWhenReady::get); } /** * Runs tasks of the main {@link Looper} until {@link Player#getCurrentTimeline()} matches the - * expected timeline. + * expected timeline or a playback error occurs. + * + *
If a playback error occurs it will be thrown wrapped in an {@link IllegalStateException}. * * @param player The {@link Player}. * @param expectedTimeline The expected {@link Timeline}. @@ -114,26 +98,19 @@ public class TestPlayerRunHelper { public static void runUntilTimelineChanged(Player player, Timeline expectedTimeline) throws TimeoutException { verifyMainTestThread(player); - if (expectedTimeline.equals(player.getCurrentTimeline())) { - return; + runMainLooperUntil( + () -> + expectedTimeline.equals(player.getCurrentTimeline()) + || player.getPlayerError() != null); + if (player.getPlayerError() != null) { + throw new IllegalStateException(player.getPlayerError()); } - AtomicBoolean receivedExpectedTimeline = new AtomicBoolean(false); - Player.Listener listener = - new Player.Listener() { - @Override - public void onTimelineChanged(Timeline timeline, int reason) { - if (expectedTimeline.equals(timeline)) { - receivedExpectedTimeline.set(true); - } - player.removeListener(this); - } - }; - player.addListener(listener); - runMainLooperUntil(receivedExpectedTimeline::get); } /** - * Runs tasks of the main {@link Looper} until a timeline change occurred. + * Runs tasks of the main {@link Looper} until a timeline change or a playback error occurs. + * + *
If a playback error occurs it will be thrown wrapped in an {@link IllegalStateException}.
*
* @param player The {@link Player}.
* @return The new {@link Timeline}.
@@ -142,24 +119,29 @@ public class TestPlayerRunHelper {
*/
public static Timeline runUntilTimelineChanged(Player player) throws TimeoutException {
verifyMainTestThread(player);
- AtomicReference If a playback error occurs it will be thrown wrapped in an {@link IllegalStateException}.
*
* @param player The {@link Player}.
* @param expectedReason The expected {@link Player.DiscontinuityReason}.
@@ -177,16 +159,19 @@ public class TestPlayerRunHelper {
Player.PositionInfo oldPosition, Player.PositionInfo newPosition, int reason) {
if (reason == expectedReason) {
receivedCallback.set(true);
- player.removeListener(this);
}
}
};
player.addListener(listener);
- runMainLooperUntil(receivedCallback::get);
+ runMainLooperUntil(() -> receivedCallback.get() || player.getPlayerError() != null);
+ player.removeListener(listener);
+ if (player.getPlayerError() != null) {
+ throw new IllegalStateException(player.getPlayerError());
+ }
}
/**
- * Runs tasks of the main {@link Looper} until a player error occurred.
+ * Runs tasks of the main {@link Looper} until a player error occurs.
*
* @param player The {@link Player}.
* @return The raised {@link ExoPlaybackException}.
@@ -195,25 +180,16 @@ public class TestPlayerRunHelper {
*/
public static ExoPlaybackException runUntilError(ExoPlayer player) throws TimeoutException {
verifyMainTestThread(player);
- AtomicReference If a playback error occurs it will be thrown wrapped in an {@link IllegalStateException}.
*
* @param player The {@link Player}.
* @return The new offloadSchedulingEnabled state.
@@ -234,14 +210,21 @@ public class TestPlayerRunHelper {
}
};
player.addAudioOffloadListener(listener);
- runMainLooperUntil(() -> offloadSchedulingEnabledReceiver.get() != null);
- return Assertions.checkNotNull(offloadSchedulingEnabledReceiver.get());
+ runMainLooperUntil(
+ () -> offloadSchedulingEnabledReceiver.get() != null || player.getPlayerError() != null);
+ player.removeAudioOffloadListener(listener);
+ if (player.getPlayerError() != null) {
+ throw new IllegalStateException(player.getPlayerError());
+ }
+ return checkNotNull(offloadSchedulingEnabledReceiver.get());
}
/**
- * Runs tasks of the main {@link Looper} until a {@link
- * ExoPlayer.AudioOffloadListener#onExperimentalSleepingForOffloadChanged(boolean)} callback
- * occurred.
+ * Runs tasks of the main {@link Looper} until {@link
+ * ExoPlayer.AudioOffloadListener#onExperimentalSleepingForOffloadChanged(boolean)} is called or a
+ * playback error occurs.
+ *
+ * If a playback error occurs it will be thrown wrapped in an {@link IllegalStateException}.
*
* @param player The {@link Player}.
* @param expectedSleepForOffload The expected sleep of offload state.
@@ -262,12 +245,17 @@ public class TestPlayerRunHelper {
}
};
player.addAudioOffloadListener(listener);
- runMainLooperUntil(receiverCallback::get);
+ runMainLooperUntil(() -> receiverCallback.get() || player.getPlayerError() != null);
+ if (player.getPlayerError() != null) {
+ throw new IllegalStateException(player.getPlayerError());
+ }
}
/**
* Runs tasks of the main {@link Looper} until the {@link VideoListener#onRenderedFirstFrame}
- * callback has been called.
+ * callback is called or a playback error occurs.
+ *
+ * If a playback error occurs it will be thrown wrapped in an {@link IllegalStateException}..
*
* @param player The {@link Player}.
* @throws TimeoutException If the {@link RobolectricUtil#DEFAULT_TIMEOUT_MS default timeout} is
@@ -281,16 +269,21 @@ public class TestPlayerRunHelper {
@Override
public void onRenderedFirstFrame() {
receivedCallback.set(true);
- player.removeListener(this);
}
};
player.addListener(listener);
- runMainLooperUntil(receivedCallback::get);
+ runMainLooperUntil(() -> receivedCallback.get() || player.getPlayerError() != null);
+ player.removeListener(listener);
+ if (player.getPlayerError() != null) {
+ throw new IllegalStateException(player.getPlayerError());
+ }
}
/**
* 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}.
+ * reaches the specified position or a playback error occurs, and then pauses the {@code player}.
+ *
+ * If a playback error occurs it will be thrown wrapped in an {@link IllegalStateException}.
*
* @param player The {@link Player}.
* @param windowIndex The window.
@@ -327,12 +320,17 @@ public class TestPlayerRunHelper {
.setPosition(windowIndex, positionMs)
.send();
player.play();
- runMainLooperUntil(messageHandled::get);
+ runMainLooperUntil(() -> messageHandled.get() || player.getPlayerError() != null);
+ if (player.getPlayerError() != null) {
+ throw new IllegalStateException(player.getPlayerError());
+ }
}
/**
* 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}.
+ * reaches the specified window or a playback error occurs, and then pauses the {@code player}.
+ *
+ * If a playback error occurs it will be thrown wrapped in an {@link IllegalStateException}.
*
* @param player The {@link Player}.
* @param windowIndex The window.