From 6ed059e6dcfc0b5f71d25cde7b470703c7a1e248 Mon Sep 17 00:00:00 2001
From: akwizgran <akwizgran@users.sourceforge.net>
Date: Wed, 1 Apr 2015 23:17:20 +0100
Subject: [PATCH] Auto-focus improvements.

---
 src/org/briarproject/qrtest/CameraView.java   | 54 +++++++++++++++----
 .../briarproject/qrtest/QrCodeDecoder.java    |  2 -
 2 files changed, 43 insertions(+), 13 deletions(-)

diff --git a/src/org/briarproject/qrtest/CameraView.java b/src/org/briarproject/qrtest/CameraView.java
index eb611f1..3bd7ace 100644
--- a/src/org/briarproject/qrtest/CameraView.java
+++ b/src/org/briarproject/qrtest/CameraView.java
@@ -2,6 +2,7 @@ package org.briarproject.qrtest;
 
 import static android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT;
 import static android.hardware.Camera.Parameters.FOCUS_MODE_AUTO;
+import static android.hardware.Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE;
 import static android.hardware.Camera.Parameters.FOCUS_MODE_MACRO;
 import static android.view.SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS;
 
@@ -14,6 +15,7 @@ import android.hardware.Camera.AutoFocusCallback;
 import android.hardware.Camera.CameraInfo;
 import android.hardware.Camera.Parameters;
 import android.hardware.Camera.Size;
+import android.os.Handler;
 import android.util.Log;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
@@ -24,29 +26,27 @@ AutoFocusCallback {
 
 	private static String TAG = CameraView.class.getPackage().getName();
 
+	private final Handler handler;
+
 	private Camera camera = null;
 	private PreviewConsumer previewConsumer = null;
 	private Size desiredSize = null;
 	private int displayOrientation = 0;
-	private boolean surfaceExists = false;
+	private boolean stopped = false, autoFocus = false, surfaceExists = false;
 
 	public CameraView(Context context) {
 		super(context);
+		handler = new Handler();
 		setKeepScreenOn(true);
 	}
 
 	void start(Camera camera, PreviewConsumer previewConsumer,
 			int rotationDegrees, boolean macro) {
+		stopped = false;
 		this.camera = camera;
 		this.previewConsumer = previewConsumer;
 		setDisplayOrientation(rotationDegrees);
-		Parameters params = camera.getParameters();
-		List<String> modes = params.getSupportedFocusModes();
-		if(macro && modes.contains(FOCUS_MODE_MACRO))
-			params.setFocusMode(FOCUS_MODE_MACRO);
-		else if(modes.contains(FOCUS_MODE_AUTO))
-			params.setFocusMode(FOCUS_MODE_AUTO);
-		camera.setParameters(params);
+		setFocusMode(macro);
 		SurfaceHolder holder = getHolder();
 		holder.addCallback(this);
 		holder.setType(SURFACE_TYPE_PUSH_BUFFERS); // Required on Android < 3.0
@@ -54,6 +54,7 @@ AutoFocusCallback {
 	}
 
 	void stop() {
+		stopped = true;
 		stopPreview();
 		getHolder().removeCallback(this);
 	}
@@ -62,7 +63,7 @@ AutoFocusCallback {
 		try {
 			camera.setPreviewDisplay(holder);
 			camera.startPreview();
-			camera.autoFocus(this);
+			autoFocus();
 			previewConsumer.start(camera);
 		} catch(IOException e) {
 			Log.e(TAG, "Error starting camera preview", e);
@@ -72,13 +73,17 @@ AutoFocusCallback {
 	private void stopPreview() {
 		try {
 			previewConsumer.stop();
-			camera.cancelAutoFocus();
+			if(autoFocus) camera.cancelAutoFocus();
 			camera.stopPreview();
 		} catch(Exception e) {
 			Log.e(TAG, "Error stopping camera preview", e);
 		}
 	}
 
+	private void autoFocus() {
+		if(!stopped && autoFocus) camera.autoFocus(this);
+	}
+
 	private void setDisplayOrientation(int rotationDegrees) {
 		int orientation;
 		CameraInfo info = new CameraInfo();
@@ -94,6 +99,28 @@ AutoFocusCallback {
 		displayOrientation = orientation;
 	}
 
+	private void setFocusMode(boolean macro) {
+		Parameters params = camera.getParameters();
+		List<String> modes = params.getSupportedFocusModes();
+		if(macro && modes.contains(FOCUS_MODE_MACRO)) {
+			Log.d(TAG, "Setting focus mode to macro");
+			params.setFocusMode(FOCUS_MODE_MACRO);
+			autoFocus = true;
+		} else if(modes.contains(FOCUS_MODE_CONTINUOUS_PICTURE)) {
+			Log.d(TAG, "Setting focus mode to continuous");
+			params.setFocusMode(FOCUS_MODE_CONTINUOUS_PICTURE);
+			autoFocus = false;
+		} else if(modes.contains(FOCUS_MODE_AUTO)) {
+			Log.d(TAG, "Setting focus mode to auto");
+			params.setFocusMode(FOCUS_MODE_AUTO);
+			autoFocus = true;
+		} else {
+			Log.d(TAG, "No suitable focus mode");
+			autoFocus = false;
+		}
+		camera.setParameters(params);
+	}
+
 	public void surfaceCreated(SurfaceHolder holder) {
 		Log.d(TAG, "Surface created");
 		surfaceExists = true;
@@ -136,8 +163,13 @@ AutoFocusCallback {
 		surfaceExists = false;
 	}
 
-	public void onAutoFocus(boolean success, Camera camera) {
+	public void onAutoFocus(boolean success, final Camera camera) {
 		Log.d(TAG, "Auto focus: " + success);
+		handler.postDelayed(new Runnable() {
+			public void run() {
+				autoFocus();
+			}
+		}, success ? 3000 : 0);
 	}
 
 	@Override
diff --git a/src/org/briarproject/qrtest/QrCodeDecoder.java b/src/org/briarproject/qrtest/QrCodeDecoder.java
index 79cb347..a0c3630 100644
--- a/src/org/briarproject/qrtest/QrCodeDecoder.java
+++ b/src/org/briarproject/qrtest/QrCodeDecoder.java
@@ -31,13 +31,11 @@ public class QrCodeDecoder implements PreviewConsumer, PreviewCallback {
 	}
 
 	public void start(Camera camera) {
-		Log.d(TAG, "Started");
 		stopped = false;
 		askForPreviewFrame(camera);
 	}
 
 	public void stop() {
-		Log.d(TAG, "Stopped");
 		stopped = true;
 	}
 
-- 
GitLab