d2327b0b6e6b3bb0b9b0ff6735262a99a712c508
[working/Evergreen.git] /
1 /*
2  * Copyright (C) 2010 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 package org.evergreen.android.barcodescan.camera;
17
18 import java.util.Collection;
19
20 import org.evergreen.android.barcodescan.PreferencesActivity;
21
22 import android.content.Context;
23 import android.content.SharedPreferences;
24 import android.graphics.Point;
25 import android.hardware.Camera;
26 import android.preference.PreferenceManager;
27 import android.util.Log;
28 import android.view.Display;
29 import android.view.WindowManager;
30
31 /**
32  * A class which deals with reading, parsing, and setting the camera parameters which are used to
33  * configure the camera hardware.
34  */
35 final class CameraConfigurationManager {
36
37   private static final String TAG = "CameraConfiguration";
38   private static final int MIN_PREVIEW_PIXELS = 320 * 240; // small screen
39   private static final int MAX_PREVIEW_PIXELS = 800 * 480; // large/HD screen
40
41   private final Context context;
42   private Point screenResolution;
43   private Point cameraResolution;
44
45   CameraConfigurationManager(Context context) {
46     this.context = context;
47   }
48
49   /**
50    * Reads, one time, values from the camera that are needed by the app.
51    */
52   void initFromCameraParameters(Camera camera) {
53     Camera.Parameters parameters = camera.getParameters();
54     WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
55     Display display = manager.getDefaultDisplay();
56     int width = display.getWidth();
57     int height = display.getHeight();
58     // We're landscape-only, and have apparently seen issues with display thinking it's portrait 
59     // when waking from sleep. If it's not landscape, assume it's mistaken and reverse them:
60     if (width < height) {
61       Log.i(TAG, "Display reports portrait orientation; assuming this is incorrect");
62       int temp = width;
63       width = height;
64       height = temp;
65     }
66     screenResolution = new Point(width, height);
67     Log.i(TAG, "Screen resolution: " + screenResolution);
68     cameraResolution = findBestPreviewSizeValue(parameters, screenResolution, false);
69     Log.i(TAG, "Camera resolution: " + cameraResolution);
70   }
71
72   void setDesiredCameraParameters(Camera camera) {
73     Camera.Parameters parameters = camera.getParameters();
74
75     if (parameters == null) {
76       Log.w(TAG, "Device error: no camera parameters are available. Proceeding without configuration.");
77       return;
78     }
79
80     SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
81
82     initializeTorch(parameters, prefs);
83     String focusMode = findSettableValue(parameters.getSupportedFocusModes(),
84                                          Camera.Parameters.FOCUS_MODE_AUTO,
85                                          Camera.Parameters.FOCUS_MODE_MACRO);
86     if (focusMode != null) {
87       parameters.setFocusMode(focusMode);
88     }
89
90     parameters.setPreviewSize(cameraResolution.x, cameraResolution.y);
91     camera.setParameters(parameters);
92   }
93
94   Point getCameraResolution() {
95     return cameraResolution;
96   }
97
98   Point getScreenResolution() {
99     return screenResolution;
100   }
101
102   void setTorch(Camera camera, boolean newSetting) {
103     Camera.Parameters parameters = camera.getParameters();
104     doSetTorch(parameters, newSetting);
105     camera.setParameters(parameters);
106     SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
107     boolean currentSetting = prefs.getBoolean(PreferencesActivity.KEY_FRONT_LIGHT, false);
108     if (currentSetting != newSetting) {
109       SharedPreferences.Editor editor = prefs.edit();
110       editor.putBoolean(PreferencesActivity.KEY_FRONT_LIGHT, newSetting);
111       editor.commit();
112     }
113   }
114
115   private static void initializeTorch(Camera.Parameters parameters, SharedPreferences prefs) {
116     boolean currentSetting = prefs.getBoolean(PreferencesActivity.KEY_FRONT_LIGHT, false);
117     doSetTorch(parameters, currentSetting);
118   }
119
120   private static void doSetTorch(Camera.Parameters parameters, boolean newSetting) {
121     String flashMode;
122     if (newSetting) {
123       flashMode = findSettableValue(parameters.getSupportedFlashModes(),
124                                     Camera.Parameters.FLASH_MODE_TORCH,
125                                     Camera.Parameters.FLASH_MODE_ON);
126     } else {
127       flashMode = findSettableValue(parameters.getSupportedFlashModes(),
128                                     Camera.Parameters.FLASH_MODE_OFF);
129     }
130     if (flashMode != null) {
131       parameters.setFlashMode(flashMode);
132     }
133   }
134
135   private static Point findBestPreviewSizeValue(Camera.Parameters parameters,
136                                                 Point screenResolution,
137                                                 boolean portrait) {
138     Point bestSize = null;
139     int diff = Integer.MAX_VALUE;
140     for (Camera.Size supportedPreviewSize : parameters.getSupportedPreviewSizes()) {
141       int pixels = supportedPreviewSize.height * supportedPreviewSize.width;
142       if (pixels < MIN_PREVIEW_PIXELS || pixels > MAX_PREVIEW_PIXELS) {
143         continue;
144       }
145       int supportedWidth = portrait ? supportedPreviewSize.height : supportedPreviewSize.width;
146       int supportedHeight = portrait ? supportedPreviewSize.width : supportedPreviewSize.height;
147       int newDiff = Math.abs(screenResolution.x * supportedHeight - supportedWidth * screenResolution.y);
148       if (newDiff == 0) {
149         bestSize = new Point(supportedWidth, supportedHeight);
150         break;
151       }
152       if (newDiff < diff) {
153         bestSize = new Point(supportedWidth, supportedHeight);
154         diff = newDiff;
155       }
156     }
157     if (bestSize == null) {
158       Camera.Size defaultSize = parameters.getPreviewSize();
159       bestSize = new Point(defaultSize.width, defaultSize.height);
160     }
161     return bestSize;
162   }
163
164   private static String findSettableValue(Collection<String> supportedValues,
165                                           String... desiredValues) {
166     Log.i(TAG, "Supported values: " + supportedValues);
167     String result = null;
168     if (supportedValues != null) {
169       for (String desiredValue : desiredValues) {
170         if (supportedValues.contains(desiredValue)) {
171           result = desiredValue;
172           break;
173         }
174       }
175     }
176     Log.i(TAG, "Settable value: " + result);
177     return result;
178   }
179
180 }