Commit 29af6899 by tonihei Committed by Toni

Move playback error into PlaybackInfo.

The error is closely related to the playback state IDLE and should be updated
in sync with the state to prevent unexpected event ordering and/or keeping the
error after re-preparation.

Issue:#5407
PiperOrigin-RevId: 265014630
parent 7883eabb
...@@ -74,7 +74,6 @@ import java.util.concurrent.CopyOnWriteArrayList; ...@@ -74,7 +74,6 @@ import java.util.concurrent.CopyOnWriteArrayList;
private int pendingSetPlaybackParametersAcks; private int pendingSetPlaybackParametersAcks;
private PlaybackParameters playbackParameters; private PlaybackParameters playbackParameters;
private SeekParameters seekParameters; private SeekParameters seekParameters;
@Nullable private ExoPlaybackException playbackError;
// Playback information when there is no pending seek/set source operation. // Playback information when there is no pending seek/set source operation.
private PlaybackInfo playbackInfo; private PlaybackInfo playbackInfo;
...@@ -202,13 +201,12 @@ import java.util.concurrent.CopyOnWriteArrayList; ...@@ -202,13 +201,12 @@ import java.util.concurrent.CopyOnWriteArrayList;
@Override @Override
@Nullable @Nullable
public ExoPlaybackException getPlaybackError() { public ExoPlaybackException getPlaybackError() {
return playbackError; return playbackInfo.playbackError;
} }
@Override @Override
public void retry() { public void retry() {
if (mediaSource != null if (mediaSource != null && playbackInfo.playbackState == Player.STATE_IDLE) {
&& (playbackError != null || playbackInfo.playbackState == Player.STATE_IDLE)) {
prepare(mediaSource, /* resetPosition= */ false, /* resetState= */ false); prepare(mediaSource, /* resetPosition= */ false, /* resetState= */ false);
} }
} }
...@@ -220,11 +218,13 @@ import java.util.concurrent.CopyOnWriteArrayList; ...@@ -220,11 +218,13 @@ import java.util.concurrent.CopyOnWriteArrayList;
@Override @Override
public void prepare(MediaSource mediaSource, boolean resetPosition, boolean resetState) { public void prepare(MediaSource mediaSource, boolean resetPosition, boolean resetState) {
playbackError = null;
this.mediaSource = mediaSource; this.mediaSource = mediaSource;
PlaybackInfo playbackInfo = PlaybackInfo playbackInfo =
getResetPlaybackInfo( getResetPlaybackInfo(
resetPosition, resetState, /* playbackState= */ Player.STATE_BUFFERING); resetPosition,
resetState,
/* resetError= */ true,
/* playbackState= */ Player.STATE_BUFFERING);
// Trigger internal prepare first before updating the playback info and notifying external // Trigger internal prepare first before updating the playback info and notifying external
// listeners to ensure that new operations issued in the listener notifications reach the // listeners to ensure that new operations issued in the listener notifications reach the
// player after this prepare. The internal player can't change the playback info immediately // player after this prepare. The internal player can't change the playback info immediately
...@@ -381,13 +381,13 @@ import java.util.concurrent.CopyOnWriteArrayList; ...@@ -381,13 +381,13 @@ import java.util.concurrent.CopyOnWriteArrayList;
@Override @Override
public void stop(boolean reset) { public void stop(boolean reset) {
if (reset) { if (reset) {
playbackError = null;
mediaSource = null; mediaSource = null;
} }
PlaybackInfo playbackInfo = PlaybackInfo playbackInfo =
getResetPlaybackInfo( getResetPlaybackInfo(
/* resetPosition= */ reset, /* resetPosition= */ reset,
/* resetState= */ reset, /* resetState= */ reset,
/* resetError= */ reset,
/* playbackState= */ Player.STATE_IDLE); /* playbackState= */ Player.STATE_IDLE);
// Trigger internal stop first before updating the playback info and notifying external // Trigger internal stop first before updating the playback info and notifying external
// listeners to ensure that new operations issued in the listener notifications reach the // listeners to ensure that new operations issued in the listener notifications reach the
...@@ -415,6 +415,7 @@ import java.util.concurrent.CopyOnWriteArrayList; ...@@ -415,6 +415,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
getResetPlaybackInfo( getResetPlaybackInfo(
/* resetPosition= */ false, /* resetPosition= */ false,
/* resetState= */ false, /* resetState= */ false,
/* resetError= */ false,
/* playbackState= */ Player.STATE_IDLE); /* playbackState= */ Player.STATE_IDLE);
} }
...@@ -572,11 +573,6 @@ import java.util.concurrent.CopyOnWriteArrayList; ...@@ -572,11 +573,6 @@ import java.util.concurrent.CopyOnWriteArrayList;
case ExoPlayerImplInternal.MSG_PLAYBACK_PARAMETERS_CHANGED: case ExoPlayerImplInternal.MSG_PLAYBACK_PARAMETERS_CHANGED:
handlePlaybackParameters((PlaybackParameters) msg.obj, /* operationAck= */ msg.arg1 != 0); handlePlaybackParameters((PlaybackParameters) msg.obj, /* operationAck= */ msg.arg1 != 0);
break; break;
case ExoPlayerImplInternal.MSG_ERROR:
ExoPlaybackException playbackError = (ExoPlaybackException) msg.obj;
this.playbackError = playbackError;
notifyListeners(listener -> listener.onPlayerError(playbackError));
break;
default: default:
throw new IllegalStateException(); throw new IllegalStateException();
} }
...@@ -635,7 +631,10 @@ import java.util.concurrent.CopyOnWriteArrayList; ...@@ -635,7 +631,10 @@ import java.util.concurrent.CopyOnWriteArrayList;
} }
private PlaybackInfo getResetPlaybackInfo( private PlaybackInfo getResetPlaybackInfo(
boolean resetPosition, boolean resetState, @Player.State int playbackState) { boolean resetPosition,
boolean resetState,
boolean resetError,
@Player.State int playbackState) {
if (resetPosition) { if (resetPosition) {
maskingWindowIndex = 0; maskingWindowIndex = 0;
maskingPeriodIndex = 0; maskingPeriodIndex = 0;
...@@ -659,6 +658,7 @@ import java.util.concurrent.CopyOnWriteArrayList; ...@@ -659,6 +658,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
startPositionUs, startPositionUs,
contentPositionUs, contentPositionUs,
playbackState, playbackState,
resetError ? null : playbackInfo.playbackError,
/* isLoading= */ false, /* isLoading= */ false,
resetState ? TrackGroupArray.EMPTY : playbackInfo.trackGroups, resetState ? TrackGroupArray.EMPTY : playbackInfo.trackGroups,
resetState ? emptyTrackSelectorResult : playbackInfo.trackSelectorResult, resetState ? emptyTrackSelectorResult : playbackInfo.trackSelectorResult,
...@@ -728,6 +728,7 @@ import java.util.concurrent.CopyOnWriteArrayList; ...@@ -728,6 +728,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
private final @Player.TimelineChangeReason int timelineChangeReason; private final @Player.TimelineChangeReason int timelineChangeReason;
private final boolean seekProcessed; private final boolean seekProcessed;
private final boolean playbackStateChanged; private final boolean playbackStateChanged;
private final boolean playbackErrorChanged;
private final boolean timelineChanged; private final boolean timelineChanged;
private final boolean isLoadingChanged; private final boolean isLoadingChanged;
private final boolean trackSelectorResultChanged; private final boolean trackSelectorResultChanged;
...@@ -752,6 +753,9 @@ import java.util.concurrent.CopyOnWriteArrayList; ...@@ -752,6 +753,9 @@ import java.util.concurrent.CopyOnWriteArrayList;
this.seekProcessed = seekProcessed; this.seekProcessed = seekProcessed;
this.playWhenReady = playWhenReady; this.playWhenReady = playWhenReady;
playbackStateChanged = previousPlaybackInfo.playbackState != playbackInfo.playbackState; playbackStateChanged = previousPlaybackInfo.playbackState != playbackInfo.playbackState;
playbackErrorChanged =
previousPlaybackInfo.playbackError != playbackInfo.playbackError
&& playbackInfo.playbackError != null;
timelineChanged = previousPlaybackInfo.timeline != playbackInfo.timeline; timelineChanged = previousPlaybackInfo.timeline != playbackInfo.timeline;
isLoadingChanged = previousPlaybackInfo.isLoading != playbackInfo.isLoading; isLoadingChanged = previousPlaybackInfo.isLoading != playbackInfo.isLoading;
trackSelectorResultChanged = trackSelectorResultChanged =
...@@ -770,6 +774,9 @@ import java.util.concurrent.CopyOnWriteArrayList; ...@@ -770,6 +774,9 @@ import java.util.concurrent.CopyOnWriteArrayList;
listenerSnapshot, listenerSnapshot,
listener -> listener.onPositionDiscontinuity(positionDiscontinuityReason)); listener -> listener.onPositionDiscontinuity(positionDiscontinuityReason));
} }
if (playbackErrorChanged) {
invokeAll(listenerSnapshot, listener -> listener.onPlayerError(playbackInfo.playbackError));
}
if (trackSelectorResultChanged) { if (trackSelectorResultChanged) {
trackSelector.onSelectionActivated(playbackInfo.trackSelectorResult.info); trackSelector.onSelectionActivated(playbackInfo.trackSelectorResult.info);
invokeAll( invokeAll(
......
...@@ -61,7 +61,6 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -61,7 +61,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
// External messages // External messages
public static final int MSG_PLAYBACK_INFO_CHANGED = 0; public static final int MSG_PLAYBACK_INFO_CHANGED = 0;
public static final int MSG_PLAYBACK_PARAMETERS_CHANGED = 1; public static final int MSG_PLAYBACK_PARAMETERS_CHANGED = 1;
public static final int MSG_ERROR = 2;
// Internal messages // Internal messages
private static final int MSG_PREPARE = 0; private static final int MSG_PREPARE = 0;
...@@ -374,19 +373,19 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -374,19 +373,19 @@ import java.util.concurrent.atomic.AtomicBoolean;
maybeNotifyPlaybackInfoChanged(); maybeNotifyPlaybackInfoChanged();
} catch (ExoPlaybackException e) { } catch (ExoPlaybackException e) {
Log.e(TAG, "Playback error.", e); Log.e(TAG, "Playback error.", e);
eventHandler.obtainMessage(MSG_ERROR, e).sendToTarget();
stopInternal( stopInternal(
/* forceResetRenderers= */ true, /* forceResetRenderers= */ true,
/* resetPositionAndState= */ false, /* resetPositionAndState= */ false,
/* acknowledgeStop= */ false); /* acknowledgeStop= */ false);
playbackInfo = playbackInfo.copyWithPlaybackError(e);
maybeNotifyPlaybackInfoChanged(); maybeNotifyPlaybackInfoChanged();
} catch (IOException e) { } catch (IOException e) {
Log.e(TAG, "Source error.", e); Log.e(TAG, "Source error.", e);
eventHandler.obtainMessage(MSG_ERROR, ExoPlaybackException.createForSource(e)).sendToTarget();
stopInternal( stopInternal(
/* forceResetRenderers= */ false, /* forceResetRenderers= */ false,
/* resetPositionAndState= */ false, /* resetPositionAndState= */ false,
/* acknowledgeStop= */ false); /* acknowledgeStop= */ false);
playbackInfo = playbackInfo.copyWithPlaybackError(ExoPlaybackException.createForSource(e));
maybeNotifyPlaybackInfoChanged(); maybeNotifyPlaybackInfoChanged();
} catch (RuntimeException | OutOfMemoryError e) { } catch (RuntimeException | OutOfMemoryError e) {
Log.e(TAG, "Internal runtime error.", e); Log.e(TAG, "Internal runtime error.", e);
...@@ -394,11 +393,11 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -394,11 +393,11 @@ import java.util.concurrent.atomic.AtomicBoolean;
e instanceof OutOfMemoryError e instanceof OutOfMemoryError
? ExoPlaybackException.createForOutOfMemoryError((OutOfMemoryError) e) ? ExoPlaybackException.createForOutOfMemoryError((OutOfMemoryError) e)
: ExoPlaybackException.createForUnexpected((RuntimeException) e); : ExoPlaybackException.createForUnexpected((RuntimeException) e);
eventHandler.obtainMessage(MSG_ERROR, error).sendToTarget();
stopInternal( stopInternal(
/* forceResetRenderers= */ true, /* forceResetRenderers= */ true,
/* resetPositionAndState= */ false, /* resetPositionAndState= */ false,
/* acknowledgeStop= */ false); /* acknowledgeStop= */ false);
playbackInfo = playbackInfo.copyWithPlaybackError(error);
maybeNotifyPlaybackInfoChanged(); maybeNotifyPlaybackInfoChanged();
} }
return true; return true;
...@@ -436,7 +435,11 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -436,7 +435,11 @@ import java.util.concurrent.atomic.AtomicBoolean;
private void prepareInternal(MediaSource mediaSource, boolean resetPosition, boolean resetState) { private void prepareInternal(MediaSource mediaSource, boolean resetPosition, boolean resetState) {
pendingPrepareCount++; pendingPrepareCount++;
resetInternal( resetInternal(
/* resetRenderers= */ false, /* releaseMediaSource= */ true, resetPosition, resetState); /* resetRenderers= */ false,
/* releaseMediaSource= */ true,
resetPosition,
resetState,
/* resetError= */ true);
loadControl.onPrepared(); loadControl.onPrepared();
this.mediaSource = mediaSource; this.mediaSource = mediaSource;
setState(Player.STATE_BUFFERING); setState(Player.STATE_BUFFERING);
...@@ -688,7 +691,8 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -688,7 +691,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
/* resetRenderers= */ false, /* resetRenderers= */ false,
/* releaseMediaSource= */ false, /* releaseMediaSource= */ false,
/* resetPosition= */ true, /* resetPosition= */ true,
/* resetState= */ false); /* resetState= */ false,
/* resetError= */ true);
} else { } else {
// Execute the seek in the current media periods. // Execute the seek in the current media periods.
long newPeriodPositionUs = periodPositionUs; long newPeriodPositionUs = periodPositionUs;
...@@ -834,7 +838,8 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -834,7 +838,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
/* resetRenderers= */ forceResetRenderers || !foregroundMode, /* resetRenderers= */ forceResetRenderers || !foregroundMode,
/* releaseMediaSource= */ true, /* releaseMediaSource= */ true,
/* resetPosition= */ resetPositionAndState, /* resetPosition= */ resetPositionAndState,
/* resetState= */ resetPositionAndState); /* resetState= */ resetPositionAndState,
/* resetError= */ resetPositionAndState);
playbackInfoUpdate.incrementPendingOperationAcks( playbackInfoUpdate.incrementPendingOperationAcks(
pendingPrepareCount + (acknowledgeStop ? 1 : 0)); pendingPrepareCount + (acknowledgeStop ? 1 : 0));
pendingPrepareCount = 0; pendingPrepareCount = 0;
...@@ -847,7 +852,8 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -847,7 +852,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
/* resetRenderers= */ true, /* resetRenderers= */ true,
/* releaseMediaSource= */ true, /* releaseMediaSource= */ true,
/* resetPosition= */ true, /* resetPosition= */ true,
/* resetState= */ true); /* resetState= */ true,
/* resetError= */ false);
loadControl.onReleased(); loadControl.onReleased();
setState(Player.STATE_IDLE); setState(Player.STATE_IDLE);
internalPlaybackThread.quit(); internalPlaybackThread.quit();
...@@ -861,7 +867,8 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -861,7 +867,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
boolean resetRenderers, boolean resetRenderers,
boolean releaseMediaSource, boolean releaseMediaSource,
boolean resetPosition, boolean resetPosition,
boolean resetState) { boolean resetState,
boolean resetError) {
handler.removeMessages(MSG_DO_SOME_WORK); handler.removeMessages(MSG_DO_SOME_WORK);
rebuffering = false; rebuffering = false;
mediaClock.stop(); mediaClock.stop();
...@@ -924,6 +931,7 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -924,6 +931,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
startPositionUs, startPositionUs,
contentPositionUs, contentPositionUs,
playbackInfo.playbackState, playbackInfo.playbackState,
resetError ? null : playbackInfo.playbackError,
/* isLoading= */ false, /* isLoading= */ false,
resetState ? TrackGroupArray.EMPTY : playbackInfo.trackGroups, resetState ? TrackGroupArray.EMPTY : playbackInfo.trackGroups,
resetState ? emptyTrackSelectorResult : playbackInfo.trackSelectorResult, resetState ? emptyTrackSelectorResult : playbackInfo.trackSelectorResult,
...@@ -1382,7 +1390,8 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -1382,7 +1390,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
/* resetRenderers= */ false, /* resetRenderers= */ false,
/* releaseMediaSource= */ false, /* releaseMediaSource= */ false,
/* resetPosition= */ true, /* resetPosition= */ true,
/* resetState= */ false); /* resetState= */ false,
/* resetError= */ true);
} }
/** /**
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
package com.google.android.exoplayer2; package com.google.android.exoplayer2;
import androidx.annotation.CheckResult; import androidx.annotation.CheckResult;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId; import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.TrackSelectorResult; import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
...@@ -51,6 +52,8 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; ...@@ -51,6 +52,8 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
public final long contentPositionUs; public final long contentPositionUs;
/** The current playback state. One of the {@link Player}.STATE_ constants. */ /** The current playback state. One of the {@link Player}.STATE_ constants. */
@Player.State public final int playbackState; @Player.State public final int playbackState;
/** The current playback error, or null if this is not an error state. */
@Nullable public final ExoPlaybackException playbackError;
/** Whether the player is currently loading. */ /** Whether the player is currently loading. */
public final boolean isLoading; public final boolean isLoading;
/** The currently available track groups. */ /** The currently available track groups. */
...@@ -93,6 +96,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; ...@@ -93,6 +96,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
startPositionUs, startPositionUs,
/* contentPositionUs= */ C.TIME_UNSET, /* contentPositionUs= */ C.TIME_UNSET,
Player.STATE_IDLE, Player.STATE_IDLE,
/* playbackError= */ null,
/* isLoading= */ false, /* isLoading= */ false,
TrackGroupArray.EMPTY, TrackGroupArray.EMPTY,
emptyTrackSelectorResult, emptyTrackSelectorResult,
...@@ -124,6 +128,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; ...@@ -124,6 +128,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
long startPositionUs, long startPositionUs,
long contentPositionUs, long contentPositionUs,
@Player.State int playbackState, @Player.State int playbackState,
@Nullable ExoPlaybackException playbackError,
boolean isLoading, boolean isLoading,
TrackGroupArray trackGroups, TrackGroupArray trackGroups,
TrackSelectorResult trackSelectorResult, TrackSelectorResult trackSelectorResult,
...@@ -136,6 +141,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; ...@@ -136,6 +141,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
this.startPositionUs = startPositionUs; this.startPositionUs = startPositionUs;
this.contentPositionUs = contentPositionUs; this.contentPositionUs = contentPositionUs;
this.playbackState = playbackState; this.playbackState = playbackState;
this.playbackError = playbackError;
this.isLoading = isLoading; this.isLoading = isLoading;
this.trackGroups = trackGroups; this.trackGroups = trackGroups;
this.trackSelectorResult = trackSelectorResult; this.trackSelectorResult = trackSelectorResult;
...@@ -194,6 +200,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; ...@@ -194,6 +200,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
positionUs, positionUs,
periodId.isAd() ? contentPositionUs : C.TIME_UNSET, periodId.isAd() ? contentPositionUs : C.TIME_UNSET,
playbackState, playbackState,
playbackError,
isLoading, isLoading,
trackGroups, trackGroups,
trackSelectorResult, trackSelectorResult,
...@@ -217,6 +224,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; ...@@ -217,6 +224,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
startPositionUs, startPositionUs,
contentPositionUs, contentPositionUs,
playbackState, playbackState,
playbackError,
isLoading, isLoading,
trackGroups, trackGroups,
trackSelectorResult, trackSelectorResult,
...@@ -240,6 +248,31 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; ...@@ -240,6 +248,31 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
startPositionUs, startPositionUs,
contentPositionUs, contentPositionUs,
playbackState, playbackState,
playbackError,
isLoading,
trackGroups,
trackSelectorResult,
loadingMediaPeriodId,
bufferedPositionUs,
totalBufferedDurationUs,
positionUs);
}
/**
* Copies playback info with a playback error.
*
* @param playbackError The error. See {@link #playbackError}.
* @return Copied playback info with the playback error.
*/
@CheckResult
public PlaybackInfo copyWithPlaybackError(@Nullable ExoPlaybackException playbackError) {
return new PlaybackInfo(
timeline,
periodId,
startPositionUs,
contentPositionUs,
playbackState,
playbackError,
isLoading, isLoading,
trackGroups, trackGroups,
trackSelectorResult, trackSelectorResult,
...@@ -263,6 +296,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; ...@@ -263,6 +296,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
startPositionUs, startPositionUs,
contentPositionUs, contentPositionUs,
playbackState, playbackState,
playbackError,
isLoading, isLoading,
trackGroups, trackGroups,
trackSelectorResult, trackSelectorResult,
...@@ -288,6 +322,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; ...@@ -288,6 +322,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
startPositionUs, startPositionUs,
contentPositionUs, contentPositionUs,
playbackState, playbackState,
playbackError,
isLoading, isLoading,
trackGroups, trackGroups,
trackSelectorResult, trackSelectorResult,
...@@ -311,6 +346,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; ...@@ -311,6 +346,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
startPositionUs, startPositionUs,
contentPositionUs, contentPositionUs,
playbackState, playbackState,
playbackError,
isLoading, isLoading,
trackGroups, trackGroups,
trackSelectorResult, trackSelectorResult,
......
...@@ -465,10 +465,7 @@ public class AnalyticsCollector ...@@ -465,10 +465,7 @@ public class AnalyticsCollector
@Override @Override
public final void onPlayerError(ExoPlaybackException error) { public final void onPlayerError(ExoPlaybackException error) {
EventTime eventTime = EventTime eventTime = generateLastReportedPlayingMediaPeriodEventTime();
error.type == ExoPlaybackException.TYPE_SOURCE
? generateLoadingMediaPeriodEventTime()
: generatePlayingMediaPeriodEventTime();
for (AnalyticsListener listener : listeners) { for (AnalyticsListener listener : listeners) {
listener.onPlayerError(eventTime, error); listener.onPlayerError(eventTime, error);
} }
......
...@@ -359,6 +359,7 @@ public final class MediaPeriodQueueTest { ...@@ -359,6 +359,7 @@ public final class MediaPeriodQueueTest {
/* startPositionUs= */ 0, /* startPositionUs= */ 0,
/* contentPositionUs= */ 0, /* contentPositionUs= */ 0,
Player.STATE_READY, Player.STATE_READY,
/* playbackError= */ null,
/* isLoading= */ false, /* isLoading= */ false,
/* trackGroups= */ null, /* trackGroups= */ null,
/* trackSelectorResult= */ null, /* trackSelectorResult= */ null,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment