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