1b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb/* 2b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * Copyright (C) 2012 The Android Open Source Project 3b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * 4b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * Licensed under the Apache License, Version 2.0 (the "License"); 5b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * you may not use this file except in compliance with the License. 6b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * You may obtain a copy of the License at 7b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * 8b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * http://www.apache.org/licenses/LICENSE-2.0 9b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * 10b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * Unless required by applicable law or agreed to in writing, software 11b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * distributed under the License is distributed on an "AS IS" BASIS, 12b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * See the License for the specific language governing permissions and 14b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * limitations under the License. 15b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb */ 16b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 17b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbpackage com.android.camera; 18b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 19b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport android.annotation.TargetApi; 20b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport android.graphics.Matrix; 21b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport android.graphics.Rect; 22b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport android.graphics.RectF; 23b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport android.hardware.Camera.Area; 24b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport android.hardware.Camera.Parameters; 25b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport android.os.Handler; 26b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport android.os.Looper; 27b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport android.os.Message; 28b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport android.util.Log; 29b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 30b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport com.android.camera.ui.FaceView; 31b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport com.android.camera.ui.FocusIndicator; 328042e7045f3e11dd49d40eebe603eb5fe12d711aMichael Kolbimport com.android.camera.ui.PieRenderer; 33b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport com.android.gallery3d.common.ApiHelper; 34b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 35b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport java.util.ArrayList; 36b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport java.util.List; 37b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 38b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb/* A class that handles everything about focus in still picture mode. 39b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * This also handles the metering area because it is the same as focus area. 40b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * 41b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * The test cases: 42b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * (1) The camera has continuous autofocus. Move the camera. Take a picture when 43b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * CAF is not in progress. 44b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * (2) The camera has continuous autofocus. Move the camera. Take a picture when 45b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * CAF is in progress. 46b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * (3) The camera has face detection. Point the camera at some faces. Hold the 47b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * shutter. Release to take a picture. 48b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * (4) The camera has face detection. Point the camera at some faces. Single tap 49b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * the shutter to take a picture. 50b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * (5) The camera has autofocus. Single tap the shutter to take a picture. 51b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * (6) The camera has autofocus. Hold the shutter. Release to take a picture. 52b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * (7) The camera has no autofocus. Single tap the shutter and take a picture. 53b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * (8) The camera has autofocus and supports focus area. Touch the screen to 54b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * trigger autofocus. Take a picture. 55b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * (9) The camera has autofocus and supports focus area. Touch the screen to 56b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * trigger autofocus. Wait until it times out. 57b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * (10) The camera has no autofocus and supports metering area. Touch the screen 58b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * to change metering area. 59b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb */ 60b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbpublic class FocusOverlayManager { 61b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private static final String TAG = "CAM_FocusManager"; 62b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 63b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private static final int RESET_TOUCH_FOCUS = 0; 64b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private static final int RESET_TOUCH_FOCUS_DELAY = 3000; 65b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 66b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private int mState = STATE_IDLE; 67b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private static final int STATE_IDLE = 0; // Focus is not active. 68b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private static final int STATE_FOCUSING = 1; // Focus is in progress. 69b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // Focus is in progress and the camera should take a picture after focus finishes. 70b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private static final int STATE_FOCUSING_SNAP_ON_FINISH = 2; 71b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private static final int STATE_SUCCESS = 3; // Focus finishes and succeeds. 72b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private static final int STATE_FAIL = 4; // Focus finishes and fails. 73b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 74b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private boolean mInitialized; 75b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private boolean mFocusAreaSupported; 76b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private boolean mMeteringAreaSupported; 77b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private boolean mLockAeAwbNeeded; 78b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private boolean mAeAwbLock; 79b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private Matrix mMatrix; 80b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 818042e7045f3e11dd49d40eebe603eb5fe12d711aMichael Kolb private PieRenderer mPieRenderer; 82b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 83b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private int mPreviewWidth; // The width of the preview frame layout. 84b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private int mPreviewHeight; // The height of the preview frame layout. 85b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private boolean mMirror; // true if the camera is front-facing. 86b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private int mDisplayOrientation; 87b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private FaceView mFaceView; 88b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private List<Object> mFocusArea; // focus area in driver format 89b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private List<Object> mMeteringArea; // metering area in driver format 90b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private String mFocusMode; 91b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private String[] mDefaultFocusModes; 92b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private String mOverrideFocusMode; 93b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private Parameters mParameters; 94b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private ComboPreferences mPreferences; 95b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private Handler mHandler; 96b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb Listener mListener; 97b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 98b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public interface Listener { 99b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public void autoFocus(); 100b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public void cancelAutoFocus(); 101b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public boolean capture(); 102b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public void startFaceDetection(); 103b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public void stopFaceDetection(); 104b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public void setFocusParameters(); 105b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 106b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 107b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private class MainHandler extends Handler { 108b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public MainHandler(Looper looper) { 109b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb super(looper); 110b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 111b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 112b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb @Override 113b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public void handleMessage(Message msg) { 114b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb switch (msg.what) { 115b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb case RESET_TOUCH_FOCUS: { 116b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb cancelAutoFocus(); 117b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mListener.startFaceDetection(); 118b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb break; 119b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 120b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 121b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 122b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 123b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 124b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public FocusOverlayManager(ComboPreferences preferences, String[] defaultFocusModes, 125b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb Parameters parameters, Listener listener, 126b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb boolean mirror, Looper looper) { 127b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mHandler = new MainHandler(looper); 128b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mMatrix = new Matrix(); 129b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mPreferences = preferences; 130b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mDefaultFocusModes = defaultFocusModes; 131b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb setParameters(parameters); 132b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mListener = listener; 133b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb setMirror(mirror); 134b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 135b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 1368042e7045f3e11dd49d40eebe603eb5fe12d711aMichael Kolb public void setFocusRenderer(PieRenderer renderer) { 1378042e7045f3e11dd49d40eebe603eb5fe12d711aMichael Kolb mPieRenderer = renderer; 13838a6c24485d36651b93d5935bfbaf3cd367885e7Michael Kolb mInitialized = (mMatrix != null); 139b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 140b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 141b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public void setParameters(Parameters parameters) { 142b7fc87328c1ee793e6c66ff6af45495268f954baDoris Liu // parameters can only be null when onConfigurationChanged is called 143b7fc87328c1ee793e6c66ff6af45495268f954baDoris Liu // before camera is open. We will just return in this case, because 144b7fc87328c1ee793e6c66ff6af45495268f954baDoris Liu // parameters will be set again later with the right parameters after 145b7fc87328c1ee793e6c66ff6af45495268f954baDoris Liu // camera is open. 146b7fc87328c1ee793e6c66ff6af45495268f954baDoris Liu if (parameters == null) return; 147b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mParameters = parameters; 148b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mFocusAreaSupported = Util.isFocusAreaSupported(parameters); 149b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mMeteringAreaSupported = Util.isMeteringAreaSupported(parameters); 150b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mLockAeAwbNeeded = (Util.isAutoExposureLockSupported(mParameters) || 151b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb Util.isAutoWhiteBalanceLockSupported(mParameters)); 152b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 153b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 154b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public void setPreviewSize(int previewWidth, int previewHeight) { 155b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (mPreviewWidth != previewWidth || mPreviewHeight != previewHeight) { 156b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mPreviewWidth = previewWidth; 157b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mPreviewHeight = previewHeight; 158b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb setMatrix(); 159b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 160b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 161b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 162b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public void setMirror(boolean mirror) { 163b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mMirror = mirror; 164b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb setMatrix(); 165b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 166b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 167b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public void setDisplayOrientation(int displayOrientation) { 168b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mDisplayOrientation = displayOrientation; 169b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb setMatrix(); 170b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 171b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 172b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public void setFaceView(FaceView faceView) { 173b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mFaceView = faceView; 174b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 175b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 176b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private void setMatrix() { 177b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (mPreviewWidth != 0 && mPreviewHeight != 0) { 178b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb Matrix matrix = new Matrix(); 179b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb Util.prepareMatrix(matrix, mMirror, mDisplayOrientation, 180b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mPreviewWidth, mPreviewHeight); 181b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // In face detection, the matrix converts the driver coordinates to UI 182b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // coordinates. In tap focus, the inverted matrix converts the UI 183b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // coordinates to driver coordinates. 184b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb matrix.invert(mMatrix); 1858042e7045f3e11dd49d40eebe603eb5fe12d711aMichael Kolb mInitialized = (mPieRenderer != null); 186b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 187b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 188b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 189bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li private void lockAeAwbIfNeeded() { 190b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (mLockAeAwbNeeded && !mAeAwbLock) { 191b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mAeAwbLock = true; 192b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mListener.setFocusParameters(); 193b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 194bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li } 195bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li 196bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li private void unlockAeAwbIfNeeded() { 197bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li if (mLockAeAwbNeeded && mAeAwbLock && (mState != STATE_FOCUSING_SNAP_ON_FINISH)) { 198bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li mAeAwbLock = false; 199bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li mListener.setFocusParameters(); 200bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li } 201bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li } 202b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 203bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li public void onShutterDown() { 204bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li if (!mInitialized) return; 205bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li 206bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li boolean autoFocusCalled = false; 207b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (needAutoFocusCall()) { 208b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // Do not focus if touch focus has been triggered. 209b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (mState != STATE_SUCCESS && mState != STATE_FAIL) { 210b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb autoFocus(); 211bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li autoFocusCalled = true; 212b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 213b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 214bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li 215bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li if (!autoFocusCalled) lockAeAwbIfNeeded(); 216b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 217b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 218b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public void onShutterUp() { 219b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (!mInitialized) return; 220b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 221b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (needAutoFocusCall()) { 222b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // User releases half-pressed focus key. 223b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (mState == STATE_FOCUSING || mState == STATE_SUCCESS 224b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb || mState == STATE_FAIL) { 225b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb cancelAutoFocus(); 226b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 227b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 228b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 229b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // Unlock AE and AWB after cancelAutoFocus. Camera API does not 230b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // guarantee setParameters can be called during autofocus. 231bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li unlockAeAwbIfNeeded(); 232b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 233b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 234b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public void doSnap() { 235b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (!mInitialized) return; 236b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 237b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // If the user has half-pressed the shutter and focus is completed, we 238b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // can take the photo right away. If the focus mode is infinity, we can 239b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // also take the photo. 240b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (!needAutoFocusCall() || (mState == STATE_SUCCESS || mState == STATE_FAIL)) { 241b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb capture(); 242b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } else if (mState == STATE_FOCUSING) { 243b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // Half pressing the shutter (i.e. the focus button event) will 244b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // already have requested AF for us, so just request capture on 245b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // focus here. 246b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mState = STATE_FOCUSING_SNAP_ON_FINISH; 247b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } else if (mState == STATE_IDLE) { 248b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // We didn't do focus. This can happen if the user press focus key 249b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // while the snapshot is still in progress. The user probably wants 250b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // the next snapshot as soon as possible, so we just do a snapshot 251b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // without focusing again. 252b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb capture(); 253b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 254b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 255b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 256bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li public void onAutoFocus(boolean focused, boolean shutterButtonPressed) { 257b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (mState == STATE_FOCUSING_SNAP_ON_FINISH) { 258b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // Take the picture no matter focus succeeds or fails. No need 259b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // to play the AF sound if we're about to play the shutter 260b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // sound. 261b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (focused) { 262b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mState = STATE_SUCCESS; 263b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } else { 264b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mState = STATE_FAIL; 265b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 266b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb updateFocusUI(); 267b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb capture(); 268b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } else if (mState == STATE_FOCUSING) { 269b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // This happens when (1) user is half-pressing the focus key or 270b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // (2) touch focus is triggered. Play the focus tone. Do not 271b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // take the picture now. 272b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (focused) { 273b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mState = STATE_SUCCESS; 274b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } else { 275b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mState = STATE_FAIL; 276b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 277b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb updateFocusUI(); 278b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // If this is triggered by touch focus, cancel focus after a 279b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // while. 280b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (mFocusArea != null) { 281b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mHandler.sendEmptyMessageDelayed(RESET_TOUCH_FOCUS, RESET_TOUCH_FOCUS_DELAY); 282b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 283bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li if (shutterButtonPressed) { 284bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li // Lock AE & AWB so users can half-press shutter and recompose. 285bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li lockAeAwbIfNeeded(); 286bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li } 287b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } else if (mState == STATE_IDLE) { 288b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // User has released the focus key before focus completes. 289b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // Do nothing. 290b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 291b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 292b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 293b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public void onAutoFocusMoving(boolean moving) { 294fe44832abc2e9fb937ac5bd9c65e103397992e8cMichael Kolb if (!mInitialized) return; 295b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // Ignore if the camera has detected some faces. 296630d255bdeeb1a13a71b0ecda0a38d6546c351e2John Reck if (mFaceView != null && mFaceView.faceExists()) { 297630d255bdeeb1a13a71b0ecda0a38d6546c351e2John Reck mPieRenderer.clear(); 298630d255bdeeb1a13a71b0ecda0a38d6546c351e2John Reck return; 299630d255bdeeb1a13a71b0ecda0a38d6546c351e2John Reck } 300b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 301b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // Ignore if we have requested autofocus. This method only handles 302b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // continuous autofocus. 303b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (mState != STATE_IDLE) return; 304b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 305b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (moving) { 3068042e7045f3e11dd49d40eebe603eb5fe12d711aMichael Kolb mPieRenderer.showStart(); 307b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } else { 3088042e7045f3e11dd49d40eebe603eb5fe12d711aMichael Kolb mPieRenderer.showSuccess(true); 309b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 310b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 311b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 312b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH) 313b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private void initializeFocusAreas(int focusWidth, int focusHeight, 314b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb int x, int y, int previewWidth, int previewHeight) { 315b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (mFocusArea == null) { 316b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mFocusArea = new ArrayList<Object>(); 317b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mFocusArea.add(new Area(new Rect(), 1)); 318b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 319b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 320b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // Convert the coordinates to driver format. 321b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb calculateTapArea(focusWidth, focusHeight, 1f, x, y, previewWidth, previewHeight, 322b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb ((Area) mFocusArea.get(0)).rect); 323b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 324b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 325b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH) 326b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private void initializeMeteringAreas(int focusWidth, int focusHeight, 327b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb int x, int y, int previewWidth, int previewHeight) { 328b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (mMeteringArea == null) { 329b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mMeteringArea = new ArrayList<Object>(); 330b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mMeteringArea.add(new Area(new Rect(), 1)); 331b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 332b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 333b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // Convert the coordinates to driver format. 334b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // AE area is bigger because exposure is sensitive and 335b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // easy to over- or underexposure if area is too small. 336b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb calculateTapArea(focusWidth, focusHeight, 1.5f, x, y, previewWidth, previewHeight, 337b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb ((Area) mMeteringArea.get(0)).rect); 338b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 339b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 340b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public void onSingleTapUp(int x, int y) { 341b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (!mInitialized || mState == STATE_FOCUSING_SNAP_ON_FINISH) return; 342b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 343b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // Let users be able to cancel previous touch focus. 344b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if ((mFocusArea != null) && (mState == STATE_FOCUSING || 345b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mState == STATE_SUCCESS || mState == STATE_FAIL)) { 346b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb cancelAutoFocus(); 347b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 348b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // Initialize variables. 3498042e7045f3e11dd49d40eebe603eb5fe12d711aMichael Kolb int focusWidth = mPieRenderer.getSize(); 3508042e7045f3e11dd49d40eebe603eb5fe12d711aMichael Kolb int focusHeight = mPieRenderer.getSize(); 3518042e7045f3e11dd49d40eebe603eb5fe12d711aMichael Kolb if (focusWidth == 0 || mPieRenderer.getWidth() == 0 3528042e7045f3e11dd49d40eebe603eb5fe12d711aMichael Kolb || mPieRenderer.getHeight() == 0) return; 353b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb int previewWidth = mPreviewWidth; 354b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb int previewHeight = mPreviewHeight; 355b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // Initialize mFocusArea. 356b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (mFocusAreaSupported) { 357b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb initializeFocusAreas( 358b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb focusWidth, focusHeight, x, y, previewWidth, previewHeight); 359b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 360b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // Initialize mMeteringArea. 361b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (mMeteringAreaSupported) { 362b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb initializeMeteringAreas( 363b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb focusWidth, focusHeight, x, y, previewWidth, previewHeight); 364b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 365b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 366b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // Use margin to set the focus indicator to the touched area. 36717a04fb7378effcef5728b5b21442a59fb88572dMichael Kolb mPieRenderer.setFocus(x, y); 368b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 369b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // Stop face detection because we want to specify focus and metering area. 370b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mListener.stopFaceDetection(); 371b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 372b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // Set the focus area and metering area. 373b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mListener.setFocusParameters(); 374b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (mFocusAreaSupported) { 375b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb autoFocus(); 376b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } else { // Just show the indicator in all other cases. 377b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb updateFocusUI(); 378b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // Reset the metering area in 3 seconds. 379b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mHandler.removeMessages(RESET_TOUCH_FOCUS); 380b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mHandler.sendEmptyMessageDelayed(RESET_TOUCH_FOCUS, RESET_TOUCH_FOCUS_DELAY); 381b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 382b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 383b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 384b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public void onPreviewStarted() { 385b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mState = STATE_IDLE; 386b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 387b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 388b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public void onPreviewStopped() { 3890505273644c4c3aaf908bcda54c6d576a3ebfae8Wu-cheng Li // If auto focus was in progress, it would have been stopped. 390b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mState = STATE_IDLE; 391b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb resetTouchFocus(); 392b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb updateFocusUI(); 393b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 394b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 395b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public void onCameraReleased() { 396b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb onPreviewStopped(); 397b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 398b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 399b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private void autoFocus() { 400b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb Log.v(TAG, "Start autofocus."); 401b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mListener.autoFocus(); 402b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mState = STATE_FOCUSING; 403b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // Pause the face view because the driver will keep sending face 404b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // callbacks after the focus completes. 405b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (mFaceView != null) mFaceView.pause(); 406b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb updateFocusUI(); 407b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mHandler.removeMessages(RESET_TOUCH_FOCUS); 408b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 409b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 410b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private void cancelAutoFocus() { 411b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb Log.v(TAG, "Cancel autofocus."); 412b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 413b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // Reset the tap area before calling mListener.cancelAutofocus. 414b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // Otherwise, focus mode stays at auto and the tap area passed to the 415b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // driver is not reset. 416b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb resetTouchFocus(); 417b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mListener.cancelAutoFocus(); 418b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (mFaceView != null) mFaceView.resume(); 419b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mState = STATE_IDLE; 420b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb updateFocusUI(); 421b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mHandler.removeMessages(RESET_TOUCH_FOCUS); 422b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 423b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 424b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private void capture() { 425b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (mListener.capture()) { 426b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mState = STATE_IDLE; 427b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mHandler.removeMessages(RESET_TOUCH_FOCUS); 428b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 429b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 430b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 431b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public String getFocusMode() { 432b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (mOverrideFocusMode != null) return mOverrideFocusMode; 433b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb List<String> supportedFocusModes = mParameters.getSupportedFocusModes(); 434b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 435b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (mFocusAreaSupported && mFocusArea != null) { 436b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // Always use autofocus in tap-to-focus. 437b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mFocusMode = Parameters.FOCUS_MODE_AUTO; 438b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } else { 439b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // The default is continuous autofocus. 440b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mFocusMode = mPreferences.getString( 441b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb CameraSettings.KEY_FOCUS_MODE, null); 442b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 443b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // Try to find a supported focus mode from the default list. 444b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (mFocusMode == null) { 445b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb for (int i = 0; i < mDefaultFocusModes.length; i++) { 446b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb String mode = mDefaultFocusModes[i]; 447b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (Util.isSupported(mode, supportedFocusModes)) { 448b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mFocusMode = mode; 449b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb break; 450b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 451b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 452b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 453b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 454b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (!Util.isSupported(mFocusMode, supportedFocusModes)) { 455b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // For some reasons, the driver does not support the current 456b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // focus mode. Fall back to auto. 457b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (Util.isSupported(Parameters.FOCUS_MODE_AUTO, 458b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mParameters.getSupportedFocusModes())) { 459b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mFocusMode = Parameters.FOCUS_MODE_AUTO; 460b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } else { 461b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mFocusMode = mParameters.getFocusMode(); 462b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 463b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 464b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb return mFocusMode; 465b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 466b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 467b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public List getFocusAreas() { 468b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb return mFocusArea; 469b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 470b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 471b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public List getMeteringAreas() { 472b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb return mMeteringArea; 473b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 474b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 475b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public void updateFocusUI() { 476b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (!mInitialized) return; 477b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // Show only focus indicator or face indicator. 478b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb boolean faceExists = (mFaceView != null && mFaceView.faceExists()); 4798042e7045f3e11dd49d40eebe603eb5fe12d711aMichael Kolb FocusIndicator focusIndicator = (faceExists) ? mFaceView : mPieRenderer; 480b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 481b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (mState == STATE_IDLE) { 482b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (mFocusArea == null) { 483b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb focusIndicator.clear(); 484b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } else { 485b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // Users touch on the preview and the indicator represents the 486b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // metering area. Either focus area is not supported or 487b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // autoFocus call is not required. 488b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb focusIndicator.showStart(); 489b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 490b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } else if (mState == STATE_FOCUSING || mState == STATE_FOCUSING_SNAP_ON_FINISH) { 491b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb focusIndicator.showStart(); 492b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } else { 493b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (Util.FOCUS_MODE_CONTINUOUS_PICTURE.equals(mFocusMode)) { 494b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // TODO: check HAL behavior and decide if this can be removed. 495b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb focusIndicator.showSuccess(false); 496b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } else if (mState == STATE_SUCCESS) { 497b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb focusIndicator.showSuccess(false); 498b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } else if (mState == STATE_FAIL) { 499b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb focusIndicator.showFail(false); 500b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 501b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 502b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 503b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 504b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public void resetTouchFocus() { 505b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (!mInitialized) return; 506b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 507b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb // Put focus indicator to the center. clear reset position 5088042e7045f3e11dd49d40eebe603eb5fe12d711aMichael Kolb mPieRenderer.clear(); 509b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 510b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mFocusArea = null; 511b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mMeteringArea = null; 512b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 513b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 514b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private void calculateTapArea(int focusWidth, int focusHeight, float areaMultiple, 515b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb int x, int y, int previewWidth, int previewHeight, Rect rect) { 516b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb int areaWidth = (int) (focusWidth * areaMultiple); 517b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb int areaHeight = (int) (focusHeight * areaMultiple); 518b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb int left = Util.clamp(x - areaWidth / 2, 0, previewWidth - areaWidth); 519b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb int top = Util.clamp(y - areaHeight / 2, 0, previewHeight - areaHeight); 520b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 521b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb RectF rectF = new RectF(left, top, left + areaWidth, top + areaHeight); 522b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mMatrix.mapRect(rectF); 523b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb Util.rectFToRect(rectF, rect); 524b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 525b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 5265c7a93d0c29cfd9480817ec8a1c83795199b13edMangesh Ghiware /* package */ int getFocusState() { 5275c7a93d0c29cfd9480817ec8a1c83795199b13edMangesh Ghiware return mState; 5285c7a93d0c29cfd9480817ec8a1c83795199b13edMangesh Ghiware } 5295c7a93d0c29cfd9480817ec8a1c83795199b13edMangesh Ghiware 530b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public boolean isFocusCompleted() { 531b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb return mState == STATE_SUCCESS || mState == STATE_FAIL; 532b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 533b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 534b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public boolean isFocusingSnapOnFinish() { 535b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb return mState == STATE_FOCUSING_SNAP_ON_FINISH; 536b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 537b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 538b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public void removeMessages() { 539b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mHandler.removeMessages(RESET_TOUCH_FOCUS); 540b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 541b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 542b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public void overrideFocusMode(String focusMode) { 543b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mOverrideFocusMode = focusMode; 544b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 545b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 546b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public void setAeAwbLock(boolean lock) { 547b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mAeAwbLock = lock; 548b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 549b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 550b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public boolean getAeAwbLock() { 551b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb return mAeAwbLock; 552b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 553b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 554b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private boolean needAutoFocusCall() { 555b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb String focusMode = getFocusMode(); 556b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb return !(focusMode.equals(Parameters.FOCUS_MODE_INFINITY) 557b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb || focusMode.equals(Parameters.FOCUS_MODE_FIXED) 558b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb || focusMode.equals(Parameters.FOCUS_MODE_EDOF)); 559b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 560b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb} 561