1d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li/* 2d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li * Copyright (C) 2011 The Android Open Source Project 3d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li * 4d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li * Licensed under the Apache License, Version 2.0 (the "License"); 5d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li * you may not use this file except in compliance with the License. 6d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li * You may obtain a copy of the License at 7d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li * 8d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li * http://www.apache.org/licenses/LICENSE-2.0 9d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li * 10d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li * Unless required by applicable law or agreed to in writing, software 11d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li * distributed under the License is distributed on an "AS IS" BASIS, 12d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li * See the License for the specific language governing permissions and 14d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li * limitations under the License. 15d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li */ 16d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 17d480002ccad05cf992c628c72884091c36cc654cWu-cheng Lipackage com.android.camera; 18d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 19d480002ccad05cf992c628c72884091c36cc654cWu-cheng Liimport com.android.camera.ui.FaceView; 2020b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Liimport com.android.camera.ui.FocusIndicator; 2120b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Liimport com.android.camera.ui.FocusIndicatorView; 22d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 231acf35ce296efc6b3ad823a9500f79f71c545201Wu-cheng Liimport android.content.res.AssetFileDescriptor; 24048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huangimport android.graphics.Matrix; 25d480002ccad05cf992c628c72884091c36cc654cWu-cheng Liimport android.graphics.Rect; 26048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huangimport android.graphics.RectF; 27d480002ccad05cf992c628c72884091c36cc654cWu-cheng Liimport android.hardware.Camera.Area; 28d480002ccad05cf992c628c72884091c36cc654cWu-cheng Liimport android.hardware.Camera.Parameters; 291461b5333aab31faee65272d64c2ac7f9809d4d0Eino-Ville Talvalaimport android.media.MediaActionSound; 30d480002ccad05cf992c628c72884091c36cc654cWu-cheng Liimport android.os.Handler; 31d480002ccad05cf992c628c72884091c36cc654cWu-cheng Liimport android.os.Message; 32d480002ccad05cf992c628c72884091c36cc654cWu-cheng Liimport android.util.Log; 33d480002ccad05cf992c628c72884091c36cc654cWu-cheng Liimport android.view.MotionEvent; 34d480002ccad05cf992c628c72884091c36cc654cWu-cheng Liimport android.view.View; 35d480002ccad05cf992c628c72884091c36cc654cWu-cheng Liimport android.view.ViewGroup; 36d480002ccad05cf992c628c72884091c36cc654cWu-cheng Liimport android.widget.RelativeLayout; 37d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 38d480002ccad05cf992c628c72884091c36cc654cWu-cheng Liimport java.util.ArrayList; 39d480002ccad05cf992c628c72884091c36cc654cWu-cheng Liimport java.util.List; 40d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 41d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li// A class that handles everything about focus in still picture mode. 42d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li// This also handles the metering area because it is the same as focus area. 43d480002ccad05cf992c628c72884091c36cc654cWu-cheng Lipublic class FocusManager { 4458dadc3028b3af2e9895089e1b39ad1ab982ece2Wu-cheng Li private static final String TAG = "FocusManager"; 45d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 46d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private static final int RESET_TOUCH_FOCUS = 0; 47d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private static final int FOCUS_BEEP_VOLUME = 100; 48d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private static final int RESET_TOUCH_FOCUS_DELAY = 3000; 49d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 50d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private int mState = STATE_IDLE; 51d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private static final int STATE_IDLE = 0; // Focus is not active. 52d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private static final int STATE_FOCUSING = 1; // Focus is in progress. 53d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // Focus is in progress and the camera should take a picture after focus finishes. 54d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private static final int STATE_FOCUSING_SNAP_ON_FINISH = 2; 55d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private static final int STATE_SUCCESS = 3; // Focus finishes and succeeds. 56d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private static final int STATE_FAIL = 4; // Focus finishes and fails. 57d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 58d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private boolean mInitialized; 59d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private boolean mFocusAreaSupported; 6053be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li private boolean mLockAeAwbNeeded; 6153be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li private boolean mAeAwbLock; 62048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang private Matrix mMatrix; 6320b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li private View mFocusIndicatorRotateLayout; 6420b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li private FocusIndicatorView mFocusIndicator; 65d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private View mPreviewFrame; 66d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private FaceView mFaceView; 67bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang private List<Area> mFocusArea; // focus area in driver format 68bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang private List<Area> mMeteringArea; // metering area in driver format 69d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private String mFocusMode; 7060dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang private String[] mDefaultFocusModes; 71d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private String mOverrideFocusMode; 72d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private Parameters mParameters; 73d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private ComboPreferences mPreferences; 74d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private Handler mHandler; 75d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li Listener mListener; 76d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 77d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public interface Listener { 78d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public void autoFocus(); 79d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public void cancelAutoFocus(); 80d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public boolean capture(); 81d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public void startFaceDetection(); 82d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public void stopFaceDetection(); 83d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public void setFocusParameters(); 84d628e27f561c4bedf0d457f64270fc12740b5280Eino-Ville Talvala public void playSound(int soundId); 85d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 86d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 87d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private class MainHandler extends Handler { 88d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li @Override 89d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public void handleMessage(Message msg) { 90d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li switch (msg.what) { 91d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li case RESET_TOUCH_FOCUS: { 92d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li cancelAutoFocus(); 93d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mListener.startFaceDetection(); 94d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li break; 95d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 96d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 97d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 98d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 99d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 10060dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang public FocusManager(ComboPreferences preferences, String[] defaultFocusModes) { 101d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mPreferences = preferences; 10260dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang mDefaultFocusModes = defaultFocusModes; 10358dadc3028b3af2e9895089e1b39ad1ab982ece2Wu-cheng Li mHandler = new MainHandler(); 104048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang mMatrix = new Matrix(); 10558dadc3028b3af2e9895089e1b39ad1ab982ece2Wu-cheng Li } 10658dadc3028b3af2e9895089e1b39ad1ab982ece2Wu-cheng Li 10758dadc3028b3af2e9895089e1b39ad1ab982ece2Wu-cheng Li // This has to be initialized before initialize(). 10858dadc3028b3af2e9895089e1b39ad1ab982ece2Wu-cheng Li public void initializeParameters(Parameters parameters) { 109d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mParameters = parameters; 110d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mFocusAreaSupported = (mParameters.getMaxNumFocusAreas() > 0 111d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li && isSupported(Parameters.FOCUS_MODE_AUTO, 112d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mParameters.getSupportedFocusModes())); 11353be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li mLockAeAwbNeeded = (mParameters.isAutoExposureLockSupported() || 11453be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li mParameters.isAutoWhiteBalanceLockSupported()); 115d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 116d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 11720b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li public void initialize(View focusIndicatorRotate, View previewFrame, 118048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang FaceView faceView, Listener listener, boolean mirror, int displayOrientation) { 11920b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li mFocusIndicatorRotateLayout = focusIndicatorRotate; 12020b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li mFocusIndicator = (FocusIndicatorView) focusIndicatorRotate.findViewById( 12120b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li R.id.focus_indicator); 122d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mPreviewFrame = previewFrame; 123d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mFaceView = faceView; 124d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mListener = listener; 125048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang 126048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang Matrix matrix = new Matrix(); 127048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang Util.prepareMatrix(matrix, mirror, displayOrientation, 128048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang previewFrame.getWidth(), previewFrame.getHeight()); 129048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang // In face detection, the matrix converts the driver coordinates to UI 130048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang // coordinates. In tap focus, the inverted matrix converts the UI 131048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang // coordinates to driver coordinates. 132048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang matrix.invert(mMatrix); 133048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang 13458dadc3028b3af2e9895089e1b39ad1ab982ece2Wu-cheng Li if (mParameters != null) { 13558dadc3028b3af2e9895089e1b39ad1ab982ece2Wu-cheng Li mInitialized = true; 13658dadc3028b3af2e9895089e1b39ad1ab982ece2Wu-cheng Li } else { 13758dadc3028b3af2e9895089e1b39ad1ab982ece2Wu-cheng Li Log.e(TAG, "mParameters is not initialized."); 13858dadc3028b3af2e9895089e1b39ad1ab982ece2Wu-cheng Li } 139d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 140d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 14153be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li public void onShutterDown() { 142d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li if (!mInitialized) return; 143d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 14453be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li // Lock AE and AWB so users can half-press shutter and recompose. 14553be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li if (mLockAeAwbNeeded && !mAeAwbLock) { 14653be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li mAeAwbLock = true; 14753be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li mListener.setFocusParameters(); 14853be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li } 14953be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li 15053be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li if (needAutoFocusCall()) { 15153be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li // Do not focus if touch focus has been triggered. 15253be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li if (mState != STATE_SUCCESS && mState != STATE_FAIL) { 15353be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li autoFocus(); 154d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 155d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 156d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 157d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 15853be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li public void onShutterUp() { 15953be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li if (!mInitialized) return; 16053be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li 16153be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li if (needAutoFocusCall()) { 16253be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li // User releases half-pressed focus key. 16353be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li if (mState == STATE_FOCUSING || mState == STATE_SUCCESS 16453be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li || mState == STATE_FAIL) { 16553be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li cancelAutoFocus(); 16653be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li } 16753be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li } 16853be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li 16953be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li // Unlock AE and AWB after cancelAutoFocus. Camera API does not 17053be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li // guarantee setParameters can be called during autofocus. 17153be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li if (mLockAeAwbNeeded && mAeAwbLock && (mState != STATE_FOCUSING_SNAP_ON_FINISH)) { 17253be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li mAeAwbLock = false; 17353be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li mListener.setFocusParameters(); 17453be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li } 17553be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li } 17653be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li 177d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public void doSnap() { 178d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li if (!mInitialized) return; 179d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 180d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // If the user has half-pressed the shutter and focus is completed, we 181d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // can take the photo right away. If the focus mode is infinity, we can 182d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // also take the photo. 18353be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li if (!needAutoFocusCall() || (mState == STATE_SUCCESS || mState == STATE_FAIL)) { 184d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li capture(); 185d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } else if (mState == STATE_FOCUSING) { 186d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // Half pressing the shutter (i.e. the focus button event) will 187d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // already have requested AF for us, so just request capture on 188d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // focus here. 189d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mState = STATE_FOCUSING_SNAP_ON_FINISH; 190d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } else if (mState == STATE_IDLE) { 1919d80a29af1ed57eded5d20af51ef5e704b32b452Chih-Chung Chang // We didn't do focus. This can happen if the user press focus key 1929d80a29af1ed57eded5d20af51ef5e704b32b452Chih-Chung Chang // while the snapshot is still in progress. The user probably wants 1939d80a29af1ed57eded5d20af51ef5e704b32b452Chih-Chung Chang // the next snapshot as soon as possible, so we just do a snapshot 1949d80a29af1ed57eded5d20af51ef5e704b32b452Chih-Chung Chang // without focusing again. 1959d80a29af1ed57eded5d20af51ef5e704b32b452Chih-Chung Chang capture(); 196d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 197d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 198d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 199d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public void onShutter() { 200d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li resetTouchFocus(); 201d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li updateFocusUI(); 202d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 203d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 204d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public void onAutoFocus(boolean focused) { 2056bc0f740f5d7fa6eb8aa8a4ba7dd3ab4dca999d4Wu-cheng Li if (mState == STATE_FOCUSING_SNAP_ON_FINISH) { 206d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // Take the picture no matter focus succeeds or fails. No need 207d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // to play the AF sound if we're about to play the shutter 208d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // sound. 209d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li if (focused) { 210d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mState = STATE_SUCCESS; 211d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } else { 212d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mState = STATE_FAIL; 213d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 214d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li updateFocusUI(); 215d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li capture(); 216d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } else if (mState == STATE_FOCUSING) { 217d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // This happens when (1) user is half-pressing the focus key or 218d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // (2) touch focus is triggered. Play the focus tone. Do not 219d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // take the picture now. 220d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li if (focused) { 221d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mState = STATE_SUCCESS; 222a7a50a45c75585e350eb730574b1e531468e8b18Wu-cheng Li // Do not play the sound in continuous autofocus mode. It does 223a7a50a45c75585e350eb730574b1e531468e8b18Wu-cheng Li // not do a full scan. The focus callback arrives before doSnap 224a7a50a45c75585e350eb730574b1e531468e8b18Wu-cheng Li // so the state is always STATE_FOCUSING. 225d628e27f561c4bedf0d457f64270fc12740b5280Eino-Ville Talvala if (!Parameters.FOCUS_MODE_CONTINUOUS_PICTURE. 226d628e27f561c4bedf0d457f64270fc12740b5280Eino-Ville Talvala equals(mFocusMode)) { 2271461b5333aab31faee65272d64c2ac7f9809d4d0Eino-Ville Talvala mListener.playSound(MediaActionSound.FOCUS_COMPLETE); 228d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 229d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } else { 230d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mState = STATE_FAIL; 231d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 232d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li updateFocusUI(); 233d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // If this is triggered by touch focus, cancel focus after a 234d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // while. 235bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang if (mFocusArea != null) { 236d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mHandler.sendEmptyMessageDelayed(RESET_TOUCH_FOCUS, RESET_TOUCH_FOCUS_DELAY); 237d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 238d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } else if (mState == STATE_IDLE) { 239d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // User has released the focus key before focus completes. 240d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // Do nothing. 241d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 242d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 243d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 244d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public boolean onTouch(MotionEvent e) { 245d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li if (!mInitialized || mState == STATE_FOCUSING_SNAP_ON_FINISH) return false; 246d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 247d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // Let users be able to cancel previous touch focus. 248bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang if ((mFocusArea != null) && (mState == STATE_FOCUSING || 249620e427c0aa990458d39b43477675b768d360327Wu-cheng Li mState == STATE_SUCCESS || mState == STATE_FAIL)) { 250d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li cancelAutoFocus(); 251d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 252d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 253d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // Initialize variables. 254d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li int x = Math.round(e.getX()); 255d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li int y = Math.round(e.getY()); 25620b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li int focusWidth = mFocusIndicatorRotateLayout.getWidth(); 25720b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li int focusHeight = mFocusIndicatorRotateLayout.getHeight(); 258d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li int previewWidth = mPreviewFrame.getWidth(); 259d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li int previewHeight = mPreviewFrame.getHeight(); 260bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang if (mFocusArea == null) { 261bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang mFocusArea = new ArrayList<Area>(); 262bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang mFocusArea.add(new Area(new Rect(), 1)); 263bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang mMeteringArea = new ArrayList<Area>(); 264bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang mMeteringArea.add(new Area(new Rect(), 1)); 265d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 266d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 267bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang // Convert the coordinates to driver format. 268bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang // AE area is bigger because exposure is sensitive and 269bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang // easy to over- or underexposure if area is too small. 270048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang calculateTapArea(focusWidth, focusHeight, 1f, x, y, previewWidth, previewHeight, 271bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang mFocusArea.get(0).rect); 272048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang calculateTapArea(focusWidth, focusHeight, 1.5f, x, y, previewWidth, previewHeight, 273bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang mMeteringArea.get(0).rect); 274d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 27520b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li // Use margin to set the focus indicator to the touched area. 276d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li RelativeLayout.LayoutParams p = 27720b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li (RelativeLayout.LayoutParams) mFocusIndicatorRotateLayout.getLayoutParams(); 278d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li int left = Util.clamp(x - focusWidth / 2, 0, previewWidth - focusWidth); 279d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li int top = Util.clamp(y - focusHeight / 2, 0, previewHeight - focusHeight); 280d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li p.setMargins(left, top, 0, 0); 281d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // Disable "center" rule because we no longer want to put it in the center. 282d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li int[] rules = p.getRules(); 283d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li rules[RelativeLayout.CENTER_IN_PARENT] = 0; 28420b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li mFocusIndicatorRotateLayout.requestLayout(); 285d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 286d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // Stop face detection because we want to specify focus and metering area. 287d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mListener.stopFaceDetection(); 288d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 289d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // Set the focus area and metering area. 290d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mListener.setFocusParameters(); 291d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li if (mFocusAreaSupported && (e.getAction() == MotionEvent.ACTION_UP)) { 292d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li autoFocus(); 29320b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li } else { // Just show the indicator in all other cases. 294d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li updateFocusUI(); 295d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // Reset the metering area in 3 seconds. 296d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mHandler.removeMessages(RESET_TOUCH_FOCUS); 297d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mHandler.sendEmptyMessageDelayed(RESET_TOUCH_FOCUS, RESET_TOUCH_FOCUS_DELAY); 298d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 299d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 300d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li return true; 301d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 302d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 303d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public void onPreviewStarted() { 304d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mState = STATE_IDLE; 305d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 306d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 307d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public void onPreviewStopped() { 308d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mState = STATE_IDLE; 309d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li resetTouchFocus(); 310d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // If auto focus was in progress, it would have been canceled. 311d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li updateFocusUI(); 312d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 313d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 314d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public void onCameraReleased() { 315d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li onPreviewStopped(); 316d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 317d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 318d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private void autoFocus() { 319d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li Log.v(TAG, "Start autofocus."); 320d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mListener.autoFocus(); 321d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mState = STATE_FOCUSING; 322d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // Pause the face view because the driver will keep sending face 323d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // callbacks after the focus completes. 324d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li if (mFaceView != null) mFaceView.pause(); 325d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li updateFocusUI(); 326d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mHandler.removeMessages(RESET_TOUCH_FOCUS); 327d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 328d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 329d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private void cancelAutoFocus() { 330d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li Log.v(TAG, "Cancel autofocus."); 3315d4972e63a1f81139c6503fd433f06c77276fc38Sundar Raman 3325d4972e63a1f81139c6503fd433f06c77276fc38Sundar Raman // Reset the tap area before calling mListener.cancelAutofocus. 3335d4972e63a1f81139c6503fd433f06c77276fc38Sundar Raman // Otherwise, focus mode stays at auto and the tap area passed to the 3345d4972e63a1f81139c6503fd433f06c77276fc38Sundar Raman // driver is not reset. 3355d4972e63a1f81139c6503fd433f06c77276fc38Sundar Raman resetTouchFocus(); 336d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mListener.cancelAutoFocus(); 337d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li if (mFaceView != null) mFaceView.resume(); 338d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mState = STATE_IDLE; 339d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li updateFocusUI(); 340d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mHandler.removeMessages(RESET_TOUCH_FOCUS); 341d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 342d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 343d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private void capture() { 344d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li if (mListener.capture()) { 345d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mState = STATE_IDLE; 346d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mHandler.removeMessages(RESET_TOUCH_FOCUS); 347d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 348d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 349d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 35058dadc3028b3af2e9895089e1b39ad1ab982ece2Wu-cheng Li // This can only be called after mParameters is initialized. 351d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public String getFocusMode() { 352d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li if (mOverrideFocusMode != null) return mOverrideFocusMode; 35360dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang List<String> supportedFocusModes = mParameters.getSupportedFocusModes(); 354d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 35530e2c49eedfbce51be7458161829a750f809d56dWu-cheng Li if (mFocusAreaSupported && mFocusArea != null) { 3566bc0f740f5d7fa6eb8aa8a4ba7dd3ab4dca999d4Wu-cheng Li // Always use autofocus in tap-to-focus. 357d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mFocusMode = Parameters.FOCUS_MODE_AUTO; 358d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } else { 359d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // The default is continuous autofocus. 360d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mFocusMode = mPreferences.getString( 36160dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang CameraSettings.KEY_FOCUS_MODE, null); 36260dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang 36360dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang // Try to find a supported focus mode from the default list. 36460dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang if (mFocusMode == null) { 36560dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang for (int i = 0; i < mDefaultFocusModes.length; i++) { 36660dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang String mode = mDefaultFocusModes[i]; 36760dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang if (isSupported(mode, supportedFocusModes)) { 36860dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang mFocusMode = mode; 36960dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang break; 37060dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang } 37160dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang } 37260dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang } 373d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 37460dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang if (!isSupported(mFocusMode, supportedFocusModes)) { 375d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // For some reasons, the driver does not support the current 376d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // focus mode. Fall back to auto. 377d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li if (isSupported(Parameters.FOCUS_MODE_AUTO, 378d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mParameters.getSupportedFocusModes())) { 379d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mFocusMode = Parameters.FOCUS_MODE_AUTO; 380d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } else { 381d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mFocusMode = mParameters.getFocusMode(); 382d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 383d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 384d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li return mFocusMode; 385d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 386d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 387bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang public List<Area> getFocusAreas() { 388bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang return mFocusArea; 389bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang } 390bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang 391bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang public List<Area> getMeteringAreas() { 392bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang return mMeteringArea; 393d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 394d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 395d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public void updateFocusUI() { 396d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li if (!mInitialized) return; 397d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 39820b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li // Set the length of focus indicator according to preview frame size. 399d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li int len = Math.min(mPreviewFrame.getWidth(), mPreviewFrame.getHeight()) / 4; 400bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang ViewGroup.LayoutParams layout = mFocusIndicator.getLayoutParams(); 401d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li layout.width = len; 402d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li layout.height = len; 403d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 40420b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li // Show only focus indicator or face indicator. 40520b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li boolean faceExists = (mFaceView != null && mFaceView.faceExists()); 40620b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li FocusIndicator focusIndicator = (faceExists) ? mFaceView : mFocusIndicator; 40720b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li 408d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li if (mState == STATE_IDLE) { 409bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang if (mFocusArea == null) { 41020b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li focusIndicator.clear(); 411d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } else { 41220b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li // Users touch on the preview and the indicator represents the 413d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // metering area. Either focus area is not supported or 414d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // autoFocus call is not required. 41520b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li focusIndicator.showStart(); 416d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 41720b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li } else if (mState == STATE_FOCUSING || mState == STATE_FOCUSING_SNAP_ON_FINISH) { 41820b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li focusIndicator.showStart(); 419a7a50a45c75585e350eb730574b1e531468e8b18Wu-cheng Li } else { 420a7a50a45c75585e350eb730574b1e531468e8b18Wu-cheng Li // In CAF, do not show success or failure because it only returns 421a7a50a45c75585e350eb730574b1e531468e8b18Wu-cheng Li // the focus status. It does not do a full scan. So the result is 422a7a50a45c75585e350eb730574b1e531468e8b18Wu-cheng Li // failure most of the time. 423a7a50a45c75585e350eb730574b1e531468e8b18Wu-cheng Li if (Parameters.FOCUS_MODE_CONTINUOUS_PICTURE.equals(mFocusMode)) { 424a7a50a45c75585e350eb730574b1e531468e8b18Wu-cheng Li focusIndicator.showStart(); 425a7a50a45c75585e350eb730574b1e531468e8b18Wu-cheng Li } else if (mState == STATE_SUCCESS) { 426a7a50a45c75585e350eb730574b1e531468e8b18Wu-cheng Li focusIndicator.showSuccess(); 427a7a50a45c75585e350eb730574b1e531468e8b18Wu-cheng Li } else if (mState == STATE_FAIL) { 428a7a50a45c75585e350eb730574b1e531468e8b18Wu-cheng Li focusIndicator.showFail(); 429a7a50a45c75585e350eb730574b1e531468e8b18Wu-cheng Li } 430d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 431d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 432d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 433d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public void resetTouchFocus() { 434d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li if (!mInitialized) return; 435d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 43620b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li // Put focus indicator to the center. 437d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li RelativeLayout.LayoutParams p = 43820b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li (RelativeLayout.LayoutParams) mFocusIndicatorRotateLayout.getLayoutParams(); 439d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li int[] rules = p.getRules(); 440d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li rules[RelativeLayout.CENTER_IN_PARENT] = RelativeLayout.TRUE; 441d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li p.setMargins(0, 0, 0, 0); 442d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 443bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang mFocusArea = null; 444bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang mMeteringArea = null; 445bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang } 446bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang 447048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang public void calculateTapArea(int focusWidth, int focusHeight, float areaMultiple, 448bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang int x, int y, int previewWidth, int previewHeight, Rect rect) { 449bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang int areaWidth = (int)(focusWidth * areaMultiple); 450bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang int areaHeight = (int)(focusHeight * areaMultiple); 451048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang int left = Util.clamp(x - areaWidth / 2, 0, previewWidth - areaWidth); 452048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang int top = Util.clamp(y - areaHeight / 2, 0, previewHeight - areaHeight); 453048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang 454048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang RectF rectF = new RectF(left, top, left + areaWidth, top + areaHeight); 455048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang mMatrix.mapRect(rectF); 456048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang Util.rectFToRect(rectF, rect); 457d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 458d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 459d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public boolean isFocusCompleted() { 460d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li return mState == STATE_SUCCESS || mState == STATE_FAIL; 461d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 462d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 46372eaced345def3746038f1aba3efe2845b274884Wu-cheng Li public boolean isFocusingSnapOnFinish() { 46472eaced345def3746038f1aba3efe2845b274884Wu-cheng Li return mState == STATE_FOCUSING_SNAP_ON_FINISH; 46572eaced345def3746038f1aba3efe2845b274884Wu-cheng Li } 46672eaced345def3746038f1aba3efe2845b274884Wu-cheng Li 467d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public void removeMessages() { 468d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mHandler.removeMessages(RESET_TOUCH_FOCUS); 469d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 470d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 471d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public void overrideFocusMode(String focusMode) { 472d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mOverrideFocusMode = focusMode; 473d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 474d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 47553be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li public void setAeAwbLock(boolean lock) { 47653be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li mAeAwbLock = lock; 47753be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li } 47853be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li 47953be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li public boolean getAeAwbLock() { 48053be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li return mAeAwbLock; 48153be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li } 48253be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li 483d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private static boolean isSupported(String value, List<String> supported) { 484d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li return supported == null ? false : supported.indexOf(value) >= 0; 485d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 48653be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li 48753be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li private boolean needAutoFocusCall() { 48853be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li String focusMode = getFocusMode(); 48953be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li return !(focusMode.equals(Parameters.FOCUS_MODE_INFINITY) 49053be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li || focusMode.equals(Parameters.FOCUS_MODE_FIXED) 49153be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li || focusMode.equals(Parameters.FOCUS_MODE_EDOF)); 49253be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li } 493d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li} 494