Bug 1452048 - Give Looper lifetime control to external callers. r=dminor

Looper lifetime must be handled by external callers as otherwise internal
callers may accidentally and unknowingly quit the looper and essentially
terminate the camera thread, stopping any flow of frames and preventing future
messages.

In this case, a reconfig of the capture settings through startCapture() causes
startCaptureOnCameraThread() to restart the capture by calling into
stopCaptureOnCameraThread() (quitting the looper) and then re-calling
startCaptureOnCameraThread() (not restarting the looper as that is invalid).

The camera thread is set up by startCapture() on the external calling thread,
which will never know that a seemingly graceful camera thread operation stopped
the camera thread altogether, and so it cannot take any action.

MozReview-Commit-ID: DUTFdanTan1

--HG--
extra : rebase_source : afeb80aa8b2596a2615f57ec4af182a837323b7e
This commit is contained in:
Andreas Pehrson 2018-04-06 13:59:45 +02:00
Родитель f532155f8c
Коммит edabee9ab6
1 изменённых файлов: 4 добавлений и 2 удалений

Просмотреть файл

@ -121,6 +121,9 @@ public class VideoCaptureAndroid implements PreviewCallback, Callback {
@Override public void run() {
boolean startResult =
startCaptureOnCameraThread(width, height, min_mfps, max_mfps);
if (!startResult) {
Looper.myLooper().quit();
}
exchange(result, startResult);
}
});
@ -316,6 +319,7 @@ public class VideoCaptureAndroid implements PreviewCallback, Callback {
cameraThreadHandler.post(new Runnable() {
@Override public void run() {
boolean stopResult = stopCaptureOnCameraThread();
Looper.myLooper().quit();
exchange(result, stopResult);
}
});
@ -348,7 +352,6 @@ public class VideoCaptureAndroid implements PreviewCallback, Callback {
}
camera.release();
camera = null;
Looper.myLooper().quit();
return true;
} catch (IOException e) {
error = e;
@ -356,7 +359,6 @@ public class VideoCaptureAndroid implements PreviewCallback, Callback {
error = e;
}
Log.e(TAG, "Failed to stop camera", error);
Looper.myLooper().quit();
return false;
}