FocusManager.java revision 72eaced345def3746038f1aba3efe2845b274884
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; 29d480002ccad05cf992c628c72884091c36cc654cWu-cheng Liimport android.os.Handler; 30d480002ccad05cf992c628c72884091c36cc654cWu-cheng Liimport android.os.Message; 31d480002ccad05cf992c628c72884091c36cc654cWu-cheng Liimport android.util.Log; 32d480002ccad05cf992c628c72884091c36cc654cWu-cheng Liimport android.view.MotionEvent; 33d480002ccad05cf992c628c72884091c36cc654cWu-cheng Liimport android.view.View; 34d480002ccad05cf992c628c72884091c36cc654cWu-cheng Liimport android.view.ViewGroup; 35d480002ccad05cf992c628c72884091c36cc654cWu-cheng Liimport android.widget.RelativeLayout; 36d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 37d480002ccad05cf992c628c72884091c36cc654cWu-cheng Liimport java.util.ArrayList; 38d480002ccad05cf992c628c72884091c36cc654cWu-cheng Liimport java.util.List; 39d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 40d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li// A class that handles everything about focus in still picture mode. 41d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li// This also handles the metering area because it is the same as focus area. 42d480002ccad05cf992c628c72884091c36cc654cWu-cheng Lipublic class FocusManager { 4358dadc3028b3af2e9895089e1b39ad1ab982ece2Wu-cheng Li private static final String TAG = "FocusManager"; 44d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 45d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private static final int RESET_TOUCH_FOCUS = 0; 46d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private static final int FOCUS_BEEP_VOLUME = 100; 47d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private static final int RESET_TOUCH_FOCUS_DELAY = 3000; 48d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 49d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private int mState = STATE_IDLE; 50d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private static final int STATE_IDLE = 0; // Focus is not active. 51d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private static final int STATE_FOCUSING = 1; // Focus is in progress. 52d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // Focus is in progress and the camera should take a picture after focus finishes. 53d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private static final int STATE_FOCUSING_SNAP_ON_FINISH = 2; 54d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private static final int STATE_SUCCESS = 3; // Focus finishes and succeeds. 55d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private static final int STATE_FAIL = 4; // Focus finishes and fails. 56d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 57d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private boolean mInitialized; 58d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private boolean mFocusAreaSupported; 5953be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li private boolean mLockAeAwbNeeded; 6053be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li private boolean mAeAwbLock; 61048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang private Matrix mMatrix; 621acf35ce296efc6b3ad823a9500f79f71c545201Wu-cheng Li private SoundPlayer mSoundPlayer; 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(); 84d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 85d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 86d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private class MainHandler extends Handler { 87d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li @Override 88d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public void handleMessage(Message msg) { 89d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li switch (msg.what) { 90d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li case RESET_TOUCH_FOCUS: { 91d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li cancelAutoFocus(); 92d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mListener.startFaceDetection(); 93d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li break; 94d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 95d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 96d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 97d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 98d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 9960dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang public FocusManager(ComboPreferences preferences, String[] defaultFocusModes) { 100d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mPreferences = preferences; 10160dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang mDefaultFocusModes = defaultFocusModes; 10258dadc3028b3af2e9895089e1b39ad1ab982ece2Wu-cheng Li mHandler = new MainHandler(); 103048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang mMatrix = new Matrix(); 10458dadc3028b3af2e9895089e1b39ad1ab982ece2Wu-cheng Li } 10558dadc3028b3af2e9895089e1b39ad1ab982ece2Wu-cheng Li 10658dadc3028b3af2e9895089e1b39ad1ab982ece2Wu-cheng Li // This has to be initialized before initialize(). 10758dadc3028b3af2e9895089e1b39ad1ab982ece2Wu-cheng Li public void initializeParameters(Parameters parameters) { 108d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mParameters = parameters; 109d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mFocusAreaSupported = (mParameters.getMaxNumFocusAreas() > 0 110d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li && isSupported(Parameters.FOCUS_MODE_AUTO, 111d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mParameters.getSupportedFocusModes())); 11253be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li mLockAeAwbNeeded = (mParameters.isAutoExposureLockSupported() || 11353be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li mParameters.isAutoWhiteBalanceLockSupported()); 114d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 115d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 11620b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li public void initialize(View focusIndicatorRotate, View previewFrame, 117048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang FaceView faceView, Listener listener, boolean mirror, int displayOrientation) { 11820b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li mFocusIndicatorRotateLayout = focusIndicatorRotate; 11920b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li mFocusIndicator = (FocusIndicatorView) focusIndicatorRotate.findViewById( 12020b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li R.id.focus_indicator); 121d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mPreviewFrame = previewFrame; 122d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mFaceView = faceView; 123d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mListener = listener; 124048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang 125048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang Matrix matrix = new Matrix(); 126048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang Util.prepareMatrix(matrix, mirror, displayOrientation, 127048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang previewFrame.getWidth(), previewFrame.getHeight()); 128048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang // In face detection, the matrix converts the driver coordinates to UI 129048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang // coordinates. In tap focus, the inverted matrix converts the UI 130048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang // coordinates to driver coordinates. 131048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang matrix.invert(mMatrix); 132048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang 13358dadc3028b3af2e9895089e1b39ad1ab982ece2Wu-cheng Li if (mParameters != null) { 13458dadc3028b3af2e9895089e1b39ad1ab982ece2Wu-cheng Li mInitialized = true; 13558dadc3028b3af2e9895089e1b39ad1ab982ece2Wu-cheng Li } else { 13658dadc3028b3af2e9895089e1b39ad1ab982ece2Wu-cheng Li Log.e(TAG, "mParameters is not initialized."); 13758dadc3028b3af2e9895089e1b39ad1ab982ece2Wu-cheng Li } 138d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 139d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 14053be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li public void onShutterDown() { 141d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li if (!mInitialized) return; 142d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 14353be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li // Lock AE and AWB so users can half-press shutter and recompose. 14453be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li if (mLockAeAwbNeeded && !mAeAwbLock) { 14553be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li mAeAwbLock = true; 14653be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li mListener.setFocusParameters(); 14753be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li } 14853be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li 14953be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li if (needAutoFocusCall()) { 15053be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li // Do not focus if touch focus has been triggered. 15153be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li if (mState != STATE_SUCCESS && mState != STATE_FAIL) { 15253be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li autoFocus(); 153d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 154d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 155d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 156d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 15753be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li public void onShutterUp() { 15853be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li if (!mInitialized) return; 15953be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li 16053be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li if (needAutoFocusCall()) { 16153be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li // User releases half-pressed focus key. 16253be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li if (mState == STATE_FOCUSING || mState == STATE_SUCCESS 16353be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li || mState == STATE_FAIL) { 16453be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li cancelAutoFocus(); 16553be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li } 16653be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li } 16753be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li 16853be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li // Unlock AE and AWB after cancelAutoFocus. Camera API does not 16953be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li // guarantee setParameters can be called during autofocus. 17053be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li if (mLockAeAwbNeeded && mAeAwbLock && (mState != STATE_FOCUSING_SNAP_ON_FINISH)) { 17153be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li mAeAwbLock = false; 17253be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li mListener.setFocusParameters(); 17353be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li } 17453be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li } 17553be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li 176d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public void doSnap() { 177d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li if (!mInitialized) return; 178d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 179d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // If the user has half-pressed the shutter and focus is completed, we 180d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // can take the photo right away. If the focus mode is infinity, we can 181d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // also take the photo. 18253be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li if (!needAutoFocusCall() || (mState == STATE_SUCCESS || mState == STATE_FAIL)) { 183d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li capture(); 184d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } else if (mState == STATE_FOCUSING) { 185d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // Half pressing the shutter (i.e. the focus button event) will 186d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // already have requested AF for us, so just request capture on 187d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // focus here. 188d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mState = STATE_FOCUSING_SNAP_ON_FINISH; 189d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } else if (mState == STATE_IDLE) { 1909d80a29af1ed57eded5d20af51ef5e704b32b452Chih-Chung Chang // We didn't do focus. This can happen if the user press focus key 1919d80a29af1ed57eded5d20af51ef5e704b32b452Chih-Chung Chang // while the snapshot is still in progress. The user probably wants 1929d80a29af1ed57eded5d20af51ef5e704b32b452Chih-Chung Chang // the next snapshot as soon as possible, so we just do a snapshot 1939d80a29af1ed57eded5d20af51ef5e704b32b452Chih-Chung Chang // without focusing again. 1949d80a29af1ed57eded5d20af51ef5e704b32b452Chih-Chung Chang capture(); 195d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 196d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 197d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 198d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public void onShutter() { 199d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li resetTouchFocus(); 200d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li updateFocusUI(); 201d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 202d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 203d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public void onAutoFocus(boolean focused) { 2046bc0f740f5d7fa6eb8aa8a4ba7dd3ab4dca999d4Wu-cheng Li if (mState == STATE_FOCUSING_SNAP_ON_FINISH) { 205d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // Take the picture no matter focus succeeds or fails. No need 206d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // to play the AF sound if we're about to play the shutter 207d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // sound. 208d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li if (focused) { 209d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mState = STATE_SUCCESS; 210d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } else { 211d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mState = STATE_FAIL; 212d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 213d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li updateFocusUI(); 214d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li capture(); 215d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } else if (mState == STATE_FOCUSING) { 216d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // This happens when (1) user is half-pressing the focus key or 217d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // (2) touch focus is triggered. Play the focus tone. Do not 218d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // take the picture now. 219d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li if (focused) { 220d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mState = STATE_SUCCESS; 221a7a50a45c75585e350eb730574b1e531468e8b18Wu-cheng Li // Do not play the sound in continuous autofocus mode. It does 222a7a50a45c75585e350eb730574b1e531468e8b18Wu-cheng Li // not do a full scan. The focus callback arrives before doSnap 223a7a50a45c75585e350eb730574b1e531468e8b18Wu-cheng Li // so the state is always STATE_FOCUSING. 224a7a50a45c75585e350eb730574b1e531468e8b18Wu-cheng Li if (!Parameters.FOCUS_MODE_CONTINUOUS_PICTURE.equals(mFocusMode) 2251acf35ce296efc6b3ad823a9500f79f71c545201Wu-cheng Li && mSoundPlayer != null) { 2261acf35ce296efc6b3ad823a9500f79f71c545201Wu-cheng Li mSoundPlayer.play(); 227d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 228d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } else { 229d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mState = STATE_FAIL; 230d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 231d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li updateFocusUI(); 232d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // If this is triggered by touch focus, cancel focus after a 233d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // while. 234bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang if (mFocusArea != null) { 235d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mHandler.sendEmptyMessageDelayed(RESET_TOUCH_FOCUS, RESET_TOUCH_FOCUS_DELAY); 236d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 237d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } else if (mState == STATE_IDLE) { 238d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // User has released the focus key before focus completes. 239d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // Do nothing. 240d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 241d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 242d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 243d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public boolean onTouch(MotionEvent e) { 244d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li if (!mInitialized || mState == STATE_FOCUSING_SNAP_ON_FINISH) return false; 245d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 246d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // Let users be able to cancel previous touch focus. 247bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang if ((mFocusArea != null) && (mState == STATE_FOCUSING || 248620e427c0aa990458d39b43477675b768d360327Wu-cheng Li mState == STATE_SUCCESS || mState == STATE_FAIL)) { 249d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li cancelAutoFocus(); 250d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 251d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 252d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // Initialize variables. 253d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li int x = Math.round(e.getX()); 254d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li int y = Math.round(e.getY()); 25520b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li int focusWidth = mFocusIndicatorRotateLayout.getWidth(); 25620b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li int focusHeight = mFocusIndicatorRotateLayout.getHeight(); 257d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li int previewWidth = mPreviewFrame.getWidth(); 258d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li int previewHeight = mPreviewFrame.getHeight(); 259bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang if (mFocusArea == null) { 260bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang mFocusArea = new ArrayList<Area>(); 261bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang mFocusArea.add(new Area(new Rect(), 1)); 262bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang mMeteringArea = new ArrayList<Area>(); 263bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang mMeteringArea.add(new Area(new Rect(), 1)); 264d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 265d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 266bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang // Convert the coordinates to driver format. 267bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang // AE area is bigger because exposure is sensitive and 268bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang // easy to over- or underexposure if area is too small. 269048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang calculateTapArea(focusWidth, focusHeight, 1f, x, y, previewWidth, previewHeight, 270bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang mFocusArea.get(0).rect); 271048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang calculateTapArea(focusWidth, focusHeight, 1.5f, x, y, previewWidth, previewHeight, 272bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang mMeteringArea.get(0).rect); 273d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 27420b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li // Use margin to set the focus indicator to the touched area. 275d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li RelativeLayout.LayoutParams p = 27620b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li (RelativeLayout.LayoutParams) mFocusIndicatorRotateLayout.getLayoutParams(); 277d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li int left = Util.clamp(x - focusWidth / 2, 0, previewWidth - focusWidth); 278d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li int top = Util.clamp(y - focusHeight / 2, 0, previewHeight - focusHeight); 279d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li p.setMargins(left, top, 0, 0); 280d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // Disable "center" rule because we no longer want to put it in the center. 281d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li int[] rules = p.getRules(); 282d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li rules[RelativeLayout.CENTER_IN_PARENT] = 0; 28320b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li mFocusIndicatorRotateLayout.requestLayout(); 284d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 285d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // Stop face detection because we want to specify focus and metering area. 286d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mListener.stopFaceDetection(); 287d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 288d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // Set the focus area and metering area. 289d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mListener.setFocusParameters(); 290d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li if (mFocusAreaSupported && (e.getAction() == MotionEvent.ACTION_UP)) { 291d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li autoFocus(); 29220b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li } else { // Just show the indicator in all other cases. 293d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li updateFocusUI(); 294d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // Reset the metering area in 3 seconds. 295d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mHandler.removeMessages(RESET_TOUCH_FOCUS); 296d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mHandler.sendEmptyMessageDelayed(RESET_TOUCH_FOCUS, RESET_TOUCH_FOCUS_DELAY); 297d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 298d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 299d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li return true; 300d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 301d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 302d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public void onPreviewStarted() { 303d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mState = STATE_IDLE; 304d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 305d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 306d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public void onPreviewStopped() { 307d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mState = STATE_IDLE; 308d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li resetTouchFocus(); 309d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // If auto focus was in progress, it would have been canceled. 310d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li updateFocusUI(); 311d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 312d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 313d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public void onCameraReleased() { 314d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li onPreviewStopped(); 315d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 316d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 317d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private void autoFocus() { 318d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li Log.v(TAG, "Start autofocus."); 319d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mListener.autoFocus(); 320d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mState = STATE_FOCUSING; 321d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // Pause the face view because the driver will keep sending face 322d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // callbacks after the focus completes. 323d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li if (mFaceView != null) mFaceView.pause(); 324d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li updateFocusUI(); 325d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mHandler.removeMessages(RESET_TOUCH_FOCUS); 326d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 327d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 328d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private void cancelAutoFocus() { 329d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li Log.v(TAG, "Cancel autofocus."); 3305d4972e63a1f81139c6503fd433f06c77276fc38Sundar Raman 3315d4972e63a1f81139c6503fd433f06c77276fc38Sundar Raman // Reset the tap area before calling mListener.cancelAutofocus. 3325d4972e63a1f81139c6503fd433f06c77276fc38Sundar Raman // Otherwise, focus mode stays at auto and the tap area passed to the 3335d4972e63a1f81139c6503fd433f06c77276fc38Sundar Raman // driver is not reset. 3345d4972e63a1f81139c6503fd433f06c77276fc38Sundar Raman resetTouchFocus(); 335d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mListener.cancelAutoFocus(); 336d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li if (mFaceView != null) mFaceView.resume(); 337d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mState = STATE_IDLE; 338d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li updateFocusUI(); 339d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mHandler.removeMessages(RESET_TOUCH_FOCUS); 340d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 341d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 342d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private void capture() { 343d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li if (mListener.capture()) { 344d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mState = STATE_IDLE; 345d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mHandler.removeMessages(RESET_TOUCH_FOCUS); 346d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 347d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 348d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 3491acf35ce296efc6b3ad823a9500f79f71c545201Wu-cheng Li public void initializeSoundPlayer(AssetFileDescriptor fd) { 3501acf35ce296efc6b3ad823a9500f79f71c545201Wu-cheng Li mSoundPlayer = new SoundPlayer(fd); 351d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 352d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 3531acf35ce296efc6b3ad823a9500f79f71c545201Wu-cheng Li public void releaseSoundPlayer() { 3541acf35ce296efc6b3ad823a9500f79f71c545201Wu-cheng Li if (mSoundPlayer != null) { 3551acf35ce296efc6b3ad823a9500f79f71c545201Wu-cheng Li mSoundPlayer.release(); 3561acf35ce296efc6b3ad823a9500f79f71c545201Wu-cheng Li mSoundPlayer = null; 357d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 358d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 359d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 3601acf35ce296efc6b3ad823a9500f79f71c545201Wu-cheng Li 36158dadc3028b3af2e9895089e1b39ad1ab982ece2Wu-cheng Li // This can only be called after mParameters is initialized. 362d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public String getFocusMode() { 363d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li if (mOverrideFocusMode != null) return mOverrideFocusMode; 36460dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang List<String> supportedFocusModes = mParameters.getSupportedFocusModes(); 365d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 36630e2c49eedfbce51be7458161829a750f809d56dWu-cheng Li if (mFocusAreaSupported && mFocusArea != null) { 3676bc0f740f5d7fa6eb8aa8a4ba7dd3ab4dca999d4Wu-cheng Li // Always use autofocus in tap-to-focus. 368d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mFocusMode = Parameters.FOCUS_MODE_AUTO; 369d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } else { 370d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // The default is continuous autofocus. 371d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mFocusMode = mPreferences.getString( 37260dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang CameraSettings.KEY_FOCUS_MODE, null); 37360dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang 37460dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang // Try to find a supported focus mode from the default list. 37560dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang if (mFocusMode == null) { 37660dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang for (int i = 0; i < mDefaultFocusModes.length; i++) { 37760dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang String mode = mDefaultFocusModes[i]; 37860dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang if (isSupported(mode, supportedFocusModes)) { 37960dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang mFocusMode = mode; 38060dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang break; 38160dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang } 38260dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang } 38360dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang } 384d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 38560dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang if (!isSupported(mFocusMode, supportedFocusModes)) { 386d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // For some reasons, the driver does not support the current 387d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // focus mode. Fall back to auto. 388d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li if (isSupported(Parameters.FOCUS_MODE_AUTO, 389d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mParameters.getSupportedFocusModes())) { 390d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mFocusMode = Parameters.FOCUS_MODE_AUTO; 391d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } else { 392d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mFocusMode = mParameters.getFocusMode(); 393d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 394d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 395d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li return mFocusMode; 396d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 397d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 398bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang public List<Area> getFocusAreas() { 399bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang return mFocusArea; 400bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang } 401bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang 402bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang public List<Area> getMeteringAreas() { 403bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang return mMeteringArea; 404d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 405d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 406d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public void updateFocusUI() { 407d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li if (!mInitialized) return; 408d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 40920b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li // Set the length of focus indicator according to preview frame size. 410d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li int len = Math.min(mPreviewFrame.getWidth(), mPreviewFrame.getHeight()) / 4; 411bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang ViewGroup.LayoutParams layout = mFocusIndicator.getLayoutParams(); 412d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li layout.width = len; 413d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li layout.height = len; 414d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 41520b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li // Show only focus indicator or face indicator. 41620b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li boolean faceExists = (mFaceView != null && mFaceView.faceExists()); 41720b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li FocusIndicator focusIndicator = (faceExists) ? mFaceView : mFocusIndicator; 41820b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li 419d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li if (mState == STATE_IDLE) { 420bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang if (mFocusArea == null) { 42120b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li focusIndicator.clear(); 422d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } else { 42320b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li // Users touch on the preview and the indicator represents the 424d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // metering area. Either focus area is not supported or 425d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li // autoFocus call is not required. 42620b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li focusIndicator.showStart(); 427d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 42820b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li } else if (mState == STATE_FOCUSING || mState == STATE_FOCUSING_SNAP_ON_FINISH) { 42920b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li focusIndicator.showStart(); 430a7a50a45c75585e350eb730574b1e531468e8b18Wu-cheng Li } else { 431a7a50a45c75585e350eb730574b1e531468e8b18Wu-cheng Li // In CAF, do not show success or failure because it only returns 432a7a50a45c75585e350eb730574b1e531468e8b18Wu-cheng Li // the focus status. It does not do a full scan. So the result is 433a7a50a45c75585e350eb730574b1e531468e8b18Wu-cheng Li // failure most of the time. 434a7a50a45c75585e350eb730574b1e531468e8b18Wu-cheng Li if (Parameters.FOCUS_MODE_CONTINUOUS_PICTURE.equals(mFocusMode)) { 435a7a50a45c75585e350eb730574b1e531468e8b18Wu-cheng Li focusIndicator.showStart(); 436a7a50a45c75585e350eb730574b1e531468e8b18Wu-cheng Li } else if (mState == STATE_SUCCESS) { 437a7a50a45c75585e350eb730574b1e531468e8b18Wu-cheng Li focusIndicator.showSuccess(); 438a7a50a45c75585e350eb730574b1e531468e8b18Wu-cheng Li } else if (mState == STATE_FAIL) { 439a7a50a45c75585e350eb730574b1e531468e8b18Wu-cheng Li focusIndicator.showFail(); 440a7a50a45c75585e350eb730574b1e531468e8b18Wu-cheng Li } 441d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 442d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 443d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 444d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public void resetTouchFocus() { 445d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li if (!mInitialized) return; 446d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 44720b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li // Put focus indicator to the center. 448d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li RelativeLayout.LayoutParams p = 44920b3c3526ebb8d8a6873f7a1110f23847a843515Wu-cheng Li (RelativeLayout.LayoutParams) mFocusIndicatorRotateLayout.getLayoutParams(); 450d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li int[] rules = p.getRules(); 451d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li rules[RelativeLayout.CENTER_IN_PARENT] = RelativeLayout.TRUE; 452d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li p.setMargins(0, 0, 0, 0); 453d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 454bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang mFocusArea = null; 455bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang mMeteringArea = null; 456bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang } 457bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang 458048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang public void calculateTapArea(int focusWidth, int focusHeight, float areaMultiple, 459bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang int x, int y, int previewWidth, int previewHeight, Rect rect) { 460bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang int areaWidth = (int)(focusWidth * areaMultiple); 461bd29d3c5d59b375d77334aaa426545dc781b95fdChih-yu Huang int areaHeight = (int)(focusHeight * areaMultiple); 462048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang int left = Util.clamp(x - areaWidth / 2, 0, previewWidth - areaWidth); 463048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang int top = Util.clamp(y - areaHeight / 2, 0, previewHeight - areaHeight); 464048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang 465048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang RectF rectF = new RectF(left, top, left + areaWidth, top + areaHeight); 466048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang mMatrix.mapRect(rectF); 467048edf2ef22607b85bc4b062e2af71804f5b3530Chih-yu Huang Util.rectFToRect(rectF, rect); 468d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 469d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 470d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public boolean isFocusCompleted() { 471d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li return mState == STATE_SUCCESS || mState == STATE_FAIL; 472d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 473d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 47472eaced345def3746038f1aba3efe2845b274884Wu-cheng Li public boolean isFocusingSnapOnFinish() { 47572eaced345def3746038f1aba3efe2845b274884Wu-cheng Li return mState == STATE_FOCUSING_SNAP_ON_FINISH; 47672eaced345def3746038f1aba3efe2845b274884Wu-cheng Li } 47772eaced345def3746038f1aba3efe2845b274884Wu-cheng Li 478d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public void removeMessages() { 479d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mHandler.removeMessages(RESET_TOUCH_FOCUS); 480d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 481d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 482d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li public void overrideFocusMode(String focusMode) { 483d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li mOverrideFocusMode = focusMode; 484d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 485d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li 48653be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li public void setAeAwbLock(boolean lock) { 48753be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li mAeAwbLock = lock; 48853be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li } 48953be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li 49053be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li public boolean getAeAwbLock() { 49153be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li return mAeAwbLock; 49253be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li } 49353be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li 494d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li private static boolean isSupported(String value, List<String> supported) { 495d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li return supported == null ? false : supported.indexOf(value) >= 0; 496d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li } 49753be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li 49853be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li private boolean needAutoFocusCall() { 49953be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li String focusMode = getFocusMode(); 50053be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li return !(focusMode.equals(Parameters.FOCUS_MODE_INFINITY) 50153be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li || focusMode.equals(Parameters.FOCUS_MODE_FIXED) 50253be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li || focusMode.equals(Parameters.FOCUS_MODE_EDOF)); 50353be34deae057cfa297c3ee73eee91f880272650Wu-cheng Li } 504d480002ccad05cf992c628c72884091c36cc654cWu-cheng Li} 505