1b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb/*
2b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * Copyright (C) 2012 The Android Open Source Project
3b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb *
4b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * Licensed under the Apache License, Version 2.0 (the "License");
5b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * you may not use this file except in compliance with the License.
6b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * You may obtain a copy of the License at
7b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb *
8b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb *      http://www.apache.org/licenses/LICENSE-2.0
9b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb *
10b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * Unless required by applicable law or agreed to in writing, software
11b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * distributed under the License is distributed on an "AS IS" BASIS,
12b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * See the License for the specific language governing permissions and
14b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * limitations under the License.
15b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb */
16b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
17b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbpackage com.android.camera;
18b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
19b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport android.annotation.TargetApi;
20b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport android.graphics.Matrix;
21b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport android.graphics.Rect;
22b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport android.graphics.RectF;
23b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport android.hardware.Camera.Area;
24b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport android.hardware.Camera.Parameters;
25b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport android.os.Handler;
26b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport android.os.Looper;
27b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport android.os.Message;
28b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport android.util.Log;
29b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
30b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport com.android.camera.ui.FaceView;
31b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport com.android.camera.ui.FocusIndicator;
328042e7045f3e11dd49d40eebe603eb5fe12d711aMichael Kolbimport com.android.camera.ui.PieRenderer;
33b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport com.android.gallery3d.common.ApiHelper;
34b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
35b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport java.util.ArrayList;
36b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport java.util.List;
37b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
38b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb/* A class that handles everything about focus in still picture mode.
39b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * This also handles the metering area because it is the same as focus area.
40b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb *
41b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * The test cases:
42b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * (1) The camera has continuous autofocus. Move the camera. Take a picture when
43b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb *     CAF is not in progress.
44b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * (2) The camera has continuous autofocus. Move the camera. Take a picture when
45b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb *     CAF is in progress.
46b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * (3) The camera has face detection. Point the camera at some faces. Hold the
47b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb *     shutter. Release to take a picture.
48b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * (4) The camera has face detection. Point the camera at some faces. Single tap
49b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb *     the shutter to take a picture.
50b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * (5) The camera has autofocus. Single tap the shutter to take a picture.
51b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * (6) The camera has autofocus. Hold the shutter. Release to take a picture.
52b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * (7) The camera has no autofocus. Single tap the shutter and take a picture.
53b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * (8) The camera has autofocus and supports focus area. Touch the screen to
54b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb *     trigger autofocus. Take a picture.
55b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * (9) The camera has autofocus and supports focus area. Touch the screen to
56b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb *     trigger autofocus. Wait until it times out.
57b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * (10) The camera has no autofocus and supports metering area. Touch the screen
58b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb *     to change metering area.
59b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb */
60b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbpublic class FocusOverlayManager {
61b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private static final String TAG = "CAM_FocusManager";
62b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
63b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private static final int RESET_TOUCH_FOCUS = 0;
64b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private static final int RESET_TOUCH_FOCUS_DELAY = 3000;
65b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
66b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private int mState = STATE_IDLE;
67b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private static final int STATE_IDLE = 0; // Focus is not active.
68b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private static final int STATE_FOCUSING = 1; // Focus is in progress.
69b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    // Focus is in progress and the camera should take a picture after focus finishes.
70b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private static final int STATE_FOCUSING_SNAP_ON_FINISH = 2;
71b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private static final int STATE_SUCCESS = 3; // Focus finishes and succeeds.
72b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private static final int STATE_FAIL = 4; // Focus finishes and fails.
73b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
74b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private boolean mInitialized;
75b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private boolean mFocusAreaSupported;
76b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private boolean mMeteringAreaSupported;
77b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private boolean mLockAeAwbNeeded;
78b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private boolean mAeAwbLock;
79b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private Matrix mMatrix;
80b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
818042e7045f3e11dd49d40eebe603eb5fe12d711aMichael Kolb    private PieRenderer mPieRenderer;
82b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
83b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private int mPreviewWidth; // The width of the preview frame layout.
84b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private int mPreviewHeight; // The height of the preview frame layout.
85b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private boolean mMirror; // true if the camera is front-facing.
86b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private int mDisplayOrientation;
87b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private FaceView mFaceView;
88b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private List<Object> mFocusArea; // focus area in driver format
89b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private List<Object> mMeteringArea; // metering area in driver format
90b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private String mFocusMode;
91b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private String[] mDefaultFocusModes;
92b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private String mOverrideFocusMode;
93b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private Parameters mParameters;
94b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private ComboPreferences mPreferences;
95b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private Handler mHandler;
96b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    Listener mListener;
97b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
98b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    public interface Listener {
99b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        public void autoFocus();
100b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        public void cancelAutoFocus();
101b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        public boolean capture();
102b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        public void startFaceDetection();
103b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        public void stopFaceDetection();
104b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        public void setFocusParameters();
105b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
106b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
107b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private class MainHandler extends Handler {
108b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        public MainHandler(Looper looper) {
109b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            super(looper);
110b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        }
111b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
112b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        @Override
113b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        public void handleMessage(Message msg) {
114b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            switch (msg.what) {
115b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                case RESET_TOUCH_FOCUS: {
116b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                    cancelAutoFocus();
117b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                    mListener.startFaceDetection();
118b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                    break;
119b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                }
120b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            }
121b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        }
122b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
123b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
124b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    public FocusOverlayManager(ComboPreferences preferences, String[] defaultFocusModes,
125b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            Parameters parameters, Listener listener,
126b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            boolean mirror, Looper looper) {
127b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        mHandler = new MainHandler(looper);
128b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        mMatrix = new Matrix();
129b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        mPreferences = preferences;
130b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        mDefaultFocusModes = defaultFocusModes;
131b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        setParameters(parameters);
132b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        mListener = listener;
133b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        setMirror(mirror);
134b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
135b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
1368042e7045f3e11dd49d40eebe603eb5fe12d711aMichael Kolb    public void setFocusRenderer(PieRenderer renderer) {
1378042e7045f3e11dd49d40eebe603eb5fe12d711aMichael Kolb        mPieRenderer = renderer;
13838a6c24485d36651b93d5935bfbaf3cd367885e7Michael Kolb        mInitialized = (mMatrix != null);
139b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
140b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
141b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    public void setParameters(Parameters parameters) {
142b7fc87328c1ee793e6c66ff6af45495268f954baDoris Liu        // parameters can only be null when onConfigurationChanged is called
143b7fc87328c1ee793e6c66ff6af45495268f954baDoris Liu        // before camera is open. We will just return in this case, because
144b7fc87328c1ee793e6c66ff6af45495268f954baDoris Liu        // parameters will be set again later with the right parameters after
145b7fc87328c1ee793e6c66ff6af45495268f954baDoris Liu        // camera is open.
146b7fc87328c1ee793e6c66ff6af45495268f954baDoris Liu        if (parameters == null) return;
147b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        mParameters = parameters;
148b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        mFocusAreaSupported = Util.isFocusAreaSupported(parameters);
149b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        mMeteringAreaSupported = Util.isMeteringAreaSupported(parameters);
150b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        mLockAeAwbNeeded = (Util.isAutoExposureLockSupported(mParameters) ||
151b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                Util.isAutoWhiteBalanceLockSupported(mParameters));
152b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
153b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
154b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    public void setPreviewSize(int previewWidth, int previewHeight) {
155b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        if (mPreviewWidth != previewWidth || mPreviewHeight != previewHeight) {
156b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            mPreviewWidth = previewWidth;
157b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            mPreviewHeight = previewHeight;
158b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            setMatrix();
159b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        }
160b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
161b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
162b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    public void setMirror(boolean mirror) {
163b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        mMirror = mirror;
164b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        setMatrix();
165b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
166b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
167b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    public void setDisplayOrientation(int displayOrientation) {
168b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        mDisplayOrientation = displayOrientation;
169b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        setMatrix();
170b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
171b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
172b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    public void setFaceView(FaceView faceView) {
173b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        mFaceView = faceView;
174b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
175b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
176b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private void setMatrix() {
177b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        if (mPreviewWidth != 0 && mPreviewHeight != 0) {
178b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            Matrix matrix = new Matrix();
179b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            Util.prepareMatrix(matrix, mMirror, mDisplayOrientation,
180b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                    mPreviewWidth, mPreviewHeight);
181b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            // In face detection, the matrix converts the driver coordinates to UI
182b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            // coordinates. In tap focus, the inverted matrix converts the UI
183b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            // coordinates to driver coordinates.
184b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            matrix.invert(mMatrix);
1858042e7045f3e11dd49d40eebe603eb5fe12d711aMichael Kolb            mInitialized = (mPieRenderer != null);
186b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        }
187b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
188b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
189bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li    private void lockAeAwbIfNeeded() {
190b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        if (mLockAeAwbNeeded && !mAeAwbLock) {
191b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            mAeAwbLock = true;
192b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            mListener.setFocusParameters();
193b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        }
194bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li    }
195bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li
196bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li    private void unlockAeAwbIfNeeded() {
197bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li        if (mLockAeAwbNeeded && mAeAwbLock && (mState != STATE_FOCUSING_SNAP_ON_FINISH)) {
198bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li            mAeAwbLock = false;
199bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li            mListener.setFocusParameters();
200bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li        }
201bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li    }
202b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
203bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li    public void onShutterDown() {
204bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li        if (!mInitialized) return;
205bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li
206bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li        boolean autoFocusCalled = false;
207b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        if (needAutoFocusCall()) {
208b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            // Do not focus if touch focus has been triggered.
209b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            if (mState != STATE_SUCCESS && mState != STATE_FAIL) {
210b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                autoFocus();
211bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li                autoFocusCalled = true;
212b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            }
213b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        }
214bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li
215bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li        if (!autoFocusCalled) lockAeAwbIfNeeded();
216b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
217b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
218b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    public void onShutterUp() {
219b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        if (!mInitialized) return;
220b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
221b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        if (needAutoFocusCall()) {
222b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            // User releases half-pressed focus key.
223b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            if (mState == STATE_FOCUSING || mState == STATE_SUCCESS
224b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                    || mState == STATE_FAIL) {
225b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                cancelAutoFocus();
226b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            }
227b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        }
228b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
229b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        // Unlock AE and AWB after cancelAutoFocus. Camera API does not
230b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        // guarantee setParameters can be called during autofocus.
231bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li        unlockAeAwbIfNeeded();
232b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
233b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
234b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    public void doSnap() {
235b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        if (!mInitialized) return;
236b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
237b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        // If the user has half-pressed the shutter and focus is completed, we
238b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        // can take the photo right away. If the focus mode is infinity, we can
239b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        // also take the photo.
240b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        if (!needAutoFocusCall() || (mState == STATE_SUCCESS || mState == STATE_FAIL)) {
241b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            capture();
242b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        } else if (mState == STATE_FOCUSING) {
243b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            // Half pressing the shutter (i.e. the focus button event) will
244b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            // already have requested AF for us, so just request capture on
245b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            // focus here.
246b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            mState = STATE_FOCUSING_SNAP_ON_FINISH;
247b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        } else if (mState == STATE_IDLE) {
248b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            // We didn't do focus. This can happen if the user press focus key
249b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            // while the snapshot is still in progress. The user probably wants
250b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            // the next snapshot as soon as possible, so we just do a snapshot
251b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            // without focusing again.
252b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            capture();
253b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        }
254b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
255b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
256bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li    public void onAutoFocus(boolean focused, boolean shutterButtonPressed) {
257b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        if (mState == STATE_FOCUSING_SNAP_ON_FINISH) {
258b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            // Take the picture no matter focus succeeds or fails. No need
259b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            // to play the AF sound if we're about to play the shutter
260b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            // sound.
261b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            if (focused) {
262b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                mState = STATE_SUCCESS;
263b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            } else {
264b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                mState = STATE_FAIL;
265b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            }
266b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            updateFocusUI();
267b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            capture();
268b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        } else if (mState == STATE_FOCUSING) {
269b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            // This happens when (1) user is half-pressing the focus key or
270b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            // (2) touch focus is triggered. Play the focus tone. Do not
271b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            // take the picture now.
272b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            if (focused) {
273b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                mState = STATE_SUCCESS;
274b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            } else {
275b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                mState = STATE_FAIL;
276b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            }
277b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            updateFocusUI();
278b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            // If this is triggered by touch focus, cancel focus after a
279b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            // while.
280b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            if (mFocusArea != null) {
281b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                mHandler.sendEmptyMessageDelayed(RESET_TOUCH_FOCUS, RESET_TOUCH_FOCUS_DELAY);
282b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            }
283bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li            if (shutterButtonPressed) {
284bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li                // Lock AE & AWB so users can half-press shutter and recompose.
285bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li                lockAeAwbIfNeeded();
286bdc502a9e0b1c701b5c5a87021dab224eb8360baWu-cheng Li            }
287b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        } else if (mState == STATE_IDLE) {
288b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            // User has released the focus key before focus completes.
289b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            // Do nothing.
290b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        }
291b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
292b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
293b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    public void onAutoFocusMoving(boolean moving) {
294fe44832abc2e9fb937ac5bd9c65e103397992e8cMichael Kolb        if (!mInitialized) return;
295b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        // Ignore if the camera has detected some faces.
296630d255bdeeb1a13a71b0ecda0a38d6546c351e2John Reck        if (mFaceView != null && mFaceView.faceExists()) {
297630d255bdeeb1a13a71b0ecda0a38d6546c351e2John Reck            mPieRenderer.clear();
298630d255bdeeb1a13a71b0ecda0a38d6546c351e2John Reck            return;
299630d255bdeeb1a13a71b0ecda0a38d6546c351e2John Reck        }
300b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
301b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        // Ignore if we have requested autofocus. This method only handles
302b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        // continuous autofocus.
303b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        if (mState != STATE_IDLE) return;
304b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
305b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        if (moving) {
3068042e7045f3e11dd49d40eebe603eb5fe12d711aMichael Kolb            mPieRenderer.showStart();
307b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        } else {
3088042e7045f3e11dd49d40eebe603eb5fe12d711aMichael Kolb            mPieRenderer.showSuccess(true);
309b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        }
310b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
311b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
312b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
313b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private void initializeFocusAreas(int focusWidth, int focusHeight,
314b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            int x, int y, int previewWidth, int previewHeight) {
315b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        if (mFocusArea == null) {
316b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            mFocusArea = new ArrayList<Object>();
317b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            mFocusArea.add(new Area(new Rect(), 1));
318b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        }
319b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
320b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        // Convert the coordinates to driver format.
321b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        calculateTapArea(focusWidth, focusHeight, 1f, x, y, previewWidth, previewHeight,
322b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                ((Area) mFocusArea.get(0)).rect);
323b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
324b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
325b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
326b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private void initializeMeteringAreas(int focusWidth, int focusHeight,
327b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            int x, int y, int previewWidth, int previewHeight) {
328b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        if (mMeteringArea == null) {
329b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            mMeteringArea = new ArrayList<Object>();
330b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            mMeteringArea.add(new Area(new Rect(), 1));
331b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        }
332b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
333b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        // Convert the coordinates to driver format.
334b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        // AE area is bigger because exposure is sensitive and
335b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        // easy to over- or underexposure if area is too small.
336b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        calculateTapArea(focusWidth, focusHeight, 1.5f, x, y, previewWidth, previewHeight,
337b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                ((Area) mMeteringArea.get(0)).rect);
338b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
339b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
340b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    public void onSingleTapUp(int x, int y) {
341b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        if (!mInitialized || mState == STATE_FOCUSING_SNAP_ON_FINISH) return;
342b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
343b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        // Let users be able to cancel previous touch focus.
344b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        if ((mFocusArea != null) && (mState == STATE_FOCUSING ||
345b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                    mState == STATE_SUCCESS || mState == STATE_FAIL)) {
346b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            cancelAutoFocus();
347b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        }
348b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        // Initialize variables.
3498042e7045f3e11dd49d40eebe603eb5fe12d711aMichael Kolb        int focusWidth = mPieRenderer.getSize();
3508042e7045f3e11dd49d40eebe603eb5fe12d711aMichael Kolb        int focusHeight = mPieRenderer.getSize();
3518042e7045f3e11dd49d40eebe603eb5fe12d711aMichael Kolb        if (focusWidth == 0 || mPieRenderer.getWidth() == 0
3528042e7045f3e11dd49d40eebe603eb5fe12d711aMichael Kolb                || mPieRenderer.getHeight() == 0) return;
353b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        int previewWidth = mPreviewWidth;
354b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        int previewHeight = mPreviewHeight;
355b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        // Initialize mFocusArea.
356b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        if (mFocusAreaSupported) {
357b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            initializeFocusAreas(
358b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                    focusWidth, focusHeight, x, y, previewWidth, previewHeight);
359b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        }
360b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        // Initialize mMeteringArea.
361b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        if (mMeteringAreaSupported) {
362b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            initializeMeteringAreas(
363b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                    focusWidth, focusHeight, x, y, previewWidth, previewHeight);
364b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        }
365b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
366b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        // Use margin to set the focus indicator to the touched area.
36717a04fb7378effcef5728b5b21442a59fb88572dMichael Kolb        mPieRenderer.setFocus(x, y);
368b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
369b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        // Stop face detection because we want to specify focus and metering area.
370b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        mListener.stopFaceDetection();
371b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
372b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        // Set the focus area and metering area.
373b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        mListener.setFocusParameters();
374b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        if (mFocusAreaSupported) {
375b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            autoFocus();
376b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        } else {  // Just show the indicator in all other cases.
377b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            updateFocusUI();
378b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            // Reset the metering area in 3 seconds.
379b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            mHandler.removeMessages(RESET_TOUCH_FOCUS);
380b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            mHandler.sendEmptyMessageDelayed(RESET_TOUCH_FOCUS, RESET_TOUCH_FOCUS_DELAY);
381b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        }
382b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
383b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
384b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    public void onPreviewStarted() {
385b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        mState = STATE_IDLE;
386b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
387b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
388b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    public void onPreviewStopped() {
3890505273644c4c3aaf908bcda54c6d576a3ebfae8Wu-cheng Li        // If auto focus was in progress, it would have been stopped.
390b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        mState = STATE_IDLE;
391b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        resetTouchFocus();
392b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        updateFocusUI();
393b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
394b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
395b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    public void onCameraReleased() {
396b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        onPreviewStopped();
397b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
398b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
399b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private void autoFocus() {
400b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        Log.v(TAG, "Start autofocus.");
401b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        mListener.autoFocus();
402b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        mState = STATE_FOCUSING;
403b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        // Pause the face view because the driver will keep sending face
404b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        // callbacks after the focus completes.
405b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        if (mFaceView != null) mFaceView.pause();
406b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        updateFocusUI();
407b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        mHandler.removeMessages(RESET_TOUCH_FOCUS);
408b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
409b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
410b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private void cancelAutoFocus() {
411b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        Log.v(TAG, "Cancel autofocus.");
412b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
413b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        // Reset the tap area before calling mListener.cancelAutofocus.
414b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        // Otherwise, focus mode stays at auto and the tap area passed to the
415b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        // driver is not reset.
416b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        resetTouchFocus();
417b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        mListener.cancelAutoFocus();
418b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        if (mFaceView != null) mFaceView.resume();
419b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        mState = STATE_IDLE;
420b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        updateFocusUI();
421b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        mHandler.removeMessages(RESET_TOUCH_FOCUS);
422b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
423b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
424b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private void capture() {
425b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        if (mListener.capture()) {
426b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            mState = STATE_IDLE;
427b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            mHandler.removeMessages(RESET_TOUCH_FOCUS);
428b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        }
429b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
430b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
431b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    public String getFocusMode() {
432b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        if (mOverrideFocusMode != null) return mOverrideFocusMode;
433b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        List<String> supportedFocusModes = mParameters.getSupportedFocusModes();
434b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
435b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        if (mFocusAreaSupported && mFocusArea != null) {
436b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            // Always use autofocus in tap-to-focus.
437b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            mFocusMode = Parameters.FOCUS_MODE_AUTO;
438b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        } else {
439b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            // The default is continuous autofocus.
440b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            mFocusMode = mPreferences.getString(
441b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                    CameraSettings.KEY_FOCUS_MODE, null);
442b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
443b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            // Try to find a supported focus mode from the default list.
444b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            if (mFocusMode == null) {
445b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                for (int i = 0; i < mDefaultFocusModes.length; i++) {
446b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                    String mode = mDefaultFocusModes[i];
447b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                    if (Util.isSupported(mode, supportedFocusModes)) {
448b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                        mFocusMode = mode;
449b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                        break;
450b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                    }
451b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                }
452b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            }
453b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        }
454b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        if (!Util.isSupported(mFocusMode, supportedFocusModes)) {
455b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            // For some reasons, the driver does not support the current
456b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            // focus mode. Fall back to auto.
457b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            if (Util.isSupported(Parameters.FOCUS_MODE_AUTO,
458b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                    mParameters.getSupportedFocusModes())) {
459b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                mFocusMode = Parameters.FOCUS_MODE_AUTO;
460b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            } else {
461b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                mFocusMode = mParameters.getFocusMode();
462b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            }
463b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        }
464b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        return mFocusMode;
465b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
466b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
467b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    public List getFocusAreas() {
468b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        return mFocusArea;
469b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
470b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
471b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    public List getMeteringAreas() {
472b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        return mMeteringArea;
473b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
474b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
475b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    public void updateFocusUI() {
476b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        if (!mInitialized) return;
477b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        // Show only focus indicator or face indicator.
478b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        boolean faceExists = (mFaceView != null && mFaceView.faceExists());
4798042e7045f3e11dd49d40eebe603eb5fe12d711aMichael Kolb        FocusIndicator focusIndicator = (faceExists) ? mFaceView : mPieRenderer;
480b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
481b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        if (mState == STATE_IDLE) {
482b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            if (mFocusArea == null) {
483b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                focusIndicator.clear();
484b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            } else {
485b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                // Users touch on the preview and the indicator represents the
486b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                // metering area. Either focus area is not supported or
487b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                // autoFocus call is not required.
488b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                focusIndicator.showStart();
489b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            }
490b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        } else if (mState == STATE_FOCUSING || mState == STATE_FOCUSING_SNAP_ON_FINISH) {
491b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            focusIndicator.showStart();
492b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        } else {
493b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            if (Util.FOCUS_MODE_CONTINUOUS_PICTURE.equals(mFocusMode)) {
494b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                // TODO: check HAL behavior and decide if this can be removed.
495b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                focusIndicator.showSuccess(false);
496b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            } else if (mState == STATE_SUCCESS) {
497b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                focusIndicator.showSuccess(false);
498b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            } else if (mState == STATE_FAIL) {
499b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                focusIndicator.showFail(false);
500b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            }
501b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        }
502b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
503b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
504b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    public void resetTouchFocus() {
505b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        if (!mInitialized) return;
506b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
507b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        // Put focus indicator to the center. clear reset position
5088042e7045f3e11dd49d40eebe603eb5fe12d711aMichael Kolb        mPieRenderer.clear();
509b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
510b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        mFocusArea = null;
511b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        mMeteringArea = null;
512b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
513b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
514b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private void calculateTapArea(int focusWidth, int focusHeight, float areaMultiple,
515b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb            int x, int y, int previewWidth, int previewHeight, Rect rect) {
516b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        int areaWidth = (int) (focusWidth * areaMultiple);
517b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        int areaHeight = (int) (focusHeight * areaMultiple);
518b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        int left = Util.clamp(x - areaWidth / 2, 0, previewWidth - areaWidth);
519b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        int top = Util.clamp(y - areaHeight / 2, 0, previewHeight - areaHeight);
520b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
521b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        RectF rectF = new RectF(left, top, left + areaWidth, top + areaHeight);
522b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        mMatrix.mapRect(rectF);
523b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        Util.rectFToRect(rectF, rect);
524b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
525b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
5265c7a93d0c29cfd9480817ec8a1c83795199b13edMangesh Ghiware    /* package */ int getFocusState() {
5275c7a93d0c29cfd9480817ec8a1c83795199b13edMangesh Ghiware        return mState;
5285c7a93d0c29cfd9480817ec8a1c83795199b13edMangesh Ghiware    }
5295c7a93d0c29cfd9480817ec8a1c83795199b13edMangesh Ghiware
530b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    public boolean isFocusCompleted() {
531b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        return mState == STATE_SUCCESS || mState == STATE_FAIL;
532b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
533b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
534b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    public boolean isFocusingSnapOnFinish() {
535b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        return mState == STATE_FOCUSING_SNAP_ON_FINISH;
536b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
537b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
538b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    public void removeMessages() {
539b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        mHandler.removeMessages(RESET_TOUCH_FOCUS);
540b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
541b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
542b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    public void overrideFocusMode(String focusMode) {
543b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        mOverrideFocusMode = focusMode;
544b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
545b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
546b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    public void setAeAwbLock(boolean lock) {
547b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        mAeAwbLock = lock;
548b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
549b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
550b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    public boolean getAeAwbLock() {
551b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        return mAeAwbLock;
552b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
553b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
554b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    private boolean needAutoFocusCall() {
555b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        String focusMode = getFocusMode();
556b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        return !(focusMode.equals(Parameters.FOCUS_MODE_INFINITY)
557b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                || focusMode.equals(Parameters.FOCUS_MODE_FIXED)
558b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb                || focusMode.equals(Parameters.FOCUS_MODE_EDOF));
559b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
560b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb}
561