mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +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}
|
* 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
|
@Documented
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@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 {}
|
public @interface Type {}
|
||||||
/**
|
/**
|
||||||
* The error occurred loading data from a {@link MediaSource}.
|
* 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.
|
* <p>Call {@link #getMessage()} to retrieve the message associated with the error.
|
||||||
*/
|
*/
|
||||||
public static final int TYPE_REMOTE = 3;
|
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
|
* The type of the playback failure. One of {@link #TYPE_SOURCE}, {@link #TYPE_RENDERER}, {@link
|
||||||
* {@link #TYPE_UNEXPECTED}.
|
* #TYPE_UNEXPECTED}, {@link #TYPE_REMOTE} and {@link #TYPE_OUT_OF_MEMORY}.
|
||||||
*/
|
*/
|
||||||
@Type public final int type;
|
@Type public final int type;
|
||||||
|
|
||||||
|
|
@ -82,7 +84,7 @@ public final class ExoPlaybackException extends Exception {
|
||||||
* @return The created instance.
|
* @return The created instance.
|
||||||
*/
|
*/
|
||||||
public static ExoPlaybackException createForSource(IOException cause) {
|
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.
|
* @return The created instance.
|
||||||
*/
|
*/
|
||||||
/* package */ static ExoPlaybackException createForUnexpected(RuntimeException cause) {
|
/* 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);
|
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) {
|
private ExoPlaybackException(@Type int type, Throwable cause, int rendererIndex) {
|
||||||
super(cause);
|
super(cause);
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
|
@ -160,4 +172,13 @@ public final class ExoPlaybackException extends Exception {
|
||||||
return (RuntimeException) Assertions.checkNotNull(cause);
|
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);
|
/* acknowledgeStop= */ false);
|
||||||
eventHandler.obtainMessage(MSG_ERROR, ExoPlaybackException.createForSource(e)).sendToTarget();
|
eventHandler.obtainMessage(MSG_ERROR, ExoPlaybackException.createForSource(e)).sendToTarget();
|
||||||
maybeNotifyPlaybackInfoChanged();
|
maybeNotifyPlaybackInfoChanged();
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException | OutOfMemoryError e) {
|
||||||
Log.e(TAG, "Internal runtime error.", e);
|
Log.e(TAG, "Internal runtime error.", e);
|
||||||
stopInternal(
|
stopInternal(
|
||||||
/* forceResetRenderers= */ true,
|
/* forceResetRenderers= */ true,
|
||||||
/* resetPositionAndState= */ false,
|
/* resetPositionAndState= */ false,
|
||||||
/* acknowledgeStop= */ false);
|
/* acknowledgeStop= */ false);
|
||||||
eventHandler.obtainMessage(MSG_ERROR, ExoPlaybackException.createForUnexpected(e))
|
ExoPlaybackException error =
|
||||||
.sendToTarget();
|
e instanceof OutOfMemoryError
|
||||||
|
? ExoPlaybackException.createForOutOfMemoryError((OutOfMemoryError) e)
|
||||||
|
: ExoPlaybackException.createForUnexpected((RuntimeException) e);
|
||||||
|
eventHandler.obtainMessage(MSG_ERROR, error).sendToTarget();
|
||||||
maybeNotifyPlaybackInfoChanged();
|
maybeNotifyPlaybackInfoChanged();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue