Commit a0460c3b by tonihei Committed by Oliver Woodman

Remove ExoPlaybackException.TYPE_TIMEOUT.

The ExoPlaybackException types are locations from where the exception
is coming from and not the type of exception itself, which should be
denoted by different exception classes.

To avoid a mixture of error types and class checks, the timeout
exceptions should use their own class and be of type RENDERER as this
is where the timeout actually happens.

PiperOrigin-RevId: 351337699
parent d640ceda
...@@ -27,19 +27,18 @@ import java.io.IOException; ...@@ -27,19 +27,18 @@ import java.io.IOException;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.util.concurrent.TimeoutException;
/** Thrown when a non locally recoverable playback failure occurs. */ /** Thrown when a non locally recoverable playback failure occurs. */
public final class ExoPlaybackException extends Exception { public final class ExoPlaybackException extends Exception {
/** /**
* The type of source that produced the error. One of {@link #TYPE_SOURCE}, {@link #TYPE_RENDERER} * The type of source that produced the error. One of {@link #TYPE_SOURCE}, {@link #TYPE_RENDERER}
* {@link #TYPE_UNEXPECTED}, {@link #TYPE_REMOTE} or {@link #TYPE_TIMEOUT}. Note that new types * {@link #TYPE_UNEXPECTED} or {@link #TYPE_REMOTE}. Note that new types may be added in the
* may be added in the future and error handling should handle unknown type values. * future and error handling should handle unknown type values.
*/ */
@Documented @Documented
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@IntDef({TYPE_SOURCE, TYPE_RENDERER, TYPE_UNEXPECTED, TYPE_REMOTE, TYPE_TIMEOUT}) @IntDef({TYPE_SOURCE, TYPE_RENDERER, TYPE_UNEXPECTED, TYPE_REMOTE})
public @interface Type {} public @interface Type {}
/** /**
* The error occurred loading data from a {@code MediaSource}. * The error occurred loading data from a {@code MediaSource}.
...@@ -68,43 +67,19 @@ public final class ExoPlaybackException extends Exception { ...@@ -68,43 +67,19 @@ public final class ExoPlaybackException extends Exception {
*/ */
public static final int TYPE_REMOTE = 3; public static final int TYPE_REMOTE = 3;
/** The error was a {@link TimeoutException}. */
public static final int TYPE_TIMEOUT = 4;
/** The {@link Type} of the playback failure. */ /** The {@link Type} of the playback failure. */
@Type public final int type; @Type public final int type;
/** /**
* The operation which produced the timeout error. One of {@link #TIMEOUT_OPERATION_RELEASE}, * If {@link #type} is {@link #TYPE_RENDERER}, this is the name of the renderer, or null if
* {@link #TIMEOUT_OPERATION_SET_FOREGROUND_MODE}, {@link #TIMEOUT_OPERATION_DETACH_SURFACE} or * unknown.
* {@link #TIMEOUT_OPERATION_UNDEFINED}. Note that new operations may be added in the future and
* error handling should handle unknown operation values.
*/ */
@Documented
@Retention(RetentionPolicy.SOURCE)
@IntDef({
TIMEOUT_OPERATION_UNDEFINED,
TIMEOUT_OPERATION_RELEASE,
TIMEOUT_OPERATION_SET_FOREGROUND_MODE,
TIMEOUT_OPERATION_DETACH_SURFACE
})
public @interface TimeoutOperation {}
/** The operation where this error occurred is not defined. */
public static final int TIMEOUT_OPERATION_UNDEFINED = 0;
// TODO(b/172315872) Change back @code to @link when the Player is in common.
/** The error occurred in {@code Player#release}. */
public static final int TIMEOUT_OPERATION_RELEASE = 1;
/** The error occurred in {@code ExoPlayer#setForegroundMode}. */
// TODO(b/172315872) Set foregroundMode is an ExoPlayer method, NOT a player one.
public static final int TIMEOUT_OPERATION_SET_FOREGROUND_MODE = 2;
/** The error occurred while detaching a surface from the player. */
public static final int TIMEOUT_OPERATION_DETACH_SURFACE = 3;
/** If {@link #type} is {@link #TYPE_RENDERER}, this is the name of the renderer. */
@Nullable public final String rendererName; @Nullable public final String rendererName;
/** If {@link #type} is {@link #TYPE_RENDERER}, this is the index of the renderer. */ /**
* If {@link #type} is {@link #TYPE_RENDERER}, this is the index of the renderer, or {@link
* C#INDEX_UNSET} if unknown.
*/
public final int rendererIndex; public final int rendererIndex;
/** /**
...@@ -120,11 +95,6 @@ public final class ExoPlaybackException extends Exception { ...@@ -120,11 +95,6 @@ public final class ExoPlaybackException extends Exception {
*/ */
@FormatSupport public final int rendererFormatSupport; @FormatSupport public final int rendererFormatSupport;
/**
* If {@link #type} is {@link #TYPE_TIMEOUT}, this is the operation where the timeout happened.
*/
@TimeoutOperation public final int timeoutOperation;
/** The value of {@link SystemClock#elapsedRealtime()} when this exception was created. */ /** The value of {@link SystemClock#elapsedRealtime()} when this exception was created. */
public final long timestampMs; public final long timestampMs;
...@@ -155,6 +125,24 @@ public final class ExoPlaybackException extends Exception { ...@@ -155,6 +125,24 @@ public final class ExoPlaybackException extends Exception {
} }
/** /**
* Creates an instance of type {@link #TYPE_RENDERER} for an unknown renderer.
*
* @param cause The cause of the failure.
* @return The created instance.
*/
public static ExoPlaybackException createForRenderer(Exception cause) {
return new ExoPlaybackException(
TYPE_RENDERER,
cause,
/* customMessage= */ null,
/* rendererName */ null,
/* rendererIndex= */ C.INDEX_UNSET,
/* rendererFormat= */ null,
/* rendererFormatSupport= */ C.FORMAT_HANDLED,
/* isRecoverable= */ false);
}
/**
* Creates an instance of type {@link #TYPE_RENDERER}. * Creates an instance of type {@link #TYPE_RENDERER}.
* *
* @param cause The cause of the failure. * @param cause The cause of the failure.
...@@ -207,7 +195,6 @@ public final class ExoPlaybackException extends Exception { ...@@ -207,7 +195,6 @@ public final class ExoPlaybackException extends Exception {
rendererIndex, rendererIndex,
rendererFormat, rendererFormat,
rendererFormat == null ? C.FORMAT_HANDLED : rendererFormatSupport, rendererFormat == null ? C.FORMAT_HANDLED : rendererFormatSupport,
TIMEOUT_OPERATION_UNDEFINED,
isRecoverable); isRecoverable);
} }
...@@ -231,27 +218,6 @@ public final class ExoPlaybackException extends Exception { ...@@ -231,27 +218,6 @@ public final class ExoPlaybackException extends Exception {
return new ExoPlaybackException(TYPE_REMOTE, message); return new ExoPlaybackException(TYPE_REMOTE, message);
} }
/**
* Creates an instance of type {@link #TYPE_TIMEOUT}.
*
* @param cause The cause of the failure.
* @param timeoutOperation The operation that caused this timeout.
* @return The created instance.
*/
public static ExoPlaybackException createForTimeout(
TimeoutException cause, @TimeoutOperation int timeoutOperation) {
return new ExoPlaybackException(
TYPE_TIMEOUT,
cause,
/* customMessage= */ null,
/* rendererName= */ null,
/* rendererIndex= */ C.INDEX_UNSET,
/* rendererFormat= */ null,
/* rendererFormatSupport= */ C.FORMAT_HANDLED,
timeoutOperation,
/* isRecoverable= */ false);
}
private ExoPlaybackException(@Type int type, Throwable cause) { private ExoPlaybackException(@Type int type, Throwable cause) {
this( this(
type, type,
...@@ -261,7 +227,6 @@ public final class ExoPlaybackException extends Exception { ...@@ -261,7 +227,6 @@ public final class ExoPlaybackException extends Exception {
/* rendererIndex= */ C.INDEX_UNSET, /* rendererIndex= */ C.INDEX_UNSET,
/* rendererFormat= */ null, /* rendererFormat= */ null,
/* rendererFormatSupport= */ C.FORMAT_HANDLED, /* rendererFormatSupport= */ C.FORMAT_HANDLED,
TIMEOUT_OPERATION_UNDEFINED,
/* isRecoverable= */ false); /* isRecoverable= */ false);
} }
...@@ -274,7 +239,6 @@ public final class ExoPlaybackException extends Exception { ...@@ -274,7 +239,6 @@ public final class ExoPlaybackException extends Exception {
/* rendererIndex= */ C.INDEX_UNSET, /* rendererIndex= */ C.INDEX_UNSET,
/* rendererFormat= */ null, /* rendererFormat= */ null,
/* rendererFormatSupport= */ C.FORMAT_HANDLED, /* rendererFormatSupport= */ C.FORMAT_HANDLED,
/* timeoutOperation= */ TIMEOUT_OPERATION_UNDEFINED,
/* isRecoverable= */ false); /* isRecoverable= */ false);
} }
...@@ -286,7 +250,6 @@ public final class ExoPlaybackException extends Exception { ...@@ -286,7 +250,6 @@ public final class ExoPlaybackException extends Exception {
int rendererIndex, int rendererIndex,
@Nullable Format rendererFormat, @Nullable Format rendererFormat,
@FormatSupport int rendererFormatSupport, @FormatSupport int rendererFormatSupport,
@TimeoutOperation int timeoutOperation,
boolean isRecoverable) { boolean isRecoverable) {
this( this(
deriveMessage( deriveMessage(
...@@ -303,7 +266,6 @@ public final class ExoPlaybackException extends Exception { ...@@ -303,7 +266,6 @@ public final class ExoPlaybackException extends Exception {
rendererFormat, rendererFormat,
rendererFormatSupport, rendererFormatSupport,
/* mediaPeriodId= */ null, /* mediaPeriodId= */ null,
timeoutOperation,
/* timestampMs= */ SystemClock.elapsedRealtime(), /* timestampMs= */ SystemClock.elapsedRealtime(),
isRecoverable); isRecoverable);
} }
...@@ -317,7 +279,6 @@ public final class ExoPlaybackException extends Exception { ...@@ -317,7 +279,6 @@ public final class ExoPlaybackException extends Exception {
@Nullable Format rendererFormat, @Nullable Format rendererFormat,
@FormatSupport int rendererFormatSupport, @FormatSupport int rendererFormatSupport,
@Nullable MediaPeriodId mediaPeriodId, @Nullable MediaPeriodId mediaPeriodId,
@TimeoutOperation int timeoutOperation,
long timestampMs, long timestampMs,
boolean isRecoverable) { boolean isRecoverable) {
super(message, cause); super(message, cause);
...@@ -328,7 +289,6 @@ public final class ExoPlaybackException extends Exception { ...@@ -328,7 +289,6 @@ public final class ExoPlaybackException extends Exception {
this.rendererFormat = rendererFormat; this.rendererFormat = rendererFormat;
this.rendererFormatSupport = rendererFormatSupport; this.rendererFormatSupport = rendererFormatSupport;
this.mediaPeriodId = mediaPeriodId; this.mediaPeriodId = mediaPeriodId;
this.timeoutOperation = timeoutOperation;
this.timestampMs = timestampMs; this.timestampMs = timestampMs;
this.isRecoverable = isRecoverable; this.isRecoverable = isRecoverable;
} }
...@@ -364,16 +324,6 @@ public final class ExoPlaybackException extends Exception { ...@@ -364,16 +324,6 @@ public final class ExoPlaybackException extends Exception {
} }
/** /**
* Retrieves the underlying error when {@link #type} is {@link #TYPE_TIMEOUT}.
*
* @throws IllegalStateException If {@link #type} is not {@link #TYPE_TIMEOUT}.
*/
public TimeoutException getTimeoutException() {
Assertions.checkState(type == TYPE_TIMEOUT);
return (TimeoutException) Assertions.checkNotNull(cause);
}
/**
* Returns a copy of this exception with the provided {@link MediaPeriodId}. * Returns a copy of this exception with the provided {@link MediaPeriodId}.
* *
* @param mediaPeriodId The {@link MediaPeriodId}. * @param mediaPeriodId The {@link MediaPeriodId}.
...@@ -390,7 +340,6 @@ public final class ExoPlaybackException extends Exception { ...@@ -390,7 +340,6 @@ public final class ExoPlaybackException extends Exception {
rendererFormat, rendererFormat,
rendererFormatSupport, rendererFormatSupport,
mediaPeriodId, mediaPeriodId,
timeoutOperation,
timestampMs, timestampMs,
isRecoverable); isRecoverable);
} }
...@@ -422,9 +371,6 @@ public final class ExoPlaybackException extends Exception { ...@@ -422,9 +371,6 @@ public final class ExoPlaybackException extends Exception {
case TYPE_REMOTE: case TYPE_REMOTE:
message = "Remote error"; message = "Remote error";
break; break;
case TYPE_TIMEOUT:
message = "Timeout error";
break;
case TYPE_UNEXPECTED: case TYPE_UNEXPECTED:
default: default:
message = "Unexpected runtime error"; message = "Unexpected runtime error";
......
...@@ -48,7 +48,6 @@ import com.google.common.collect.ImmutableList; ...@@ -48,7 +48,6 @@ import com.google.common.collect.ImmutableList;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeoutException;
/** /**
* An {@link ExoPlayer} implementation. Instances can be obtained from {@link ExoPlayer.Builder}. * An {@link ExoPlayer} implementation. Instances can be obtained from {@link ExoPlayer.Builder}.
...@@ -674,11 +673,12 @@ import java.util.concurrent.TimeoutException; ...@@ -674,11 +673,12 @@ import java.util.concurrent.TimeoutException;
if (this.foregroundMode != foregroundMode) { if (this.foregroundMode != foregroundMode) {
this.foregroundMode = foregroundMode; this.foregroundMode = foregroundMode;
if (!internalPlayer.setForegroundMode(foregroundMode)) { if (!internalPlayer.setForegroundMode(foregroundMode)) {
// One of the renderers timed out releasing its resources.
stop( stop(
/* reset= */ false, /* reset= */ false,
ExoPlaybackException.createForTimeout( ExoPlaybackException.createForRenderer(
new TimeoutException("Setting foreground mode timed out."), new ExoTimeoutException(
ExoPlaybackException.TIMEOUT_OPERATION_SET_FOREGROUND_MODE)); ExoTimeoutException.TIMEOUT_OPERATION_SET_FOREGROUND_MODE)));
} }
} }
} }
...@@ -728,13 +728,13 @@ import java.util.concurrent.TimeoutException; ...@@ -728,13 +728,13 @@ import java.util.concurrent.TimeoutException;
+ ExoPlayerLibraryInfo.VERSION_SLASHY + "] [" + Util.DEVICE_DEBUG_INFO + "] [" + ExoPlayerLibraryInfo.VERSION_SLASHY + "] [" + Util.DEVICE_DEBUG_INFO + "] ["
+ ExoPlayerLibraryInfo.registeredModules() + "]"); + ExoPlayerLibraryInfo.registeredModules() + "]");
if (!internalPlayer.release()) { if (!internalPlayer.release()) {
// One of the renderers timed out releasing its resources.
listeners.sendEvent( listeners.sendEvent(
Player.EVENT_PLAYER_ERROR, Player.EVENT_PLAYER_ERROR,
listener -> listener ->
listener.onPlayerError( listener.onPlayerError(
ExoPlaybackException.createForTimeout( ExoPlaybackException.createForRenderer(
new TimeoutException("Player release timed out."), new ExoTimeoutException(ExoTimeoutException.TIMEOUT_OPERATION_RELEASE))));
ExoPlaybackException.TIMEOUT_OPERATION_RELEASE)));
} }
listeners.release(); listeners.release();
playbackInfoUpdateHandler.removeCallbacksAndMessages(null); playbackInfoUpdateHandler.removeCallbacksAndMessages(null);
......
/*
* Copyright 2021 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;
import androidx.annotation.IntDef;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/** A timeout of an operation on the ExoPlayer playback thread. */
public final class ExoTimeoutException extends Exception {
/**
* The operation which produced the timeout error. One of {@link #TIMEOUT_OPERATION_RELEASE},
* {@link #TIMEOUT_OPERATION_SET_FOREGROUND_MODE}, {@link #TIMEOUT_OPERATION_DETACH_SURFACE} or
* {@link #TIMEOUT_OPERATION_UNDEFINED}. Note that new operations may be added in the future and
* error handling should handle unknown operation values.
*/
@Documented
@Retention(RetentionPolicy.SOURCE)
@IntDef({
TIMEOUT_OPERATION_UNDEFINED,
TIMEOUT_OPERATION_RELEASE,
TIMEOUT_OPERATION_SET_FOREGROUND_MODE,
TIMEOUT_OPERATION_DETACH_SURFACE
})
public @interface TimeoutOperation {}
/** The operation where this error occurred is not defined. */
public static final int TIMEOUT_OPERATION_UNDEFINED = 0;
// TODO(b/172315872) Change back @code to @link when the Player is in common.
/** The error occurred in {@code Player#release}. */
public static final int TIMEOUT_OPERATION_RELEASE = 1;
/** The error occurred in {@code ExoPlayer#setForegroundMode}. */
// TODO(b/172315872) Set foregroundMode is an ExoPlayer method, NOT a player one.
public static final int TIMEOUT_OPERATION_SET_FOREGROUND_MODE = 2;
/** The error occurred while detaching a surface from the player. */
public static final int TIMEOUT_OPERATION_DETACH_SURFACE = 3;
/** The operation on the ExoPlayer playback thread that timed out. */
@TimeoutOperation public final int timeoutOperation;
/**
* Creates the timeout exception.
*
* @param timeoutOperation The {@link TimeoutOperation operation} that produced the timeout.
*/
public ExoTimeoutException(@TimeoutOperation int timeoutOperation) {
super(getErrorMessage(timeoutOperation));
this.timeoutOperation = timeoutOperation;
}
private static String getErrorMessage(@TimeoutOperation int timeoutOperation) {
switch (timeoutOperation) {
case TIMEOUT_OPERATION_RELEASE:
return "Player release timed out.";
case TIMEOUT_OPERATION_SET_FOREGROUND_MODE:
return "Setting foreground mode timed out.";
case TIMEOUT_OPERATION_DETACH_SURFACE:
return "Detaching surface timed out.";
case TIMEOUT_OPERATION_UNDEFINED:
default:
return "Undefined timeout.";
}
}
}
...@@ -2061,11 +2061,11 @@ public class SimpleExoPlayer extends BasePlayer ...@@ -2061,11 +2061,11 @@ public class SimpleExoPlayer extends BasePlayer
} catch (InterruptedException e) { } catch (InterruptedException e) {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
} catch (TimeoutException e) { } catch (TimeoutException e) {
// One of the renderers timed out releasing its resources.
player.stop( player.stop(
/* reset= */ false, /* reset= */ false,
ExoPlaybackException.createForTimeout( ExoPlaybackException.createForRenderer(
new TimeoutException("Detaching surface timed out."), new ExoTimeoutException(ExoTimeoutException.TIMEOUT_OPERATION_DETACH_SURFACE)));
ExoPlaybackException.TIMEOUT_OPERATION_DETACH_SURFACE));
} }
// If we created the previous surface, we are responsible for releasing it. // If we created the previous surface, we are responsible for releasing it.
if (this.ownsSurface) { if (this.ownsSurface) {
......
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