From c8eaf1be854c60f1a212ead19d0269d1b1a0233f Mon Sep 17 00:00:00 2001 From: Wolfgang Wiedmeyer Date: Fri, 30 Dec 2016 17:54:35 +0100 Subject: Redo snapshot if shutter button is clicked during SNAPSHOT_IN_PROGRESS If the shutter button is clicked in the photo view, the interface will be in the SNAPSHOT_IN_PROGRESS state until the picture is taken. During this state, the app is unresponsive and if there is an issue with the camera HAL, the app may not leave this state. Let's restart the camera if the shutter is clicked a second time during this state and redo the snapshot. Previously, the app only registered that the shutter was pressed a second time and tried to take a second picture after the previous snapshot was finished. Signed-off-by: Wolfgang Wiedmeyer --- src/com/android/camera/Camera.java | 58 ++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/src/com/android/camera/Camera.java b/src/com/android/camera/Camera.java index 254db28..edff244 100644 --- a/src/com/android/camera/Camera.java +++ b/src/com/android/camera/Camera.java @@ -190,12 +190,6 @@ public class Camera extends ActivityBase implements FocusManager.Listener, private MediaActionSound mCameraSound; - private Runnable mDoSnapRunnable = new Runnable() { - public void run() { - onShutterButtonClick(); - } - }; - private final StringBuilder mBuilder = new StringBuilder(); private final Formatter mFormatter = new Formatter(mBuilder); private final Object[] mFormatterArgs = new Object[1]; @@ -224,7 +218,6 @@ public class Camera extends ActivityBase implements FocusManager.Listener, private static final int FOCUSING = 2; private static final int SNAPSHOT_IN_PROGRESS = 3; private int mCameraState = PREVIEW_STOPPED; - private boolean mSnapshotOnIdle = false; private ContentResolver mContentResolver; private boolean mDidRegister = false; @@ -1492,16 +1485,15 @@ public class Camera extends ActivityBase implements FocusManager.Listener, Log.v(TAG, "onShutterButtonClick: mCameraState=" + mCameraState); // If the user wants to do a snapshot while the previous one is still - // in progress, remember the fact and do it after we finish the previous - // one and re-start the preview. Snapshot in progress also includes the - // state that autofocus is focusing and a picture will be taken when - // focus callback arrives. + // in progress, restart the camera and redo the snapshot. Snapshot in + // progress also includes the state that autofocus is focusing and a + // picture will be taken when focus callback arrives. if (mFocusManager.isFocusingSnapOnFinish() || mCameraState == SNAPSHOT_IN_PROGRESS) { - mSnapshotOnIdle = true; + Log.v(TAG, "Shutter was clicked again, redoing the snapshot"); + redoSnapshot(); return; } - mSnapshotOnIdle = false; mFocusManager.doSnap(); } @@ -1859,14 +1851,13 @@ public class Camera extends ActivityBase implements FocusManager.Listener, setPreviewDisplay(mSurfaceHolder); setDisplayOrientation(); - if (!mSnapshotOnIdle) { - // If the focus mode is continuous autofocus, call cancelAutoFocus to - // resume it because it may have been paused by autoFocus call. - if (Parameters.FOCUS_MODE_CONTINUOUS_PICTURE.equals(mFocusManager.getFocusMode())) { - mCameraDevice.cancelAutoFocus(); - } - mFocusManager.setAeAwbLock(false); // Unlock AE and AWB. + // If the focus mode is continuous autofocus, call cancelAutoFocus to + // resume it because it may have been paused by autoFocus call. + if (Parameters.FOCUS_MODE_CONTINUOUS_PICTURE.equals(mFocusManager.getFocusMode())) { + mCameraDevice.cancelAutoFocus(); } + mFocusManager.setAeAwbLock(false); // Unlock AE and AWB. + setCameraParameters(UPDATE_PARAM_ALL); // Inform the mainthread to go on the UI initialization. @@ -1887,10 +1878,6 @@ public class Camera extends ActivityBase implements FocusManager.Listener, mZoomState = ZOOM_STOPPED; setCameraState(IDLE); mFocusManager.onPreviewStarted(); - - if (mSnapshotOnIdle) { - mHandler.post(mDoSnapRunnable); - } } private void stopPreview() { @@ -2336,6 +2323,29 @@ public class Camera extends ActivityBase implements FocusManager.Listener, mAwbLockSupported = mInitialParams.isAutoWhiteBalanceLockSupported(); } + private void redoSnapshot() { + stopPreview(); + closeCamera(); + mHandler.removeMessages(FIRST_TIME_INIT); + mHandler.removeMessages(CHECK_DISPLAY_ROTATION); + mFocusManager.removeMessages(); + + try { + mCameraDevice = Util.openCamera(this, mCameraId); + } catch (CameraHardwareException e) { + Util.showErrorAndFinish(this, R.string.cannot_connect_camera); + return; + } catch (CameraDisabledException e) { + Util.showErrorAndFinish(this, R.string.camera_disabled); + return; + } + initializeCapabilities(); + resetExposureCompensation(); + startPreview(); + startFaceDetection(); + onShutterButtonClick(); + } + @Override public void onResumeAfterSuper() { // Add delay on resume from lock screen only, in order to to speed up -- cgit v1.1