2 * Copyright (C) 2012 ZXing authors
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package cz.cvut.fel.dce.barcodescanner.camera;
19 import android.content.Context;
20 import android.content.SharedPreferences;
21 import android.hardware.Camera;
22 import android.os.AsyncTask;
23 import android.preference.PreferenceManager;
24 import android.util.Log;
26 import cz.cvut.fel.dce.barcodescanner.PreferencesActivity;
28 import java.util.ArrayList;
29 import java.util.Collection;
30 import java.util.concurrent.RejectedExecutionException;
32 final class AutoFocusManager implements Camera.AutoFocusCallback {
34 private static final String TAG = AutoFocusManager.class.getSimpleName();
36 private static final long AUTO_FOCUS_INTERVAL_MS = 2000L;
37 private static final Collection<String> FOCUS_MODES_CALLING_AF;
39 FOCUS_MODES_CALLING_AF = new ArrayList<>(2);
40 FOCUS_MODES_CALLING_AF.add(Camera.Parameters.FOCUS_MODE_AUTO);
41 FOCUS_MODES_CALLING_AF.add(Camera.Parameters.FOCUS_MODE_MACRO);
44 private boolean stopped;
45 private boolean focusing;
46 private final boolean useAutoFocus;
47 private final Camera camera;
48 private AsyncTask<?,?,?> outstandingTask;
50 AutoFocusManager(Context context, Camera camera) {
52 SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
53 String currentFocusMode = camera.getParameters().getFocusMode();
55 sharedPrefs.getBoolean(PreferencesActivity.KEY_AUTO_FOCUS, true) &&
56 FOCUS_MODES_CALLING_AF.contains(currentFocusMode);
57 Log.i(TAG, "Current focus mode '" + currentFocusMode + "'; use auto focus? " + useAutoFocus);
62 public synchronized void onAutoFocus(boolean success, Camera theCamera) {
64 autoFocusAgainLater();
67 private synchronized void autoFocusAgainLater() {
68 if (!stopped && outstandingTask == null) {
69 AutoFocusTask newTask = new AutoFocusTask();
71 newTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
72 outstandingTask = newTask;
73 } catch (RejectedExecutionException ree) {
74 Log.w(TAG, "Could not request auto focus", ree);
79 synchronized void start() {
81 outstandingTask = null;
82 if (!stopped && !focusing) {
84 camera.autoFocus(this);
86 } catch (RuntimeException re) {
87 // Have heard RuntimeException reported in Android 4.0.x+; continue?
88 Log.w(TAG, "Unexpected exception while focusing", re);
89 // Try again later to keep cycle going
90 autoFocusAgainLater();
96 private synchronized void cancelOutstandingTask() {
97 if (outstandingTask != null) {
98 if (outstandingTask.getStatus() != AsyncTask.Status.FINISHED) {
99 outstandingTask.cancel(true);
101 outstandingTask = null;
105 synchronized void stop() {
108 cancelOutstandingTask();
109 // Doesn't hurt to call this even if not focusing
111 camera.cancelAutoFocus();
112 } catch (RuntimeException re) {
113 // Have heard RuntimeException reported in Android 4.0.x+; continue?
114 Log.w(TAG, "Unexpected exception while cancelling focusing", re);
119 private final class AutoFocusTask extends AsyncTask<Object,Object,Object> {
121 protected Object doInBackground(Object... voids) {
123 Thread.sleep(AUTO_FOCUS_INTERVAL_MS);
124 } catch (InterruptedException e) {