From 6bf62770bddd9b6a6e694b0b513a39ca3d051cf4 Mon Sep 17 00:00:00 2001 From: Oliver Woodman Date: Fri, 1 May 2015 20:24:50 +0100 Subject: [PATCH] Make sure that the process dies if a loading task throws Error. --- .../android/exoplayer/upstream/Loader.java | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/library/src/main/java/com/google/android/exoplayer/upstream/Loader.java b/library/src/main/java/com/google/android/exoplayer/upstream/Loader.java index d11f2166c8..6eb477fd0d 100644 --- a/library/src/main/java/com/google/android/exoplayer/upstream/Loader.java +++ b/library/src/main/java/com/google/android/exoplayer/upstream/Loader.java @@ -99,7 +99,8 @@ public final class Loader { } private static final int MSG_END_OF_SOURCE = 0; - private static final int MSG_ERROR = 1; + private static final int MSG_IO_EXCEPTION = 1; + private static final int MSG_FATAL_ERROR = 2; private final ExecutorService downloadExecutorService; @@ -242,20 +243,30 @@ public final class Loader { } sendEmptyMessage(MSG_END_OF_SOURCE); } catch (IOException e) { - obtainMessage(MSG_ERROR, e).sendToTarget(); + obtainMessage(MSG_IO_EXCEPTION, e).sendToTarget(); } catch (InterruptedException e) { // The load was canceled. Assertions.checkState(loadable.isLoadCanceled()); sendEmptyMessage(MSG_END_OF_SOURCE); } catch (Exception e) { // This should never happen, but handle it anyway. + Log.e(TAG, "Unexpected exception loading stream", e); + 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 + // the handler thread so that the process dies even if the executor behaves in this way. Log.e(TAG, "Unexpected error loading stream", e); - obtainMessage(MSG_ERROR, new UnexpectedLoaderException(e)).sendToTarget(); + obtainMessage(MSG_FATAL_ERROR, e).sendToTarget(); + throw e; } } @Override public void handleMessage(Message msg) { + if (msg.what == MSG_FATAL_ERROR) { + throw (Error) msg.obj; + } onFinished(); if (loadable.isLoadCanceled()) { callback.onLoadCanceled(loadable); @@ -265,7 +276,7 @@ public final class Loader { case MSG_END_OF_SOURCE: callback.onLoadCompleted(loadable); break; - case MSG_ERROR: + case MSG_IO_EXCEPTION: callback.onLoadError(loadable, (IOException) msg.obj); break; }