Add Player.Listener.onPlayerErrorChanged
Equivalent to onPlayerError, except it's also called for null. PiperOrigin-RevId: 381015336
This commit is contained in:
parent
620ab67fee
commit
1a8592c5c0
@ -273,7 +273,9 @@ public final class ImaAdsLoaderTest {
|
||||
adEventListener.onAdEvent(getAdEvent(AdEventType.STARTED, mockPrerollSingleAd));
|
||||
videoAdPlayer.pauseAd(TEST_AD_MEDIA_INFO);
|
||||
videoAdPlayer.stopAd(TEST_AD_MEDIA_INFO);
|
||||
imaAdsLoader.onPlayerError(ExoPlaybackException.createForSource(new IOException()));
|
||||
ExoPlaybackException anException = ExoPlaybackException.createForSource(new IOException());
|
||||
imaAdsLoader.onPlayerErrorChanged(anException);
|
||||
imaAdsLoader.onPlayerError(anException);
|
||||
imaAdsLoader.onPositionDiscontinuity(
|
||||
new Player.PositionInfo(
|
||||
/* windowUid= */ new Object(),
|
||||
|
@ -685,6 +685,11 @@ public class ForwardingPlayer implements Player {
|
||||
eventListener.onPlayerError(error);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerErrorChanged(@Nullable PlaybackException error) {
|
||||
eventListener.onPlayerErrorChanged(error);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPositionDiscontinuity(@DiscontinuityReason int reason) {
|
||||
eventListener.onPositionDiscontinuity(reason);
|
||||
|
@ -274,6 +274,19 @@ public interface Player {
|
||||
*/
|
||||
default void onPlayerError(PlaybackException error) {}
|
||||
|
||||
/**
|
||||
* Called when the {@link PlaybackException} returned by {@link #getPlayerError()} changes.
|
||||
*
|
||||
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
|
||||
* other events that happen in the same {@link Looper} message queue iteration.
|
||||
*
|
||||
* <p>Implementations of Player may pass an instance of a subclass of {@link PlaybackException}
|
||||
* to this method in order to include more information about the error.
|
||||
*
|
||||
* @param error The new error, or null if the error is being cleared.
|
||||
*/
|
||||
default void onPlayerErrorChanged(@Nullable PlaybackException error) {}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #onPositionDiscontinuity(PositionInfo, PositionInfo, int)} instead.
|
||||
*/
|
||||
|
@ -1314,12 +1314,16 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
Player.EVENT_MEDIA_ITEM_TRANSITION,
|
||||
listener -> listener.onMediaItemTransition(finalMediaItem, mediaItemTransitionReason));
|
||||
}
|
||||
if (previousPlaybackInfo.playbackError != newPlaybackInfo.playbackError
|
||||
&& newPlaybackInfo.playbackError != null) {
|
||||
if (previousPlaybackInfo.playbackError != newPlaybackInfo.playbackError) {
|
||||
listeners.queueEvent(
|
||||
Player.EVENT_PLAYER_ERROR,
|
||||
listener -> listener.onPlayerErrorChanged(newPlaybackInfo.playbackError));
|
||||
if (newPlaybackInfo.playbackError != null) {
|
||||
listeners.queueEvent(
|
||||
Player.EVENT_PLAYER_ERROR,
|
||||
listener -> listener.onPlayerError(newPlaybackInfo.playbackError));
|
||||
}
|
||||
}
|
||||
if (previousPlaybackInfo.trackSelectorResult != newPlaybackInfo.trackSelectorResult) {
|
||||
trackSelector.onSelectionActivated(newPlaybackInfo.trackSelectorResult.info);
|
||||
TrackSelectionArray newSelection =
|
||||
|
@ -44,6 +44,7 @@ import static com.google.android.exoplayer2.Player.COMMAND_SET_VIDEO_SURFACE;
|
||||
import static com.google.android.exoplayer2.Player.COMMAND_SET_VOLUME;
|
||||
import static com.google.android.exoplayer2.Player.DEFAULT_FAST_FORWARD_INCREMENT_MS;
|
||||
import static com.google.android.exoplayer2.Player.DEFAULT_REWIND_INCREMENT_MS;
|
||||
import static com.google.android.exoplayer2.Player.STATE_ENDED;
|
||||
import static com.google.android.exoplayer2.robolectric.RobolectricUtil.runMainLooperUntil;
|
||||
import static com.google.android.exoplayer2.robolectric.TestPlayerRunHelper.playUntilPosition;
|
||||
import static com.google.android.exoplayer2.robolectric.TestPlayerRunHelper.playUntilStartOfWindow;
|
||||
@ -69,6 +70,7 @@ import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.robolectric.Shadows.shadowOf;
|
||||
@ -161,6 +163,7 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.ArgumentMatcher;
|
||||
import org.mockito.ArgumentMatchers;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mockito;
|
||||
import org.robolectric.shadows.ShadowAudioManager;
|
||||
@ -2855,6 +2858,38 @@ public final class ExoPlayerTest {
|
||||
assertThat(position[0]).isEqualTo(0L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPlayerErrorChanged_isNotifiedForNullError() throws Exception {
|
||||
ExoPlayer player = new TestExoPlayerBuilder(context).build();
|
||||
player.addMediaSource(
|
||||
new FakeMediaSource(/* timeline= */ null) {
|
||||
@Override
|
||||
public void maybeThrowSourceInfoRefreshError() throws IOException {
|
||||
throw new IOException();
|
||||
}
|
||||
});
|
||||
Player.Listener mockListener = mock(Player.Listener.class);
|
||||
player.addListener(mockListener);
|
||||
|
||||
player.prepare();
|
||||
player.play();
|
||||
ExoPlaybackException error = TestPlayerRunHelper.runUntilError(player);
|
||||
// The media source fails preparation, so we expect both methods to be called.
|
||||
verify(mockListener).onPlayerErrorChanged(error);
|
||||
verify(mockListener).onPlayerError(error);
|
||||
|
||||
reset(mockListener);
|
||||
|
||||
player.setMediaSource(new FakeMediaSource());
|
||||
player.prepare();
|
||||
player.play();
|
||||
TestPlayerRunHelper.runUntilPlaybackState(player, STATE_ENDED);
|
||||
// Now the player, which had a playback error, was re-prepared causing the error to be cleared.
|
||||
// We expect the change to null to be notified, but not onPlayerError.
|
||||
verify(mockListener).onPlayerErrorChanged(ArgumentMatchers.isNull());
|
||||
verify(mockListener, never()).onPlayerError(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void recursivePlayerChangesReportConsistentValuesForAllListeners() throws Exception {
|
||||
// We add two listeners to the player. The first stops the player as soon as it's ready and both
|
||||
@ -9408,6 +9443,7 @@ public final class ExoPlayerTest {
|
||||
verify(listener, atLeastOnce()).onStaticMetadataChanged(any());
|
||||
verify(listener, atLeastOnce()).onPlayWhenReadyChanged(anyBoolean(), anyInt());
|
||||
verify(listener, atLeastOnce()).onIsPlayingChanged(anyBoolean());
|
||||
verify(listener, atLeastOnce()).onPlayerErrorChanged(any());
|
||||
verify(listener, atLeastOnce()).onPlayerError(any());
|
||||
|
||||
// Verify all the same events have been recorded with onEvents.
|
||||
|
Loading…
x
Reference in New Issue
Block a user