From abfa9a1c4cc1d9c0a6cc50f02c35066850364d80 Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Wed, 17 Feb 2021 15:56:28 +0100 Subject: [PATCH 1/2] Added timeout for waiting pre-capture state Android --- .../io/flutter/plugins/camera/Camera.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index a5f8647afb0b..62fd529b6700 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -36,6 +36,7 @@ import android.os.Build.VERSION_CODES; import android.os.Handler; import android.os.Looper; +import android.os.SystemClock; import android.util.Log; import android.util.Range; import android.util.Rational; @@ -73,6 +74,11 @@ interface ErrorCallback { public class Camera { private static final String TAG = "Camera"; + /** + * Timeout for the pre-capture sequence. + */ + private static final long PRECAPTURE_TIMEOUT_MS = 1000; + private final SurfaceTextureEntry flutterTexture; private final CameraManager cameraManager; private final DeviceOrientationManager deviceOrientationListener; @@ -105,6 +111,7 @@ public class Camera { private boolean useAutoFocus = true; private Range fpsRange; private PlatformChannel.DeviceOrientation lockedCaptureOrientation; + private long preCaptureStartTime; private static final HashMap supportedImageFormats; // Current supported outputs @@ -503,11 +510,16 @@ private void processCapture(CaptureResult result) { || aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED || aeState == CaptureRequest.CONTROL_AE_STATE_CONVERGED) { pictureCaptureRequest.setState(State.waitingPreCaptureReady); + setPreCaptureStartTime(); } break; case waitingPreCaptureReady: if (aeState == null || aeState != CaptureRequest.CONTROL_AE_STATE_PRECAPTURE) { runPictureCapture(); + } else { + if (hitPreCaptureTimeout()) { + unlockAutoFocus(); + } } } } @@ -1142,6 +1154,22 @@ public void stopImageStream() throws CameraAccessException { startPreview(); } + /** + * Sets the time the pre-capture sequence started. + */ + private void setPreCaptureStartTime() { + preCaptureStartTime = SystemClock.elapsedRealtime(); + } + + /** + * Check if the timeout for the pre-capture sequence has been reached. + * + * @return true if the timeout is reached; otherwise false is returned. + */ + private boolean hitPreCaptureTimeout() { + return (SystemClock.elapsedRealtime() - preCaptureStartTime) > PRECAPTURE_TIMEOUT_MS; + } + private void closeCaptureSession() { if (cameraCaptureSession != null) { cameraCaptureSession.close(); From 360f86dbaf8f1646bff87a6a5e8df3da97d4a677 Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Wed, 17 Feb 2021 16:47:23 +0100 Subject: [PATCH 2/2] Fix analysis warning and bumped version --- packages/camera/camera/CHANGELOG.md | 4 ++++ .../src/main/java/io/flutter/plugins/camera/Camera.java | 8 ++------ packages/camera/camera/pubspec.yaml | 2 +- packages/camera/camera/test/camera_test.dart | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index aee3774087ba..7391f3090565 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.8.0-nullsafety.1 + +* Added a timeout to the pre-capture sequence on Android to prevent crashes when the camera cannot get a focus. + ## 0.8.0-nullsafety * Migrated to null safety. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 62fd529b6700..5169a3babb74 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -74,9 +74,7 @@ interface ErrorCallback { public class Camera { private static final String TAG = "Camera"; - /** - * Timeout for the pre-capture sequence. - */ + /** Timeout for the pre-capture sequence. */ private static final long PRECAPTURE_TIMEOUT_MS = 1000; private final SurfaceTextureEntry flutterTexture; @@ -1154,9 +1152,7 @@ public void stopImageStream() throws CameraAccessException { startPreview(); } - /** - * Sets the time the pre-capture sequence started. - */ + /** Sets the time the pre-capture sequence started. */ private void setPreCaptureStartTime() { preCaptureStartTime = SystemClock.elapsedRealtime(); } diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 7ed08d892de8..5b98c39acd99 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.8.0-nullsafety +version: 0.8.0-nullsafety.1 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: diff --git a/packages/camera/camera/test/camera_test.dart b/packages/camera/camera/test/camera_test.dart index b37b7701a14f..40ce29e363b1 100644 --- a/packages/camera/camera/test/camera_test.dart +++ b/packages/camera/camera/test/camera_test.dart @@ -1268,7 +1268,7 @@ class MockCameraPlatform extends Mock Future createCamera( CameraDescription description, ResolutionPreset? resolutionPreset, { - bool enableAudio = true, + bool enableAudio = false, }) => mockPlatformException ? throw PlatformException(code: 'foo', message: 'bar')