Don't act on Camera if it is in the middle of a stop (#50)

* Don't act on Camera if it is in the middle of a stop
* Ensure no issues if scheduled for stop
pull/68/head
Mattia Iavarone 7 years ago committed by GitHub
parent 98855d0976
commit dbc58af510
  1. 17
      cameraview/src/main/java/com/otaliastudios/cameraview/Camera1.java
  2. 10
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraController.java

@ -191,7 +191,7 @@ class Camera1 extends CameraController {
Exception error = null; Exception error = null;
LOG.i("onStop:", "About to clean up."); LOG.i("onStop:", "About to clean up.");
mHandler.get().removeCallbacks(mPostFocusResetRunnable); mHandler.get().removeCallbacks(mPostFocusResetRunnable);
if (isCameraAvailable()) { if (mCamera != null) {
LOG.i("onStop:", "Clean up.", "Ending video?", mIsCapturingVideo); LOG.i("onStop:", "Clean up.", "Ending video?", mIsCapturingVideo);
if (mIsCapturingVideo) endVideo(); if (mIsCapturingVideo) endVideo();
@ -510,7 +510,20 @@ class Camera1 extends CameraController {
} }
private boolean isCameraAvailable() { private boolean isCameraAvailable() {
return mCamera != null; 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;
} }

@ -38,6 +38,10 @@ abstract class CameraController implements CameraPreview.SurfaceCallback {
protected int mDisplayOffset; protected int mDisplayOffset;
protected int mDeviceOrientation; protected int mDeviceOrientation;
protected boolean mScheduledForStart = false;
protected boolean mScheduledForStop = false;
protected boolean mScheduledForRestart = false;
protected int mState = STATE_STOPPED; protected int mState = STATE_STOPPED;
protected WorkerHandler mHandler; protected WorkerHandler mHandler;
@ -84,11 +88,13 @@ abstract class CameraController implements CameraPreview.SurfaceCallback {
// Starts the preview asynchronously. // Starts the preview asynchronously.
final void start() { final void start() {
LOG.i("Start:", "posting runnable. State:", ss()); LOG.i("Start:", "posting runnable. State:", ss());
mScheduledForStart = true;
mHandler.post(new Runnable() { mHandler.post(new Runnable() {
@Override @Override
public void run() { public void run() {
try { try {
LOG.i("Start:", "executing. State:", ss()); LOG.i("Start:", "executing. State:", ss());
mScheduledForStart = false;
if (mState >= STATE_STARTING) return; if (mState >= STATE_STARTING) return;
mState = STATE_STARTING; mState = STATE_STARTING;
LOG.i("Start:", "about to call onStart()", ss()); LOG.i("Start:", "about to call onStart()", ss());
@ -108,11 +114,13 @@ abstract class CameraController implements CameraPreview.SurfaceCallback {
// Stops the preview asynchronously. // Stops the preview asynchronously.
final void stop() { final void stop() {
LOG.i("Stop:", "posting runnable. State:", ss()); LOG.i("Stop:", "posting runnable. State:", ss());
mScheduledForStop = true;
mHandler.post(new Runnable() { mHandler.post(new Runnable() {
@Override @Override
public void run() { public void run() {
try { try {
LOG.i("Stop:", "executing. State:", ss()); LOG.i("Stop:", "executing. State:", ss());
mScheduledForStop = false;
if (mState <= STATE_STOPPED) return; if (mState <= STATE_STOPPED) return;
mState = STATE_STOPPING; mState = STATE_STOPPING;
LOG.i("Stop:", "about to call onStop()"); LOG.i("Stop:", "about to call onStop()");
@ -148,11 +156,13 @@ abstract class CameraController implements CameraPreview.SurfaceCallback {
// Forces a restart. // Forces a restart.
protected final void restart() { protected final void restart() {
LOG.i("Restart:", "posting runnable"); LOG.i("Restart:", "posting runnable");
mScheduledForRestart = true;
mHandler.post(new Runnable() { mHandler.post(new Runnable() {
@Override @Override
public void run() { public void run() {
try { try {
LOG.i("Restart:", "executing. Needs stopping:", mState > STATE_STOPPED, ss()); LOG.i("Restart:", "executing. Needs stopping:", mState > STATE_STOPPED, ss());
mScheduledForRestart = false;
// Don't stop if stopped. // Don't stop if stopped.
if (mState > STATE_STOPPED) { if (mState > STATE_STOPPED) {
mState = STATE_STOPPING; mState = STATE_STOPPING;

Loading…
Cancel
Save