From f3dbef6cf2fa2bd3772d89588bcea99779c20858 Mon Sep 17 00:00:00 2001 From: Mattia Iavarone Date: Wed, 11 Oct 2017 15:39:32 +0200 Subject: [PATCH] Ensure no issues if scheduled for stop --- .../com/otaliastudios/cameraview/Camera1.java | 17 ++++++++++++++--- .../cameraview/CameraController.java | 10 ++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/Camera1.java b/cameraview/src/main/java/com/otaliastudios/cameraview/Camera1.java index a2272051..0537cf9f 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/Camera1.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/Camera1.java @@ -510,9 +510,20 @@ class Camera1 extends CameraController { } private boolean isCameraAvailable() { - // Don't do if state is stopping. The camera instance might have been released, - // even if onStop did not return yet. - return mCamera != null && mState > STATE_STOPPING; + switch (mState) { + // If we are stopped, don't. + case STATE_STOPPED: return false; + // If we are going to be closed, don't act on camera. + // Even if mCamera != null, it might have been released. + case STATE_STOPPING: return false; + // If we are started, act as long as there is no stop/restart scheduled. + // At this point mCamera should never be null. + case STATE_STARTED: return !mScheduledForStop && !mScheduledForRestart; + // If we are starting, theoretically we could act. + // Just check that camera is available. + case STATE_STARTING: return mCamera != null && !mScheduledForStop && !mScheduledForRestart; + } + return false; } diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraController.java b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraController.java index c9c1038c..be221965 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraController.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraController.java @@ -38,6 +38,10 @@ abstract class CameraController implements CameraPreview.SurfaceCallback { protected int mDisplayOffset; protected int mDeviceOrientation; + + protected boolean mScheduledForStart = false; + protected boolean mScheduledForStop = false; + protected boolean mScheduledForRestart = false; protected int mState = STATE_STOPPED; protected WorkerHandler mHandler; @@ -84,11 +88,13 @@ abstract class CameraController implements CameraPreview.SurfaceCallback { // Starts the preview asynchronously. final void start() { LOG.i("Start:", "posting runnable. State:", ss()); + mScheduledForStart = true; mHandler.post(new Runnable() { @Override public void run() { try { LOG.i("Start:", "executing. State:", ss()); + mScheduledForStart = false; if (mState >= STATE_STARTING) return; mState = STATE_STARTING; LOG.i("Start:", "about to call onStart()", ss()); @@ -108,11 +114,13 @@ abstract class CameraController implements CameraPreview.SurfaceCallback { // Stops the preview asynchronously. final void stop() { LOG.i("Stop:", "posting runnable. State:", ss()); + mScheduledForStop = true; mHandler.post(new Runnable() { @Override public void run() { try { LOG.i("Stop:", "executing. State:", ss()); + mScheduledForStop = false; if (mState <= STATE_STOPPED) return; mState = STATE_STOPPING; LOG.i("Stop:", "about to call onStop()"); @@ -148,11 +156,13 @@ abstract class CameraController implements CameraPreview.SurfaceCallback { // Forces a restart. protected final void restart() { LOG.i("Restart:", "posting runnable"); + mScheduledForRestart = true; mHandler.post(new Runnable() { @Override public void run() { try { LOG.i("Restart:", "executing. Needs stopping:", mState > STATE_STOPPED, ss()); + mScheduledForRestart = false; // Don't stop if stopped. if (mState > STATE_STOPPED) { mState = STATE_STOPPING;