FocusOverlayManager.java revision d4a68ca4e34ad256cd4cd2f7b1faae234d240dfa
18872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb/* 28872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * Copyright (C) 2012 The Android Open Source Project 38872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * 48872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * Licensed under the Apache License, Version 2.0 (the "License"); 58872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * you may not use this file except in compliance with the License. 68872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * You may obtain a copy of the License at 78872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * 88872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * http://www.apache.org/licenses/LICENSE-2.0 98872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * 108872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * Unless required by applicable law or agreed to in writing, software 118872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * distributed under the License is distributed on an "AS IS" BASIS, 128872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * See the License for the specific language governing permissions and 148872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * limitations under the License. 158872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb */ 168872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 178872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbpackage com.android.camera; 188872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 198872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.annotation.TargetApi; 208872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.graphics.Matrix; 218872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.graphics.Rect; 228872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.graphics.RectF; 238872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.hardware.Camera.Area; 248872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.hardware.Camera.Parameters; 25638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberlingimport android.os.Build; 268872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.os.Handler; 278872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.os.Looper; 288872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.os.Message; 298872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.util.Log; 308872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 31357b7673f03d9b45d281d585cc3f4f87dc7d727bErin Dahlgrenimport com.android.camera.settings.SettingsManager; 32482de029dc20e0a577388a602985fb31c3200309Doris Liuimport com.android.camera.ui.PreviewStatusListener; 33b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kongimport com.android.camera.util.CameraUtil; 34cbd8267ee99e457f72822e8d8187b5e6823104f8Seth Raphaelimport com.android.camera.util.UsageStatistics; 358872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 36638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberlingimport java.util.ArrayList; 37638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberlingimport java.util.List; 38638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberling 398872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb/* A class that handles everything about focus in still picture mode. 408872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * This also handles the metering area because it is the same as focus area. 418872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * 428872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * The test cases: 438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (1) The camera has continuous autofocus. Move the camera. Take a picture when 448872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * CAF is not in progress. 458872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (2) The camera has continuous autofocus. Move the camera. Take a picture when 468872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * CAF is in progress. 478872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (3) The camera has face detection. Point the camera at some faces. Hold the 488872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * shutter. Release to take a picture. 498872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (4) The camera has face detection. Point the camera at some faces. Single tap 508872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * the shutter to take a picture. 518872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (5) The camera has autofocus. Single tap the shutter to take a picture. 528872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (6) The camera has autofocus. Hold the shutter. Release to take a picture. 538872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (7) The camera has no autofocus. Single tap the shutter and take a picture. 548872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (8) The camera has autofocus and supports focus area. Touch the screen to 558872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * trigger autofocus. Take a picture. 568872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (9) The camera has autofocus and supports focus area. Touch the screen to 578872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * trigger autofocus. Wait until it times out. 588872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (10) The camera has no autofocus and supports metering area. Touch the screen 598872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * to change metering area. 608872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb */ 612bacca795a1b0adb0daf515c43c48234b44bbba5Angus Kongpublic class FocusOverlayManager implements PreviewStatusListener.PreviewAreaChangedListener { 625850115399516c9186cc0a8231eb1b554f570441Sascha Haeberling private static final String TAG = "FocusOverlayManager"; 638872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 648872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private static final int RESET_TOUCH_FOCUS = 0; 65d4a68ca4e34ad256cd4cd2f7b1faae234d240dfaKevin Gabayan private static final int RESET_TOUCH_FOCUS_DELAY = 4000; 668872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 678872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private int mState = STATE_IDLE; 688872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private static final int STATE_IDLE = 0; // Focus is not active. 698872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private static final int STATE_FOCUSING = 1; // Focus is in progress. 708872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Focus is in progress and the camera should take a picture after focus finishes. 718872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private static final int STATE_FOCUSING_SNAP_ON_FINISH = 2; 728872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private static final int STATE_SUCCESS = 3; // Focus finishes and succeeds. 738872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private static final int STATE_FAIL = 4; // Focus finishes and fails. 748872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 758872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private boolean mInitialized; 768872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private boolean mFocusAreaSupported; 778872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private boolean mMeteringAreaSupported; 788872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private boolean mLockAeAwbNeeded; 798872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private boolean mAeAwbLock; 80a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling private final Matrix mMatrix; 818872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 828872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private boolean mMirror; // true if the camera is front-facing. 838872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private int mDisplayOrientation; 84a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling private List<Area> mFocusArea; // focus area in driver format 85a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling private List<Area> mMeteringArea; // metering area in driver format 868872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private String mFocusMode; 87a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling private final String[] mDefaultFocusModes; 888872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private String mOverrideFocusMode; 898872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private Parameters mParameters; 90a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling private final SettingsManager mSettingsManager; 91a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling private final Handler mHandler; 928872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb Listener mListener; 93e3de7223ee3fe56e097d68f50c5a59ae61370d65Michael Kolb private boolean mPreviousMoving; 948872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 95a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling private final FocusUI mUI; 9636ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu private final Rect mPreviewRect = new Rect(0, 0, 0, 0); 97d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 98d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb public interface FocusUI { 99d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb public boolean hasFaces(); 100d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb public void clearFocus(); 10110a035c93e2cb3ed65f59258fa4d0aca89555bcdDoris Liu public void setFocusPosition(int x, int y, boolean isAutoFocus); 102d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb public void onFocusStarted(); 103e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling public void onFocusSucceeded(); 104e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling public void onFocusFailed(); 105d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb public void pauseFaceDetection(); 106d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb public void resumeFaceDetection(); 107d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb } 108d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 1098872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public interface Listener { 1108872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void autoFocus(); 1118872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void cancelAutoFocus(); 1128872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public boolean capture(); 1138872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void startFaceDetection(); 1148872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void stopFaceDetection(); 1158872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void setFocusParameters(); 1168872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1178872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 1188872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private class MainHandler extends Handler { 1198872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public MainHandler(Looper looper) { 1208872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb super(looper); 1218872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1228872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 1238872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb @Override 1248872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void handleMessage(Message msg) { 1258872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb switch (msg.what) { 1268872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb case RESET_TOUCH_FOCUS: { 1278872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb cancelAutoFocus(); 1288872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mListener.startFaceDetection(); 1298872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb break; 1308872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1318872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1328872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1338872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1348872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 135357b7673f03d9b45d281d585cc3f4f87dc7d727bErin Dahlgren public FocusOverlayManager(SettingsManager settingsManager, 136357b7673f03d9b45d281d585cc3f4f87dc7d727bErin Dahlgren String[] defaultFocusModes, 1378872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb Parameters parameters, Listener listener, 138d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb boolean mirror, Looper looper, FocusUI ui) { 139357b7673f03d9b45d281d585cc3f4f87dc7d727bErin Dahlgren mSettingsManager = settingsManager; 1408872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mHandler = new MainHandler(looper); 1418872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mMatrix = new Matrix(); 1428872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mDefaultFocusModes = defaultFocusModes; 1438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb setParameters(parameters); 1448872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mListener = listener; 1458872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb setMirror(mirror); 146d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb mUI = ui; 1478872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1488872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 1498872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void setParameters(Parameters parameters) { 1508872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // parameters can only be null when onConfigurationChanged is called 1518872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // before camera is open. We will just return in this case, because 1528872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // parameters will be set again later with the right parameters after 1538872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // camera is open. 1548872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (parameters == null) return; 1558872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mParameters = parameters; 156b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong mFocusAreaSupported = CameraUtil.isFocusAreaSupported(parameters); 157b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong mMeteringAreaSupported = CameraUtil.isMeteringAreaSupported(parameters); 158b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong mLockAeAwbNeeded = (CameraUtil.isAutoExposureLockSupported(mParameters) || 159b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong CameraUtil.isAutoWhiteBalanceLockSupported(mParameters)); 1608872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1618872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 16236ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu /** This setter should be the only way to mutate mPreviewRect. */ 16336ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu public void setPreviewRect(Rect previewRect) { 16436ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu if (!mPreviewRect.equals(previewRect)) { 16536ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu mPreviewRect.set(previewRect); 1668872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb setMatrix(); 1678872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1688872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1698872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 170482de029dc20e0a577388a602985fb31c3200309Doris Liu @Override 1712bacca795a1b0adb0daf515c43c48234b44bbba5Angus Kong public void onPreviewAreaChanged(RectF previewArea) { 172a1ec04a9f9526418f5cb17a5afbfc48aca1e02d0Doris Liu setPreviewRect(CameraUtil.rectFToRect(previewArea)); 173482de029dc20e0a577388a602985fb31c3200309Doris Liu } 174482de029dc20e0a577388a602985fb31c3200309Doris Liu 17536ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu /** Returns a copy of mPreviewRect so that outside class cannot modify preview 17636ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu * rect except deliberately doing so through the setter. */ 17736ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu public Rect getPreviewRect() { 17836ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu return new Rect(mPreviewRect); 17936ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu } 18036ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu 1818872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void setMirror(boolean mirror) { 1828872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mMirror = mirror; 1838872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb setMatrix(); 1848872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1858872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 1868872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void setDisplayOrientation(int displayOrientation) { 1878872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mDisplayOrientation = displayOrientation; 1888872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb setMatrix(); 1898872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1908872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 1918872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private void setMatrix() { 19236ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu if (mPreviewRect.width() != 0 && mPreviewRect.height() != 0) { 1938872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb Matrix matrix = new Matrix(); 19436ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu CameraUtil.prepareMatrix(matrix, mMirror, mDisplayOrientation, getPreviewRect()); 1958872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // In face detection, the matrix converts the driver coordinates to UI 1968872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // coordinates. In tap focus, the inverted matrix converts the UI 1978872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // coordinates to driver coordinates. 1988872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb matrix.invert(mMatrix); 199d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb mInitialized = true; 2008872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2018872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2028872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 2038872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private void lockAeAwbIfNeeded() { 2048872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (mLockAeAwbNeeded && !mAeAwbLock) { 2058872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mAeAwbLock = true; 2068872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mListener.setFocusParameters(); 2078872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2088872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2098872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 2108872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private void unlockAeAwbIfNeeded() { 2118872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (mLockAeAwbNeeded && mAeAwbLock && (mState != STATE_FOCUSING_SNAP_ON_FINISH)) { 2128872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mAeAwbLock = false; 2138872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mListener.setFocusParameters(); 2148872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2158872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2168872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 2178872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void onShutterUp() { 2188872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (!mInitialized) return; 2198872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 2208872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (needAutoFocusCall()) { 2218872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // User releases half-pressed focus key. 2228872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (mState == STATE_FOCUSING || mState == STATE_SUCCESS 2238872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb || mState == STATE_FAIL) { 2248872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb cancelAutoFocus(); 2258872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2268872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2278872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 2288872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Unlock AE and AWB after cancelAutoFocus. Camera API does not 2298872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // guarantee setParameters can be called during autofocus. 2308872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb unlockAeAwbIfNeeded(); 2318872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2328872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 233eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong public void focusAndCapture() { 2348872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (!mInitialized) return; 2358872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 236eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong if (!needAutoFocusCall()) { 237eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong // Focus is not needed. 238eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong capture(); 239eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong } else if (mState == STATE_SUCCESS || mState == STATE_FAIL) { 240eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong // Focus is done already. 2418872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb capture(); 2428872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else if (mState == STATE_FOCUSING) { 243eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong // Still focusing and will not trigger snap upon finish. 2448872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mState = STATE_FOCUSING_SNAP_ON_FINISH; 2458872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else if (mState == STATE_IDLE) { 246eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong autoFocusAndCapture(); 2478872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2488872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2498872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 2508872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void onAutoFocus(boolean focused, boolean shutterButtonPressed) { 2518872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (mState == STATE_FOCUSING_SNAP_ON_FINISH) { 2528872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Take the picture no matter focus succeeds or fails. No need 2538872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // to play the AF sound if we're about to play the shutter 2548872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // sound. 2558872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (focused) { 2568872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mState = STATE_SUCCESS; 2578872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else { 2588872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mState = STATE_FAIL; 2598872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2608872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb updateFocusUI(); 2618872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb capture(); 2628872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else if (mState == STATE_FOCUSING) { 2638872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // This happens when (1) user is half-pressing the focus key or 2648872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // (2) touch focus is triggered. Play the focus tone. Do not 2658872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // take the picture now. 2668872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (focused) { 2678872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mState = STATE_SUCCESS; 2688872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else { 2698872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mState = STATE_FAIL; 2708872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2718872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb updateFocusUI(); 2728872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // If this is triggered by touch focus, cancel focus after a 2738872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // while. 274b05794393444ebd13bd24c2ecfb3fbd9963f688eMichael Kolb if (mFocusArea != null) { 2758872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mHandler.sendEmptyMessageDelayed(RESET_TOUCH_FOCUS, RESET_TOUCH_FOCUS_DELAY); 2768872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2778872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (shutterButtonPressed) { 2788872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Lock AE & AWB so users can half-press shutter and recompose. 2798872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb lockAeAwbIfNeeded(); 2808872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2818872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else if (mState == STATE_IDLE) { 2828872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // User has released the focus key before focus completes. 2838872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Do nothing. 2848872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2858872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2868872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 2878872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void onAutoFocusMoving(boolean moving) { 2888872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (!mInitialized) return; 289d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 290d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 2918872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Ignore if the camera has detected some faces. 292d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb if (mUI.hasFaces()) { 293d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb mUI.clearFocus(); 2948872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb return; 2958872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2968872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 2978872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Ignore if we have requested autofocus. This method only handles 2988872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // continuous autofocus. 2998872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (mState != STATE_IDLE) return; 3008872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 301e3de7223ee3fe56e097d68f50c5a59ae61370d65Michael Kolb // animate on false->true trasition only b/8219520 302e3de7223ee3fe56e097d68f50c5a59ae61370d65Michael Kolb if (moving && !mPreviousMoving) { 303ca4a5668c5bcda027bd896ebf17c8ef374e2ac75Doris Liu // Auto focus at the center of the preview. 30410a035c93e2cb3ed65f59258fa4d0aca89555bcdDoris Liu mUI.setFocusPosition(mPreviewRect.centerX(), mPreviewRect.centerY(), true); 305d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb mUI.onFocusStarted(); 306e3de7223ee3fe56e097d68f50c5a59ae61370d65Michael Kolb } else if (!moving) { 307e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling mUI.onFocusSucceeded(); 3088872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 309e3de7223ee3fe56e097d68f50c5a59ae61370d65Michael Kolb mPreviousMoving = moving; 3108872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 3118872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 312638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberling @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) 3130718d480a144ba0a44c07c48f90e85cf4ec669c6Michael Kolb private void initializeFocusAreas(int x, int y) { 3148872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (mFocusArea == null) { 315a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling mFocusArea = new ArrayList<Area>(); 3168872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mFocusArea.add(new Area(new Rect(), 1)); 3178872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 3188872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 3198872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Convert the coordinates to driver format. 320a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling calculateTapArea(x, y, 1f, mFocusArea.get(0).rect); 3218872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 3228872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 323638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberling @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) 3240718d480a144ba0a44c07c48f90e85cf4ec669c6Michael Kolb private void initializeMeteringAreas(int x, int y) { 3258872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (mMeteringArea == null) { 326a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling mMeteringArea = new ArrayList<Area>(); 3278872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mMeteringArea.add(new Area(new Rect(), 1)); 3288872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 3298872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 3308872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Convert the coordinates to driver format. 3318872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // AE area is bigger because exposure is sensitive and 3328872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // easy to over- or underexposure if area is too small. 333a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling calculateTapArea(x, y, 1.5f, mMeteringArea.get(0).rect); 3348872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 3358872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 3368872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void onSingleTapUp(int x, int y) { 3378872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (!mInitialized || mState == STATE_FOCUSING_SNAP_ON_FINISH) return; 3388872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 3395e09d01d80b64c81f21c57f1b99dd9dc1afed18dSeth Raphael UsageStatistics.tapToFocus(); 340cbd8267ee99e457f72822e8d8187b5e6823104f8Seth Raphael 3418872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Let users be able to cancel previous touch focus. 342b05794393444ebd13bd24c2ecfb3fbd9963f688eMichael Kolb if ((mFocusArea != null) && (mState == STATE_FOCUSING || 3438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mState == STATE_SUCCESS || mState == STATE_FAIL)) { 3448872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb cancelAutoFocus(); 3458872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 34636ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu if (mPreviewRect.width() == 0 || mPreviewRect.height() == 0) return; 347b05794393444ebd13bd24c2ecfb3fbd9963f688eMichael Kolb // Initialize variables. 3488872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Initialize mFocusArea. 3498872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (mFocusAreaSupported) { 3500718d480a144ba0a44c07c48f90e85cf4ec669c6Michael Kolb initializeFocusAreas(x, y); 3518872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 3528872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Initialize mMeteringArea. 3538872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (mMeteringAreaSupported) { 3540718d480a144ba0a44c07c48f90e85cf4ec669c6Michael Kolb initializeMeteringAreas(x, y); 3558872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 3568872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 3578872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Use margin to set the focus indicator to the touched area. 35810a035c93e2cb3ed65f59258fa4d0aca89555bcdDoris Liu mUI.setFocusPosition(x, y, false); 3598872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 3608872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Stop face detection because we want to specify focus and metering area. 3618872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mListener.stopFaceDetection(); 3628872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 3638872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Set the focus area and metering area. 3648872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mListener.setFocusParameters(); 3658872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (mFocusAreaSupported) { 3668872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb autoFocus(); 3678872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else { // Just show the indicator in all other cases. 3688872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb updateFocusUI(); 369d4a68ca4e34ad256cd4cd2f7b1faae234d240dfaKevin Gabayan // Reset the metering area in 4 seconds. 3708872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mHandler.removeMessages(RESET_TOUCH_FOCUS); 3718872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mHandler.sendEmptyMessageDelayed(RESET_TOUCH_FOCUS, RESET_TOUCH_FOCUS_DELAY); 3728872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 3738872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 3748872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 3758872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void onPreviewStarted() { 3768872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mState = STATE_IDLE; 3778872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 3788872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 3798872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void onPreviewStopped() { 3808872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // If auto focus was in progress, it would have been stopped. 3818872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mState = STATE_IDLE; 3828872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb resetTouchFocus(); 3838872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb updateFocusUI(); 3848872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 3858872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 3868872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void onCameraReleased() { 3878872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb onPreviewStopped(); 3888872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 3898872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 390eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong /** 391eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong * Triggers the autofocus and sets the specified state. 392eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong * 393eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong * @param focusingState The state to use when focus is in progress. 394eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong */ 395eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong private void autoFocus(int focusingState) { 3968872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb Log.v(TAG, "Start autofocus."); 3978872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mListener.autoFocus(); 398eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong mState = focusingState; 3998872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Pause the face view because the driver will keep sending face 4008872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // callbacks after the focus completes. 401d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb mUI.pauseFaceDetection(); 4028872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb updateFocusUI(); 4038872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mHandler.removeMessages(RESET_TOUCH_FOCUS); 4048872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 4058872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 406eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong /** 407eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong * Triggers the autofocus and set the state to indicate the focus is in 408eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong * progress. 409eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong */ 410eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong private void autoFocus() { 411eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong autoFocus(STATE_FOCUSING); 412eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong } 413eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong 414eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong /** 415eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong * Triggers the autofocus and set the state to which a capture will happen 416eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong * in the following autofocus callback. 417eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong */ 418eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong private void autoFocusAndCapture() { 419eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong autoFocus(STATE_FOCUSING_SNAP_ON_FINISH); 420eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong } 421eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong 4228872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private void cancelAutoFocus() { 4238872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb Log.v(TAG, "Cancel autofocus."); 4248872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Reset the tap area before calling mListener.cancelAutofocus. 4258872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Otherwise, focus mode stays at auto and the tap area passed to the 4268872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // driver is not reset. 4278872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb resetTouchFocus(); 4288872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mListener.cancelAutoFocus(); 429d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb mUI.resumeFaceDetection(); 4308872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mState = STATE_IDLE; 4318872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb updateFocusUI(); 4328872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mHandler.removeMessages(RESET_TOUCH_FOCUS); 4338872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 4348872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 4358872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private void capture() { 4368872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (mListener.capture()) { 4378872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mState = STATE_IDLE; 4388872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mHandler.removeMessages(RESET_TOUCH_FOCUS); 4398872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 4408872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 4418872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 4428872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public String getFocusMode() { 4438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (mOverrideFocusMode != null) return mOverrideFocusMode; 4444a40e126df5a77eaf44a52c73011cbfa91879b54Michael Kolb if (mParameters == null) return Parameters.FOCUS_MODE_AUTO; 4458872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb List<String> supportedFocusModes = mParameters.getSupportedFocusModes(); 4468872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 447b05794393444ebd13bd24c2ecfb3fbd9963f688eMichael Kolb if (mFocusAreaSupported && mFocusArea != null) { 4488872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Always use autofocus in tap-to-focus. 4498872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mFocusMode = Parameters.FOCUS_MODE_AUTO; 4508872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else { 4518872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // The default is continuous autofocus. 452635a4b8ba2b8684f95e5cb0aa35c244a06985f4cErin Dahlgren mFocusMode = mSettingsManager.get(SettingsManager.SETTING_FOCUS_MODE); 4538872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Try to find a supported focus mode from the default list. 4548872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (mFocusMode == null) { 4558872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb for (int i = 0; i < mDefaultFocusModes.length; i++) { 4568872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb String mode = mDefaultFocusModes[i]; 457b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong if (CameraUtil.isSupported(mode, supportedFocusModes)) { 4588872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mFocusMode = mode; 4598872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb break; 4608872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 4618872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 4628872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 4638872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 464b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong if (!CameraUtil.isSupported(mFocusMode, supportedFocusModes)) { 4658872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // For some reasons, the driver does not support the current 4668872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // focus mode. Fall back to auto. 467b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong if (CameraUtil.isSupported(Parameters.FOCUS_MODE_AUTO, 4688872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mParameters.getSupportedFocusModes())) { 4698872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mFocusMode = Parameters.FOCUS_MODE_AUTO; 4708872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else { 4718872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mFocusMode = mParameters.getFocusMode(); 4728872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 4738872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 4748872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb return mFocusMode; 4758872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 4768872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 477a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling public List<Area> getFocusAreas() { 4788872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb return mFocusArea; 4798872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 4808872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 481a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling public List<Area> getMeteringAreas() { 4828872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb return mMeteringArea; 4838872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 4848872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 4858872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void updateFocusUI() { 4868872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (!mInitialized) return; 4878872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Show only focus indicator or face indicator. 4888872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 4898872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (mState == STATE_IDLE) { 490b05794393444ebd13bd24c2ecfb3fbd9963f688eMichael Kolb if (mFocusArea == null) { 491d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb mUI.clearFocus(); 4928872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else { 4938872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Users touch on the preview and the indicator represents the 4948872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // metering area. Either focus area is not supported or 4958872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // autoFocus call is not required. 496d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb mUI.onFocusStarted(); 4978872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 4988872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else if (mState == STATE_FOCUSING || mState == STATE_FOCUSING_SNAP_ON_FINISH) { 499d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb mUI.onFocusStarted(); 5008872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else { 501b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong if (CameraUtil.FOCUS_MODE_CONTINUOUS_PICTURE.equals(mFocusMode)) { 5028872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // TODO: check HAL behavior and decide if this can be removed. 503e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling mUI.onFocusSucceeded(); 5048872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else if (mState == STATE_SUCCESS) { 505e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling mUI.onFocusSucceeded(); 5068872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else if (mState == STATE_FAIL) { 507e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling mUI.onFocusFailed(); 5088872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 5098872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 5108872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 5118872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 5128872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void resetTouchFocus() { 5138872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (!mInitialized) return; 5148872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 5158872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Put focus indicator to the center. clear reset position 516d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb mUI.clearFocus(); 5170718d480a144ba0a44c07c48f90e85cf4ec669c6Michael Kolb // Initialize mFocusArea. 518b05794393444ebd13bd24c2ecfb3fbd9963f688eMichael Kolb mFocusArea = null; 519b05794393444ebd13bd24c2ecfb3fbd9963f688eMichael Kolb mMeteringArea = null; 5208872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 5218872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 5220718d480a144ba0a44c07c48f90e85cf4ec669c6Michael Kolb private void calculateTapArea(int x, int y, float areaMultiple, Rect rect) { 523b3749f2071f866c43ea5f70de219f23157097077Doris Liu int areaSize = (int) (getAreaSize() * areaMultiple); 52436ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu int left = CameraUtil.clamp(x - areaSize / 2, mPreviewRect.left, 52536ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu mPreviewRect.right - areaSize); 52636ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu int top = CameraUtil.clamp(y - areaSize / 2, mPreviewRect.top, 52736ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu mPreviewRect.bottom - areaSize); 5288872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 529b3749f2071f866c43ea5f70de219f23157097077Doris Liu RectF rectF = new RectF(left, top, left + areaSize, top + areaSize); 5308872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mMatrix.mapRect(rectF); 531b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong CameraUtil.rectFToRect(rectF, rect); 5328872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 5338872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 534b3749f2071f866c43ea5f70de219f23157097077Doris Liu private int getAreaSize() { 535b3749f2071f866c43ea5f70de219f23157097077Doris Liu // Recommended focus area size from the manufacture is 1/8 of the image 5362ba03263340639635120be467f8cabec2889aa08Doris Liu // width (i.e. longer edge of the image) 53736ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu return Math.max(mPreviewRect.width(), mPreviewRect.height()) / 8; 538b3749f2071f866c43ea5f70de219f23157097077Doris Liu } 539b3749f2071f866c43ea5f70de219f23157097077Doris Liu 5408872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb /* package */ int getFocusState() { 5418872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb return mState; 5428872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 5438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 5448872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public boolean isFocusCompleted() { 5458872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb return mState == STATE_SUCCESS || mState == STATE_FAIL; 5468872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 5478872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 5488872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public boolean isFocusingSnapOnFinish() { 5498872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb return mState == STATE_FOCUSING_SNAP_ON_FINISH; 5508872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 5518872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 5528872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void removeMessages() { 5538872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mHandler.removeMessages(RESET_TOUCH_FOCUS); 5548872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 5558872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 5568872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void overrideFocusMode(String focusMode) { 5578872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mOverrideFocusMode = focusMode; 5588872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 5598872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 5608872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void setAeAwbLock(boolean lock) { 5618872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mAeAwbLock = lock; 5628872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 5638872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 5648872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public boolean getAeAwbLock() { 5658872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb return mAeAwbLock; 5668872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 5678872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 5688872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private boolean needAutoFocusCall() { 5698872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb String focusMode = getFocusMode(); 5708872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb return !(focusMode.equals(Parameters.FOCUS_MODE_INFINITY) 5718872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb || focusMode.equals(Parameters.FOCUS_MODE_FIXED) 5728872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb || focusMode.equals(Parameters.FOCUS_MODE_EDOF)); 5738872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 5748872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb} 575