mirror of
https://github.com/samsonjs/media.git
synced 2026-03-27 09:45:47 +00:00
Avoid crashing process on OOM
Catch OutOfMemoryErrors and surface them as unexpected ExoPlaybackExceptions. PiperOrigin-RevId: 234481140
This commit is contained in:
parent
0ceff589b3
commit
2b67f2a626
2 changed files with 33 additions and 9 deletions
|
|
@ -31,11 +31,11 @@ public final class ExoPlaybackException extends Exception {
|
|||
|
||||
/**
|
||||
* The type of source that produced the error. One of {@link #TYPE_SOURCE}, {@link #TYPE_RENDERER}
|
||||
* or {@link #TYPE_UNEXPECTED}.
|
||||
* {@link #TYPE_UNEXPECTED}, {@link #TYPE_REMOTE} or {@link #TYPE_OUT_OF_MEMORY}.
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({TYPE_SOURCE, TYPE_RENDERER, TYPE_UNEXPECTED, TYPE_REMOTE})
|
||||
@IntDef({TYPE_SOURCE, TYPE_RENDERER, TYPE_UNEXPECTED, TYPE_REMOTE, TYPE_OUT_OF_MEMORY})
|
||||
public @interface Type {}
|
||||
/**
|
||||
* The error occurred loading data from a {@link MediaSource}.
|
||||
|
|
@ -61,10 +61,12 @@ public final class ExoPlaybackException extends Exception {
|
|||
* <p>Call {@link #getMessage()} to retrieve the message associated with the error.
|
||||
*/
|
||||
public static final int TYPE_REMOTE = 3;
|
||||
/** The error was an {@link OutOfMemoryError}. */
|
||||
public static final int TYPE_OUT_OF_MEMORY = 4;
|
||||
|
||||
/**
|
||||
* The type of the playback failure. One of {@link #TYPE_SOURCE}, {@link #TYPE_RENDERER} and
|
||||
* {@link #TYPE_UNEXPECTED}.
|
||||
* The type of the playback failure. One of {@link #TYPE_SOURCE}, {@link #TYPE_RENDERER}, {@link
|
||||
* #TYPE_UNEXPECTED}, {@link #TYPE_REMOTE} and {@link #TYPE_OUT_OF_MEMORY}.
|
||||
*/
|
||||
@Type public final int type;
|
||||
|
||||
|
|
@ -82,7 +84,7 @@ public final class ExoPlaybackException extends Exception {
|
|||
* @return The created instance.
|
||||
*/
|
||||
public static ExoPlaybackException createForSource(IOException cause) {
|
||||
return new ExoPlaybackException(TYPE_SOURCE, cause, C.INDEX_UNSET);
|
||||
return new ExoPlaybackException(TYPE_SOURCE, cause, /* rendererIndex= */ C.INDEX_UNSET);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -103,7 +105,7 @@ public final class ExoPlaybackException extends Exception {
|
|||
* @return The created instance.
|
||||
*/
|
||||
/* package */ static ExoPlaybackException createForUnexpected(RuntimeException cause) {
|
||||
return new ExoPlaybackException(TYPE_UNEXPECTED, cause, C.INDEX_UNSET);
|
||||
return new ExoPlaybackException(TYPE_UNEXPECTED, cause, /* rendererIndex= */ C.INDEX_UNSET);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -116,6 +118,16 @@ public final class ExoPlaybackException extends Exception {
|
|||
return new ExoPlaybackException(TYPE_REMOTE, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of type {@link #TYPE_OUT_OF_MEMORY}.
|
||||
*
|
||||
* @param cause The cause of the failure.
|
||||
* @return The created instance.
|
||||
*/
|
||||
/* package */ static ExoPlaybackException createForOutOfMemoryError(OutOfMemoryError cause) {
|
||||
return new ExoPlaybackException(TYPE_OUT_OF_MEMORY, cause, /* rendererIndex= */ C.INDEX_UNSET);
|
||||
}
|
||||
|
||||
private ExoPlaybackException(@Type int type, Throwable cause, int rendererIndex) {
|
||||
super(cause);
|
||||
this.type = type;
|
||||
|
|
@ -160,4 +172,13 @@ public final class ExoPlaybackException extends Exception {
|
|||
return (RuntimeException) Assertions.checkNotNull(cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the underlying error when {@link #type} is {@link #TYPE_OUT_OF_MEMORY}.
|
||||
*
|
||||
* @throws IllegalStateException If {@link #type} is not {@link #TYPE_OUT_OF_MEMORY}.
|
||||
*/
|
||||
public OutOfMemoryError getOutOfMemoryError() {
|
||||
Assertions.checkState(type == TYPE_OUT_OF_MEMORY);
|
||||
return (OutOfMemoryError) Assertions.checkNotNull(cause);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -389,14 +389,17 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
/* acknowledgeStop= */ false);
|
||||
eventHandler.obtainMessage(MSG_ERROR, ExoPlaybackException.createForSource(e)).sendToTarget();
|
||||
maybeNotifyPlaybackInfoChanged();
|
||||
} catch (RuntimeException e) {
|
||||
} catch (RuntimeException | OutOfMemoryError e) {
|
||||
Log.e(TAG, "Internal runtime error.", e);
|
||||
stopInternal(
|
||||
/* forceResetRenderers= */ true,
|
||||
/* resetPositionAndState= */ false,
|
||||
/* acknowledgeStop= */ false);
|
||||
eventHandler.obtainMessage(MSG_ERROR, ExoPlaybackException.createForUnexpected(e))
|
||||
.sendToTarget();
|
||||
ExoPlaybackException error =
|
||||
e instanceof OutOfMemoryError
|
||||
? ExoPlaybackException.createForOutOfMemoryError((OutOfMemoryError) e)
|
||||
: ExoPlaybackException.createForUnexpected((RuntimeException) e);
|
||||
eventHandler.obtainMessage(MSG_ERROR, error).sendToTarget();
|
||||
maybeNotifyPlaybackInfoChanged();
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
Loading…
Reference in a new issue