From 78df21d9b7c767e5842c2d71f167d699e8078bd4 Mon Sep 17 00:00:00 2001 From: Mattia Iavarone Date: Thu, 28 Nov 2019 13:59:13 +0100 Subject: [PATCH] Ensure actions are only started in a valid holder state - Fixes #669 --- .../cameraview/engine/Camera2Engine.java | 5 ++- .../cameraview/engine/action/BaseAction.java | 14 ++++++-- .../picture/Snapshot2PictureRecorder.java | 35 ++++++++++++------- 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java index 2fbbd900..9f4ccea3 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java @@ -613,6 +613,7 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv throw createCameraException(e); } removeRepeatingRequestBuilderSurfaces(); + mLastRepeatingResult = null; LOG.i("onStopPreview:", "Returning."); return Tasks.forResult(null); } @@ -1524,7 +1525,9 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv @Override public void applyBuilder(@NonNull Action source, @NonNull CaptureRequest.Builder builder) throws CameraAccessException { - mSession.capture(builder.build(), mRepeatingRequestCallback, null); + if (getPreviewState() == STATE_STARTED) { + mSession.capture(builder.build(), mRepeatingRequestCallback, null); + } } //endregion diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/action/BaseAction.java b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/action/BaseAction.java index ceff4207..341f7c31 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/action/BaseAction.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/action/BaseAction.java @@ -30,6 +30,7 @@ public abstract class BaseAction implements Action { private final List callbacks = new ArrayList<>(); private int state; private ActionHolder holder; + private boolean needsOnStart; @Override public final int getState() { @@ -39,7 +40,11 @@ public abstract class BaseAction implements Action { @Override public final void start(@NonNull ActionHolder holder) { holder.addAction(this); - onStart(holder); + if (holder.getLastResult(this) != null) { + onStart(holder); + } else { + needsOnStart = true; + } } @Override @@ -49,6 +54,7 @@ public abstract class BaseAction implements Action { onAbort(holder); setState(STATE_COMPLETED); } + needsOnStart = false; } /** @@ -72,9 +78,13 @@ public abstract class BaseAction implements Action { // Overrideable } + @CallSuper @Override public void onCaptureStarted(@NonNull ActionHolder holder, @NonNull CaptureRequest request) { - // Overrideable + if (needsOnStart) { + onStart(holder); + needsOnStart = false; + } } @Override diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/picture/Snapshot2PictureRecorder.java b/cameraview/src/main/java/com/otaliastudios/cameraview/picture/Snapshot2PictureRecorder.java index 8e074ff3..dc2bfba1 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/picture/Snapshot2PictureRecorder.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/picture/Snapshot2PictureRecorder.java @@ -48,7 +48,7 @@ public class Snapshot2PictureRecorder extends SnapshotGlPictureRecorder { private final static CameraLogger LOG = CameraLogger.create(TAG); private final static long LOCK_TIMEOUT = 2500; - private static class FlashAction extends BaseAction { + private class FlashAction extends BaseAction { @Override protected void onStart(@NonNull ActionHolder holder) { @@ -82,6 +82,26 @@ public class Snapshot2PictureRecorder extends SnapshotGlPictureRecorder { } } + private class ResetFlashAction extends BaseAction { + + @Override + protected void onStart(@NonNull ActionHolder holder) { + super.onStart(holder); + try { + // See Camera2Engine.setFlash() comments: turning TORCH off has bugs and we must do + // as follows. + LOG.i("ResetFlashAction:", "Reverting the flash changes."); + CaptureRequest.Builder builder = holder.getBuilder(this); + builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON); + builder.set(CaptureRequest.FLASH_MODE, CaptureResult.FLASH_MODE_OFF); + holder.applyBuilder(this, builder); + builder.set(CaptureRequest.CONTROL_AE_MODE, mOriginalAeMode); + builder.set(CaptureRequest.FLASH_MODE, mOriginalFlashMode); + holder.applyBuilder(this); + } catch (CameraAccessException ignore) {} + } + } + private final Action mAction; private final ActionHolder mHolder; private final boolean mActionNeeded; @@ -135,18 +155,7 @@ public class Snapshot2PictureRecorder extends SnapshotGlPictureRecorder { @Override protected void dispatchResult() { // Revert our changes. - LOG.i("dispatchResult:", "Reverting the flash changes."); - try { - // See Camera2Engine.setFlash() comments: turning TORCH off has bugs and we must do - // as follows. - CaptureRequest.Builder builder = mHolder.getBuilder(mAction); - builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON); - builder.set(CaptureRequest.FLASH_MODE, CaptureResult.FLASH_MODE_OFF); - mHolder.applyBuilder(mAction, builder); - builder.set(CaptureRequest.CONTROL_AE_MODE, mOriginalAeMode); - builder.set(CaptureRequest.FLASH_MODE, mOriginalFlashMode); - mHolder.applyBuilder(mAction); - } catch (CameraAccessException ignore) {} + new ResetFlashAction().start(mHolder); super.dispatchResult(); } }