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