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