FocusOverlayManager.java revision 516c11a6885f6e524927bd369567f5bbd592f8ef
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 Kolb 3088289047ba6928e317d17f2e1d4b013693545c67Angus Kongimport com.android.camera.cameradevice.CameraCapabilities; 3188289047ba6928e317d17f2e1d4b013693545c67Angus Kongimport com.android.camera.cameradevice.CameraCapabilitiesFactory; 325596b4c902dcb685928b43678f428746ca5ffd08Angus Kongimport com.android.camera.debug.Log; 33357b7673f03d9b45d281d585cc3f4f87dc7d727bErin Dahlgrenimport com.android.camera.settings.SettingsManager; 34482de029dc20e0a577388a602985fb31c3200309Doris Liuimport com.android.camera.ui.PreviewStatusListener; 35b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kongimport com.android.camera.util.CameraUtil; 368872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 37638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberlingimport java.util.ArrayList; 38638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberlingimport java.util.List; 39638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberling 408872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb/* A class that handles everything about focus in still picture mode. 418872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * This also handles the metering area because it is the same as focus area. 428872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * 438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * The test cases: 448872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (1) The camera has continuous autofocus. Move the camera. Take a picture when 458872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * CAF is not in progress. 468872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (2) The camera has continuous autofocus. Move the camera. Take a picture when 478872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * CAF is in progress. 488872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (3) The camera has face detection. Point the camera at some faces. Hold the 498872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * shutter. Release to take a picture. 508872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (4) The camera has face detection. Point the camera at some faces. Single tap 518872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * the shutter to take a picture. 528872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (5) The camera has autofocus. Single tap the shutter to take a picture. 538872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (6) The camera has autofocus. Hold the shutter. Release to take a picture. 548872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (7) The camera has no autofocus. Single tap the shutter and take a picture. 558872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (8) The camera has autofocus and supports focus area. Touch the screen to 568872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * trigger autofocus. Take a picture. 578872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (9) The camera has autofocus and supports focus area. Touch the screen to 588872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * trigger autofocus. Wait until it times out. 598872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (10) The camera has no autofocus and supports metering area. Touch the screen 608872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * to change metering area. 618872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb */ 62516c11a6885f6e524927bd369567f5bbd592f8efKevin Gabayanpublic class FocusOverlayManager implements PreviewStatusListener.PreviewAreaChangedListener { 635596b4c902dcb685928b43678f428746ca5ffd08Angus Kong private static final Log.Tag TAG = new Log.Tag("FocusOverlayMgr"); 648872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 658872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private static final int RESET_TOUCH_FOCUS = 0; 66d4a68ca4e34ad256cd4cd2f7b1faae234d240dfaKevin Gabayan private static final int RESET_TOUCH_FOCUS_DELAY = 4000; 678872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 688872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private int mState = STATE_IDLE; 698872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private static final int STATE_IDLE = 0; // Focus is not active. 708872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private static final int STATE_FOCUSING = 1; // Focus is in progress. 718872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Focus is in progress and the camera should take a picture after focus finishes. 728872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private static final int STATE_FOCUSING_SNAP_ON_FINISH = 2; 738872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private static final int STATE_SUCCESS = 3; // Focus finishes and succeeds. 748872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private static final int STATE_FAIL = 4; // Focus finishes and fails. 758872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 768872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private boolean mInitialized; 778872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private boolean mFocusAreaSupported; 788872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private boolean mMeteringAreaSupported; 798872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private boolean mLockAeAwbNeeded; 808872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private boolean mAeAwbLock; 81a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling private final Matrix mMatrix; 828872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 838872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private boolean mMirror; // true if the camera is front-facing. 848872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private int mDisplayOrientation; 85a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling private List<Area> mFocusArea; // focus area in driver format 86a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling private List<Area> mMeteringArea; // metering area in driver format 878872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private String mFocusMode; 88a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling private final String[] mDefaultFocusModes; 898872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private String mOverrideFocusMode; 908872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private Parameters mParameters; 9188289047ba6928e317d17f2e1d4b013693545c67Angus Kong private CameraCapabilities mCapabilities; 92a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling private final SettingsManager mSettingsManager; 93a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling private final Handler mHandler; 948872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb Listener mListener; 95e3de7223ee3fe56e097d68f50c5a59ae61370d65Michael Kolb private boolean mPreviousMoving; 96516c11a6885f6e524927bd369567f5bbd592f8efKevin Gabayan 97a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling private final FocusUI mUI; 9836ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu private final Rect mPreviewRect = new Rect(0, 0, 0, 0); 99d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 100d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb public interface FocusUI { 101d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb public boolean hasFaces(); 102d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb public void clearFocus(); 10310a035c93e2cb3ed65f59258fa4d0aca89555bcdDoris Liu public void setFocusPosition(int x, int y, boolean isAutoFocus); 104d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb public void onFocusStarted(); 105e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling public void onFocusSucceeded(); 106e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling public void onFocusFailed(); 107d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb public void pauseFaceDetection(); 108d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb public void resumeFaceDetection(); 109d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb } 110d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 1118872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public interface Listener { 1128872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void autoFocus(); 1138872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void cancelAutoFocus(); 1148872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public boolean capture(); 1158872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void startFaceDetection(); 1168872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void stopFaceDetection(); 1178872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void setFocusParameters(); 1188872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1198872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 1208872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private class MainHandler extends Handler { 1218872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public MainHandler(Looper looper) { 1228872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb super(looper); 1238872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1248872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 1258872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb @Override 1268872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void handleMessage(Message msg) { 1278872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb switch (msg.what) { 1288872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb case RESET_TOUCH_FOCUS: { 1298872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb cancelAutoFocus(); 1308872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mListener.startFaceDetection(); 1318872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb break; 1328872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1338872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1348872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1358872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1368872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 137357b7673f03d9b45d281d585cc3f4f87dc7d727bErin Dahlgren public FocusOverlayManager(SettingsManager settingsManager, 138357b7673f03d9b45d281d585cc3f4f87dc7d727bErin Dahlgren String[] defaultFocusModes, 1398872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb Parameters parameters, Listener listener, 140d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb boolean mirror, Looper looper, FocusUI ui) { 141357b7673f03d9b45d281d585cc3f4f87dc7d727bErin Dahlgren mSettingsManager = settingsManager; 1428872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mHandler = new MainHandler(looper); 1438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mMatrix = new Matrix(); 1448872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mDefaultFocusModes = defaultFocusModes; 14588289047ba6928e317d17f2e1d4b013693545c67Angus Kong // TODO: Pass in the capabilities directly. 14688289047ba6928e317d17f2e1d4b013693545c67Angus Kong setParameters(parameters, CameraCapabilitiesFactory.createFrom(parameters)); 1478872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mListener = listener; 1488872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb setMirror(mirror); 149d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb mUI = ui; 1508872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1518872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 15288289047ba6928e317d17f2e1d4b013693545c67Angus Kong public void setParameters(Parameters parameters, CameraCapabilities capabilities) { 1538872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // parameters can only be null when onConfigurationChanged is called 1548872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // before camera is open. We will just return in this case, because 1558872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // parameters will be set again later with the right parameters after 1568872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // camera is open. 1578872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (parameters == null) return; 1588872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mParameters = parameters; 15988289047ba6928e317d17f2e1d4b013693545c67Angus Kong mCapabilities = capabilities; 16088289047ba6928e317d17f2e1d4b013693545c67Angus Kong mFocusAreaSupported = mCapabilities.supports(CameraCapabilities.Feature.FOCUS_AREA); 16188289047ba6928e317d17f2e1d4b013693545c67Angus Kong mMeteringAreaSupported = mCapabilities.supports(CameraCapabilities.Feature.METERING_AREA); 16288289047ba6928e317d17f2e1d4b013693545c67Angus Kong mLockAeAwbNeeded = (mCapabilities.supports(CameraCapabilities.Feature.AUTO_EXPOSURE_LOCK) 16388289047ba6928e317d17f2e1d4b013693545c67Angus Kong || mCapabilities.supports(CameraCapabilities.Feature.AUTO_WHITE_BALANCE_LOCK)); 1648872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1658872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 16636ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu /** This setter should be the only way to mutate mPreviewRect. */ 16736ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu public void setPreviewRect(Rect previewRect) { 16836ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu if (!mPreviewRect.equals(previewRect)) { 16936ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu mPreviewRect.set(previewRect); 1708872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb setMatrix(); 1718872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1728872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1738872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 174482de029dc20e0a577388a602985fb31c3200309Doris Liu @Override 1752bacca795a1b0adb0daf515c43c48234b44bbba5Angus Kong public void onPreviewAreaChanged(RectF previewArea) { 176a1ec04a9f9526418f5cb17a5afbfc48aca1e02d0Doris Liu setPreviewRect(CameraUtil.rectFToRect(previewArea)); 177482de029dc20e0a577388a602985fb31c3200309Doris Liu } 178482de029dc20e0a577388a602985fb31c3200309Doris Liu 17936ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu /** Returns a copy of mPreviewRect so that outside class cannot modify preview 18036ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu * rect except deliberately doing so through the setter. */ 18136ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu public Rect getPreviewRect() { 18236ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu return new Rect(mPreviewRect); 18336ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu } 18436ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu 1858872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void setMirror(boolean mirror) { 1868872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mMirror = mirror; 1878872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb setMatrix(); 1888872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1898872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 1908872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void setDisplayOrientation(int displayOrientation) { 1918872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mDisplayOrientation = displayOrientation; 1928872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb setMatrix(); 1938872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1948872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 1958872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private void setMatrix() { 19636ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu if (mPreviewRect.width() != 0 && mPreviewRect.height() != 0) { 1978872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb Matrix matrix = new Matrix(); 19836ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu CameraUtil.prepareMatrix(matrix, mMirror, mDisplayOrientation, getPreviewRect()); 1998872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // In face detection, the matrix converts the driver coordinates to UI 2008872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // coordinates. In tap focus, the inverted matrix converts the UI 2018872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // coordinates to driver coordinates. 2028872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb matrix.invert(mMatrix); 203d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb mInitialized = true; 2048872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2058872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2068872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 2078872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private void lockAeAwbIfNeeded() { 2088872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (mLockAeAwbNeeded && !mAeAwbLock) { 2098872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mAeAwbLock = true; 2108872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mListener.setFocusParameters(); 2118872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2128872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2138872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 2148872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private void unlockAeAwbIfNeeded() { 2158872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (mLockAeAwbNeeded && mAeAwbLock && (mState != STATE_FOCUSING_SNAP_ON_FINISH)) { 2168872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mAeAwbLock = false; 2178872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mListener.setFocusParameters(); 2188872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2198872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2208872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 2218872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void onShutterUp() { 2228872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (!mInitialized) return; 2238872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 2248872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (needAutoFocusCall()) { 2258872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // User releases half-pressed focus key. 2268872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (mState == STATE_FOCUSING || mState == STATE_SUCCESS 2278872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb || mState == STATE_FAIL) { 2288872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb cancelAutoFocus(); 2298872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2308872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2318872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 2328872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Unlock AE and AWB after cancelAutoFocus. Camera API does not 2338872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // guarantee setParameters can be called during autofocus. 2348872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb unlockAeAwbIfNeeded(); 2358872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2368872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 237eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong public void focusAndCapture() { 2388872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (!mInitialized) return; 2398872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 240eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong if (!needAutoFocusCall()) { 241eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong // Focus is not needed. 242eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong capture(); 243eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong } else if (mState == STATE_SUCCESS || mState == STATE_FAIL) { 244eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong // Focus is done already. 2458872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb capture(); 2468872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else if (mState == STATE_FOCUSING) { 247eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong // Still focusing and will not trigger snap upon finish. 2488872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mState = STATE_FOCUSING_SNAP_ON_FINISH; 2498872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else if (mState == STATE_IDLE) { 250eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong autoFocusAndCapture(); 2518872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2528872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2538872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 2548872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void onAutoFocus(boolean focused, boolean shutterButtonPressed) { 2558872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (mState == STATE_FOCUSING_SNAP_ON_FINISH) { 2568872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Take the picture no matter focus succeeds or fails. No need 2578872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // to play the AF sound if we're about to play the shutter 2588872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // sound. 2598872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (focused) { 2608872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mState = STATE_SUCCESS; 2618872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else { 2628872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mState = STATE_FAIL; 2638872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2648872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb updateFocusUI(); 2658872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb capture(); 2668872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else if (mState == STATE_FOCUSING) { 2678872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // This happens when (1) user is half-pressing the focus key or 2688872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // (2) touch focus is triggered. Play the focus tone. Do not 2698872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // take the picture now. 2708872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (focused) { 2718872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mState = STATE_SUCCESS; 2728872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else { 2738872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mState = STATE_FAIL; 2748872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2758872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb updateFocusUI(); 2768872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // If this is triggered by touch focus, cancel focus after a 2778872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // while. 278b05794393444ebd13bd24c2ecfb3fbd9963f688eMichael Kolb if (mFocusArea != null) { 2798872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mHandler.sendEmptyMessageDelayed(RESET_TOUCH_FOCUS, RESET_TOUCH_FOCUS_DELAY); 2808872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2818872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (shutterButtonPressed) { 2828872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Lock AE & AWB so users can half-press shutter and recompose. 2838872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb lockAeAwbIfNeeded(); 2848872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2858872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else if (mState == STATE_IDLE) { 2868872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // User has released the focus key before focus completes. 2878872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Do nothing. 2888872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2898872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 2908872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 2918872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void onAutoFocusMoving(boolean moving) { 2928872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (!mInitialized) return; 293d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 294d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 2958872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Ignore if the camera has detected some faces. 296d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb if (mUI.hasFaces()) { 297d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb mUI.clearFocus(); 2988872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb return; 2998872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 3008872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 3018872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Ignore if we have requested autofocus. This method only handles 3028872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // continuous autofocus. 3038872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (mState != STATE_IDLE) return; 3048872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 305e3de7223ee3fe56e097d68f50c5a59ae61370d65Michael Kolb // animate on false->true trasition only b/8219520 306e3de7223ee3fe56e097d68f50c5a59ae61370d65Michael Kolb if (moving && !mPreviousMoving) { 307ca4a5668c5bcda027bd896ebf17c8ef374e2ac75Doris Liu // Auto focus at the center of the preview. 30810a035c93e2cb3ed65f59258fa4d0aca89555bcdDoris Liu mUI.setFocusPosition(mPreviewRect.centerX(), mPreviewRect.centerY(), true); 309d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb mUI.onFocusStarted(); 310e3de7223ee3fe56e097d68f50c5a59ae61370d65Michael Kolb } else if (!moving) { 311e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling mUI.onFocusSucceeded(); 3128872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 313e3de7223ee3fe56e097d68f50c5a59ae61370d65Michael Kolb mPreviousMoving = moving; 3148872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 3158872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 316638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberling @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) 3170718d480a144ba0a44c07c48f90e85cf4ec669c6Michael Kolb private void initializeFocusAreas(int x, int y) { 3188872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (mFocusArea == null) { 319a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling mFocusArea = new ArrayList<Area>(); 3208872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mFocusArea.add(new Area(new Rect(), 1)); 3218872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 3228872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 3238872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Convert the coordinates to driver format. 324a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling calculateTapArea(x, y, 1f, mFocusArea.get(0).rect); 3258872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 3268872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 327638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberling @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) 3280718d480a144ba0a44c07c48f90e85cf4ec669c6Michael Kolb private void initializeMeteringAreas(int x, int y) { 3298872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (mMeteringArea == null) { 330a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling mMeteringArea = new ArrayList<Area>(); 3318872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mMeteringArea.add(new Area(new Rect(), 1)); 3328872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 3338872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 3348872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Convert the coordinates to driver format. 3358872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // AE area is bigger because exposure is sensitive and 3368872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // easy to over- or underexposure if area is too small. 337a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling calculateTapArea(x, y, 1.5f, mMeteringArea.get(0).rect); 3388872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 3398872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 3408872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void onSingleTapUp(int x, int y) { 3418872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (!mInitialized || mState == STATE_FOCUSING_SNAP_ON_FINISH) return; 3428872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 3438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Let users be able to cancel previous touch focus. 344b05794393444ebd13bd24c2ecfb3fbd9963f688eMichael Kolb if ((mFocusArea != null) && (mState == STATE_FOCUSING || 3458872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mState == STATE_SUCCESS || mState == STATE_FAIL)) { 3468872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb cancelAutoFocus(); 3478872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 34836ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu if (mPreviewRect.width() == 0 || mPreviewRect.height() == 0) return; 349b05794393444ebd13bd24c2ecfb3fbd9963f688eMichael Kolb // Initialize variables. 3508872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Initialize mFocusArea. 3518872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (mFocusAreaSupported) { 3520718d480a144ba0a44c07c48f90e85cf4ec669c6Michael Kolb initializeFocusAreas(x, y); 3538872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 3548872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Initialize mMeteringArea. 3558872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (mMeteringAreaSupported) { 3560718d480a144ba0a44c07c48f90e85cf4ec669c6Michael Kolb initializeMeteringAreas(x, y); 3578872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 3588872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 3598872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Use margin to set the focus indicator to the touched area. 36010a035c93e2cb3ed65f59258fa4d0aca89555bcdDoris Liu mUI.setFocusPosition(x, y, false); 3618872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 3628872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Stop face detection because we want to specify focus and metering area. 3638872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mListener.stopFaceDetection(); 3648872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 3658872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Set the focus area and metering area. 3668872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mListener.setFocusParameters(); 3678872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (mFocusAreaSupported) { 3688872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb autoFocus(); 3698872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else { // Just show the indicator in all other cases. 3708872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb updateFocusUI(); 371d4a68ca4e34ad256cd4cd2f7b1faae234d240dfaKevin Gabayan // Reset the metering area in 4 seconds. 3728872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mHandler.removeMessages(RESET_TOUCH_FOCUS); 3738872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mHandler.sendEmptyMessageDelayed(RESET_TOUCH_FOCUS, RESET_TOUCH_FOCUS_DELAY); 3748872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 3758872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 3768872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 3778872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void onPreviewStarted() { 3788872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mState = STATE_IDLE; 3798872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 3808872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 3818872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void onPreviewStopped() { 3828872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // If auto focus was in progress, it would have been stopped. 3838872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mState = STATE_IDLE; 3848872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb resetTouchFocus(); 3858872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb updateFocusUI(); 3868872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 3878872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 3888872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void onCameraReleased() { 3898872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb onPreviewStopped(); 3908872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 3918872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 392eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong /** 393eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong * Triggers the autofocus and sets the specified state. 394eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong * 395eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong * @param focusingState The state to use when focus is in progress. 396eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong */ 397eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong private void autoFocus(int focusingState) { 398516c11a6885f6e524927bd369567f5bbd592f8efKevin Gabayan Log.v(TAG, "Start autofocus."); 3998872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mListener.autoFocus(); 400eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong mState = focusingState; 4018872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Pause the face view because the driver will keep sending face 4028872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // callbacks after the focus completes. 403d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb mUI.pauseFaceDetection(); 4048872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb updateFocusUI(); 4058872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mHandler.removeMessages(RESET_TOUCH_FOCUS); 4068872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 4078872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 408eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong /** 409eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong * Triggers the autofocus and set the state to indicate the focus is in 410eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong * progress. 411eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong */ 412eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong private void autoFocus() { 413eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong autoFocus(STATE_FOCUSING); 414eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong } 415eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong 416eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong /** 417eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong * Triggers the autofocus and set the state to which a capture will happen 418eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong * in the following autofocus callback. 419eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong */ 420eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong private void autoFocusAndCapture() { 421eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong autoFocus(STATE_FOCUSING_SNAP_ON_FINISH); 422eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong } 423eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong 4248872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private void cancelAutoFocus() { 425516c11a6885f6e524927bd369567f5bbd592f8efKevin Gabayan Log.v(TAG, "Cancel autofocus."); 4268872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Reset the tap area before calling mListener.cancelAutofocus. 4278872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Otherwise, focus mode stays at auto and the tap area passed to the 4288872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // driver is not reset. 4298872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb resetTouchFocus(); 4308872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mListener.cancelAutoFocus(); 431d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb mUI.resumeFaceDetection(); 4328872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mState = STATE_IDLE; 4338872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb updateFocusUI(); 4348872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mHandler.removeMessages(RESET_TOUCH_FOCUS); 4358872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 4368872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 4378872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private void capture() { 4388872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (mListener.capture()) { 4398872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mState = STATE_IDLE; 4408872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mHandler.removeMessages(RESET_TOUCH_FOCUS); 4418872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 4428872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 4438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 4448872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public String getFocusMode() { 4458872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (mOverrideFocusMode != null) return mOverrideFocusMode; 4464a40e126df5a77eaf44a52c73011cbfa91879b54Michael Kolb if (mParameters == null) return Parameters.FOCUS_MODE_AUTO; 4478872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb List<String> supportedFocusModes = mParameters.getSupportedFocusModes(); 4488872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 449b05794393444ebd13bd24c2ecfb3fbd9963f688eMichael Kolb if (mFocusAreaSupported && mFocusArea != null) { 4508872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Always use autofocus in tap-to-focus. 4518872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mFocusMode = Parameters.FOCUS_MODE_AUTO; 4528872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else { 4538872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // The default is continuous autofocus. 454635a4b8ba2b8684f95e5cb0aa35c244a06985f4cErin Dahlgren mFocusMode = mSettingsManager.get(SettingsManager.SETTING_FOCUS_MODE); 4558872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Try to find a supported focus mode from the default list. 4568872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (mFocusMode == null) { 4578872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb for (int i = 0; i < mDefaultFocusModes.length; i++) { 4588872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb String mode = mDefaultFocusModes[i]; 459b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong if (CameraUtil.isSupported(mode, supportedFocusModes)) { 4608872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mFocusMode = mode; 4618872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb break; 4628872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 4638872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 4648872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 4658872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 466b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong if (!CameraUtil.isSupported(mFocusMode, supportedFocusModes)) { 4678872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // For some reasons, the driver does not support the current 4688872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // focus mode. Fall back to auto. 469b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong if (CameraUtil.isSupported(Parameters.FOCUS_MODE_AUTO, 4708872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mParameters.getSupportedFocusModes())) { 4718872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mFocusMode = Parameters.FOCUS_MODE_AUTO; 4728872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else { 4738872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mFocusMode = mParameters.getFocusMode(); 4748872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 4758872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 4768872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb return mFocusMode; 4778872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 4788872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 479a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling public List<Area> getFocusAreas() { 4808872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb return mFocusArea; 4818872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 4828872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 483a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling public List<Area> getMeteringAreas() { 4848872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb return mMeteringArea; 4858872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 4868872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 4878872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void updateFocusUI() { 4888872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (!mInitialized) return; 4898872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Show only focus indicator or face indicator. 4908872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 4918872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (mState == STATE_IDLE) { 492b05794393444ebd13bd24c2ecfb3fbd9963f688eMichael Kolb if (mFocusArea == null) { 493d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb mUI.clearFocus(); 4948872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else { 4958872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Users touch on the preview and the indicator represents the 4968872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // metering area. Either focus area is not supported or 4978872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // autoFocus call is not required. 498d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb mUI.onFocusStarted(); 4998872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 5008872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else if (mState == STATE_FOCUSING || mState == STATE_FOCUSING_SNAP_ON_FINISH) { 501d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb mUI.onFocusStarted(); 5028872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else { 503b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong if (CameraUtil.FOCUS_MODE_CONTINUOUS_PICTURE.equals(mFocusMode)) { 5048872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // TODO: check HAL behavior and decide if this can be removed. 505e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling mUI.onFocusSucceeded(); 5068872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else if (mState == STATE_SUCCESS) { 507e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling mUI.onFocusSucceeded(); 5088872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else if (mState == STATE_FAIL) { 509e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling mUI.onFocusFailed(); 5108872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 5118872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 5128872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 5138872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 5148872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void resetTouchFocus() { 5158872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (!mInitialized) return; 5168872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 5178872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Put focus indicator to the center. clear reset position 518d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb mUI.clearFocus(); 5190718d480a144ba0a44c07c48f90e85cf4ec669c6Michael Kolb // Initialize mFocusArea. 520b05794393444ebd13bd24c2ecfb3fbd9963f688eMichael Kolb mFocusArea = null; 521b05794393444ebd13bd24c2ecfb3fbd9963f688eMichael Kolb mMeteringArea = null; 5228872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 5238872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 5240718d480a144ba0a44c07c48f90e85cf4ec669c6Michael Kolb private void calculateTapArea(int x, int y, float areaMultiple, Rect rect) { 525b3749f2071f866c43ea5f70de219f23157097077Doris Liu int areaSize = (int) (getAreaSize() * areaMultiple); 52636ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu int left = CameraUtil.clamp(x - areaSize / 2, mPreviewRect.left, 52736ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu mPreviewRect.right - areaSize); 52836ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu int top = CameraUtil.clamp(y - areaSize / 2, mPreviewRect.top, 52936ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu mPreviewRect.bottom - areaSize); 5308872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 531b3749f2071f866c43ea5f70de219f23157097077Doris Liu RectF rectF = new RectF(left, top, left + areaSize, top + areaSize); 5328872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mMatrix.mapRect(rectF); 533b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong CameraUtil.rectFToRect(rectF, rect); 5348872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 5358872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 536b3749f2071f866c43ea5f70de219f23157097077Doris Liu private int getAreaSize() { 537b3749f2071f866c43ea5f70de219f23157097077Doris Liu // Recommended focus area size from the manufacture is 1/8 of the image 5382ba03263340639635120be467f8cabec2889aa08Doris Liu // width (i.e. longer edge of the image) 53936ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu return Math.max(mPreviewRect.width(), mPreviewRect.height()) / 8; 540b3749f2071f866c43ea5f70de219f23157097077Doris Liu } 541b3749f2071f866c43ea5f70de219f23157097077Doris Liu 5428872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb /* package */ int getFocusState() { 5438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb return mState; 5448872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 5458872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 5468872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public boolean isFocusCompleted() { 5478872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb return mState == STATE_SUCCESS || mState == STATE_FAIL; 5488872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 5498872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 5508872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public boolean isFocusingSnapOnFinish() { 5518872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb return mState == STATE_FOCUSING_SNAP_ON_FINISH; 5528872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 5538872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 5548872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void removeMessages() { 5558872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mHandler.removeMessages(RESET_TOUCH_FOCUS); 5568872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 5578872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 5588872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void overrideFocusMode(String focusMode) { 5598872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mOverrideFocusMode = focusMode; 5608872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 5618872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 5628872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void setAeAwbLock(boolean lock) { 5638872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mAeAwbLock = lock; 5648872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 5658872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 5668872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public boolean getAeAwbLock() { 5678872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb return mAeAwbLock; 5688872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 5698872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 5708872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private boolean needAutoFocusCall() { 5718872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb String focusMode = getFocusMode(); 5728872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb return !(focusMode.equals(Parameters.FOCUS_MODE_INFINITY) 5738872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb || focusMode.equals(Parameters.FOCUS_MODE_FIXED) 5748872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb || focusMode.equals(Parameters.FOCUS_MODE_EDOF)); 5758872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 5768872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb} 577