Avoid process death if OOM occurs on a loading thread

This is most commonly caused by malformed media, where
the media indicates that something we need to make an
allocation for is *really huge*. Failing playback is
appropriate for this case; killing the process is not.

Issue: #2780

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=155408062
This commit is contained in:
olly 2017-01-07 11:59:20 +00:00 committed by Oliver Woodman
parent 963b7cbf72
commit 1d6816d94b

View File

@ -33,11 +33,11 @@ import java.util.concurrent.ExecutorService;
public final class Loader implements LoaderErrorThrower {
/**
* Thrown when an unexpected exception is encountered during loading.
* Thrown when an unexpected exception or error is encountered during loading.
*/
public static final class UnexpectedLoaderException extends IOException {
public UnexpectedLoaderException(Exception cause) {
public UnexpectedLoaderException(Throwable cause) {
super("Unexpected " + cause.getClass().getSimpleName() + ": " + cause.getMessage(), cause);
}
@ -316,6 +316,14 @@ public final class Loader implements LoaderErrorThrower {
if (!released) {
obtainMessage(MSG_IO_EXCEPTION, new UnexpectedLoaderException(e)).sendToTarget();
}
} catch (OutOfMemoryError e) {
// This can occur if a stream is malformed in a way that causes an extractor to think it
// needs to allocate a large amount of memory. We don't want the process to die in this
// case, but we do want the playback to fail.
Log.e(TAG, "OutOfMemory error loading stream", e);
if (!released) {
obtainMessage(MSG_IO_EXCEPTION, new UnexpectedLoaderException(e)).sendToTarget();
}
} catch (Error e) {
// We'd hope that the platform would kill the process if an Error is thrown here, but the
// executor may catch the error (b/20616433). Throw it here, but also pass and throw it from