]> rtime.felk.cvut.cz Git - hornmich/skoda-qr-demo.git/blob - BarCodeScanner/mobile/src/main/java/cz/cvut/fel/dce/barcodescanner/camera/AutoFocusManager.java
Initial commit
[hornmich/skoda-qr-demo.git] / BarCodeScanner / mobile / src / main / java / cz / cvut / fel / dce / barcodescanner / camera / AutoFocusManager.java
1 /*
2  * Copyright (C) 2012 ZXing authors
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package cz.cvut.fel.dce.barcodescanner.camera;
18
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;
25
26 import cz.cvut.fel.dce.barcodescanner.PreferencesActivity;
27
28 import java.util.ArrayList;
29 import java.util.Collection;
30 import java.util.concurrent.RejectedExecutionException;
31
32 final class AutoFocusManager implements Camera.AutoFocusCallback {
33
34   private static final String TAG = AutoFocusManager.class.getSimpleName();
35
36   private static final long AUTO_FOCUS_INTERVAL_MS = 2000L;
37   private static final Collection<String> FOCUS_MODES_CALLING_AF;
38   static {
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);
42   }
43
44   private boolean stopped;
45   private boolean focusing;
46   private final boolean useAutoFocus;
47   private final Camera camera;
48   private AsyncTask<?,?,?> outstandingTask;
49
50   AutoFocusManager(Context context, Camera camera) {
51     this.camera = camera;
52     SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
53     String currentFocusMode = camera.getParameters().getFocusMode();
54     useAutoFocus =
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);
58     start();
59   }
60
61   @Override
62   public synchronized void onAutoFocus(boolean success, Camera theCamera) {
63     focusing = false;
64     autoFocusAgainLater();
65   }
66
67   private synchronized void autoFocusAgainLater() {
68     if (!stopped && outstandingTask == null) {
69       AutoFocusTask newTask = new AutoFocusTask();
70       try {
71         newTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
72         outstandingTask = newTask;
73       } catch (RejectedExecutionException ree) {
74         Log.w(TAG, "Could not request auto focus", ree);
75       }
76     }
77   }
78
79   synchronized void start() {
80     if (useAutoFocus) {
81       outstandingTask = null;
82       if (!stopped && !focusing) {
83         try {
84           camera.autoFocus(this);
85           focusing = true;
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();
91         }
92       }
93     }
94   }
95
96   private synchronized void cancelOutstandingTask() {
97     if (outstandingTask != null) {
98       if (outstandingTask.getStatus() != AsyncTask.Status.FINISHED) {
99         outstandingTask.cancel(true);
100       }
101       outstandingTask = null;
102     }
103   }
104
105   synchronized void stop() {
106     stopped = true;
107     if (useAutoFocus) {
108       cancelOutstandingTask();
109       // Doesn't hurt to call this even if not focusing
110       try {
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);
115       }
116     }
117   }
118
119   private final class AutoFocusTask extends AsyncTask<Object,Object,Object> {
120     @Override
121     protected Object doInBackground(Object... voids) {
122       try {
123         Thread.sleep(AUTO_FOCUS_INTERVAL_MS);
124       } catch (InterruptedException e) {
125         // continue
126       }
127       start();
128       return null;
129     }
130   }
131
132 }