FocusOverlayManager.java revision c0fe0b6915004303a550047e68a2124edae9fdb2
18872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb/*
28872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * Copyright (C) 2012 The Android Open Source Project
38872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *
48872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * Licensed under the Apache License, Version 2.0 (the "License");
58872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * you may not use this file except in compliance with the License.
68872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * You may obtain a copy of the License at
78872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *
88872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *      http://www.apache.org/licenses/LICENSE-2.0
98872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *
108872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * Unless required by applicable law or agreed to in writing, software
118872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * distributed under the License is distributed on an "AS IS" BASIS,
128872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * See the License for the specific language governing permissions and
148872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * limitations under the License.
158872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb */
168872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
178872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbpackage com.android.camera;
188872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
198872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.annotation.TargetApi;
208872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.graphics.Matrix;
218872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.graphics.Rect;
228872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.graphics.RectF;
238872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.hardware.Camera.Area;
24638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberlingimport android.os.Build;
258872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.os.Handler;
268872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.os.Looper;
278872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.os.Message;
288872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
296190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgrenimport com.android.camera.app.AppController;
30fb33336bc6f4b70b0686b5e060819d6bd41f3b6fKevin Gabayanimport com.android.camera.app.MotionManager;
315596b4c902dcb685928b43678f428746ca5ffd08Angus Kongimport com.android.camera.debug.Log;
326190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgrenimport com.android.camera.settings.Keys;
33357b7673f03d9b45d281d585cc3f4f87dc7d727bErin Dahlgrenimport com.android.camera.settings.SettingsManager;
34482de029dc20e0a577388a602985fb31c3200309Doris Liuimport com.android.camera.ui.PreviewStatusListener;
35b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibersimport com.android.camera.ui.TouchCoordinate;
36b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kongimport com.android.camera.util.CameraUtil;
37b6605381f4c2d5d086cdd04c8d3972f22e525be5Andy Huibersimport com.android.camera.util.UsageStatistics;
385a344964cb003525727c31d295ca3a592c245606Sol Boucherimport com.android.ex.camera2.portability.CameraCapabilities;
398872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
40638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberlingimport java.util.ArrayList;
41638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberlingimport java.util.List;
42638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberling
438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb/* A class that handles everything about focus in still picture mode.
448872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * This also handles the metering area because it is the same as focus area.
458872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *
468872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * The test cases:
478872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (1) The camera has continuous autofocus. Move the camera. Take a picture when
488872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *     CAF is not in progress.
498872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (2) The camera has continuous autofocus. Move the camera. Take a picture when
508872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *     CAF is in progress.
518872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (3) The camera has face detection. Point the camera at some faces. Hold the
528872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *     shutter. Release to take a picture.
538872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (4) The camera has face detection. Point the camera at some faces. Single tap
548872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *     the shutter to take a picture.
558872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (5) The camera has autofocus. Single tap the shutter to take a picture.
568872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (6) The camera has autofocus. Hold the shutter. Release to take a picture.
578872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (7) The camera has no autofocus. Single tap the shutter and take a picture.
588872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (8) The camera has autofocus and supports focus area. Touch the screen to
598872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *     trigger autofocus. Take a picture.
608872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (9) The camera has autofocus and supports focus area. Touch the screen to
618872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *     trigger autofocus. Wait until it times out.
628872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (10) The camera has no autofocus and supports metering area. Touch the screen
638872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *     to change metering area.
648872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb */
65fb33336bc6f4b70b0686b5e060819d6bd41f3b6fKevin Gabayanpublic class FocusOverlayManager implements PreviewStatusListener.PreviewAreaChangedListener,
66fb33336bc6f4b70b0686b5e060819d6bd41f3b6fKevin Gabayan        MotionManager.MotionListener {
675596b4c902dcb685928b43678f428746ca5ffd08Angus Kong    private static final Log.Tag TAG = new Log.Tag("FocusOverlayMgr");
688872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
698872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private static final int RESET_TOUCH_FOCUS = 0;
70d4a68ca4e34ad256cd4cd2f7b1faae234d240dfaKevin Gabayan    private static final int RESET_TOUCH_FOCUS_DELAY = 4000;
718872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
728872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private int mState = STATE_IDLE;
738872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private static final int STATE_IDLE = 0; // Focus is not active.
748872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private static final int STATE_FOCUSING = 1; // Focus is in progress.
758872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    // Focus is in progress and the camera should take a picture after focus finishes.
768872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private static final int STATE_FOCUSING_SNAP_ON_FINISH = 2;
778872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private static final int STATE_SUCCESS = 3; // Focus finishes and succeeds.
788872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private static final int STATE_FAIL = 4; // Focus finishes and fails.
798872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
808872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private boolean mInitialized;
818872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private boolean mFocusAreaSupported;
828872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private boolean mMeteringAreaSupported;
838872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private boolean mLockAeAwbNeeded;
848872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private boolean mAeAwbLock;
85a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling    private final Matrix mMatrix;
868872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
878872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private boolean mMirror; // true if the camera is front-facing.
888872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private int mDisplayOrientation;
89a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling    private List<Area> mFocusArea; // focus area in driver format
90a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling    private List<Area> mMeteringArea; // metering area in driver format
91831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong    private CameraCapabilities.FocusMode mFocusMode;
92831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong    private final List<CameraCapabilities.FocusMode> mDefaultFocusModes;
93831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong    private CameraCapabilities.FocusMode mOverrideFocusMode;
9488289047ba6928e317d17f2e1d4b013693545c67Angus Kong    private CameraCapabilities mCapabilities;
956190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren    private final AppController mAppController;
96a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling    private final SettingsManager mSettingsManager;
97a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling    private final Handler mHandler;
988872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    Listener mListener;
99e3de7223ee3fe56e097d68f50c5a59ae61370d65Michael Kolb    private boolean mPreviousMoving;
100a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling    private final FocusUI mUI;
10136ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu    private final Rect mPreviewRect = new Rect(0, 0, 0, 0);
102fb33336bc6f4b70b0686b5e060819d6bd41f3b6fKevin Gabayan    private boolean mFocusLocked;
103d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
104b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers    /** Manual tap to focus parameters */
105b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers    private TouchCoordinate mTouchCoordinate;
106b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers    private long mTouchTime;
107b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers
108d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public  interface FocusUI {
109d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        public boolean hasFaces();
110d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        public void clearFocus();
111c0fe0b6915004303a550047e68a2124edae9fdb2Andy Huibers        public void setFocusPosition(int x, int y, boolean isPassiveScan);
112d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        public void onFocusStarted();
113e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling        public void onFocusSucceeded();
114e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling        public void onFocusFailed();
115d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        public void pauseFaceDetection();
116d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        public void resumeFaceDetection();
117d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
118d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
1198872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public interface Listener {
1208872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        public void autoFocus();
1218872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        public void cancelAutoFocus();
1228872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        public boolean capture();
1238872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        public void startFaceDetection();
1248872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        public void stopFaceDetection();
1258872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        public void setFocusParameters();
1268872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
1278872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
1288872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private class MainHandler extends Handler {
1298872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        public MainHandler(Looper looper) {
1308872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            super(looper);
1318872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
1328872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
1338872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        @Override
1348872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        public void handleMessage(Message msg) {
1358872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            switch (msg.what) {
1368872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                case RESET_TOUCH_FOCUS: {
1378872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                    cancelAutoFocus();
1388872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                    mListener.startFaceDetection();
1398872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                    break;
1408872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                }
1418872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            }
1428872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
1438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
1448872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
1456190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren    public FocusOverlayManager(AppController appController,
146831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong            List<CameraCapabilities.FocusMode> defaultFocusModes, CameraCapabilities capabilities,
147831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong            Listener listener, boolean mirror, Looper looper, FocusUI ui) {
1486190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren        mAppController = appController;
1496190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren        mSettingsManager = appController.getSettingsManager();
1508872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mHandler = new MainHandler(looper);
1518872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mMatrix = new Matrix();
152ee36c5f591ac181a10692b2ec2b96de5251c4abbSascha Haeberling        mDefaultFocusModes = new ArrayList<CameraCapabilities.FocusMode>(defaultFocusModes);
153831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong        updateCapabilities(capabilities);
1548872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mListener = listener;
1558872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        setMirror(mirror);
156d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mUI = ui;
157fb33336bc6f4b70b0686b5e060819d6bd41f3b6fKevin Gabayan        mFocusLocked = false;
1588872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
1598872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
160831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong    public void updateCapabilities(CameraCapabilities capabilities) {
16109e134056bf85ee87855a44bfc5d8e7b055fe2e9Andy Huibers        // capabilities can only be null when onConfigurationChanged is called
1628872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // before camera is open. We will just return in this case, because
16309e134056bf85ee87855a44bfc5d8e7b055fe2e9Andy Huibers        // capabilities will be set again later with the right capabilities after
1648872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // camera is open.
16509e134056bf85ee87855a44bfc5d8e7b055fe2e9Andy Huibers        if (capabilities == null) {
166e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling            return;
167e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        }
16888289047ba6928e317d17f2e1d4b013693545c67Angus Kong        mCapabilities = capabilities;
16988289047ba6928e317d17f2e1d4b013693545c67Angus Kong        mFocusAreaSupported = mCapabilities.supports(CameraCapabilities.Feature.FOCUS_AREA);
17088289047ba6928e317d17f2e1d4b013693545c67Angus Kong        mMeteringAreaSupported = mCapabilities.supports(CameraCapabilities.Feature.METERING_AREA);
17188289047ba6928e317d17f2e1d4b013693545c67Angus Kong        mLockAeAwbNeeded = (mCapabilities.supports(CameraCapabilities.Feature.AUTO_EXPOSURE_LOCK)
17288289047ba6928e317d17f2e1d4b013693545c67Angus Kong                || mCapabilities.supports(CameraCapabilities.Feature.AUTO_WHITE_BALANCE_LOCK));
1738872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
1748872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
17536ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu    /** This setter should be the only way to mutate mPreviewRect. */
17636ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu    public void setPreviewRect(Rect previewRect) {
17736ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu        if (!mPreviewRect.equals(previewRect)) {
17836ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu            mPreviewRect.set(previewRect);
1798872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            setMatrix();
1808872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
1818872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
1828872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
183482de029dc20e0a577388a602985fb31c3200309Doris Liu    @Override
1842bacca795a1b0adb0daf515c43c48234b44bbba5Angus Kong    public void onPreviewAreaChanged(RectF previewArea) {
185a1ec04a9f9526418f5cb17a5afbfc48aca1e02d0Doris Liu        setPreviewRect(CameraUtil.rectFToRect(previewArea));
186482de029dc20e0a577388a602985fb31c3200309Doris Liu    }
187482de029dc20e0a577388a602985fb31c3200309Doris Liu
18836ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu    /** Returns a copy of mPreviewRect so that outside class cannot modify preview
18936ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu     *  rect except deliberately doing so through the setter. */
19036ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu    public Rect getPreviewRect() {
19136ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu        return new Rect(mPreviewRect);
19236ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu    }
19336ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu
1948872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void setMirror(boolean mirror) {
1958872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mMirror = mirror;
1968872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        setMatrix();
1978872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
1988872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
1998872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void setDisplayOrientation(int displayOrientation) {
2008872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mDisplayOrientation = displayOrientation;
2018872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        setMatrix();
2028872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
2038872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
2048872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private void setMatrix() {
20536ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu        if (mPreviewRect.width() != 0 && mPreviewRect.height() != 0) {
2068872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            Matrix matrix = new Matrix();
20736ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu            CameraUtil.prepareMatrix(matrix, mMirror, mDisplayOrientation, getPreviewRect());
2088872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // In face detection, the matrix converts the driver coordinates to UI
2098872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // coordinates. In tap focus, the inverted matrix converts the UI
2108872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // coordinates to driver coordinates.
2118872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            matrix.invert(mMatrix);
212d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mInitialized = true;
2138872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
2148872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
2158872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
2168872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private void lockAeAwbIfNeeded() {
2178872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        if (mLockAeAwbNeeded && !mAeAwbLock) {
2188872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mAeAwbLock = true;
2198872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mListener.setFocusParameters();
2208872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
2218872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
2228872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
2238872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private void unlockAeAwbIfNeeded() {
2248872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        if (mLockAeAwbNeeded && mAeAwbLock && (mState != STATE_FOCUSING_SNAP_ON_FINISH)) {
2258872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mAeAwbLock = false;
2268872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mListener.setFocusParameters();
2278872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
2288872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
2298872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
230831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong    public void onShutterUp(CameraCapabilities.FocusMode currentFocusMode) {
231e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        if (!mInitialized) {
232e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling            return;
233e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        }
2348872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
235831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong        if (needAutoFocusCall(currentFocusMode)) {
2368872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // User releases half-pressed focus key.
2378872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            if (mState == STATE_FOCUSING || mState == STATE_SUCCESS
2388872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                    || mState == STATE_FAIL) {
2398872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                cancelAutoFocus();
2408872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            }
2418872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
2428872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
2438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // Unlock AE and AWB after cancelAutoFocus. Camera API does not
2448872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // guarantee setParameters can be called during autofocus.
2458872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        unlockAeAwbIfNeeded();
2468872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
2478872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
248831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong    public void focusAndCapture(CameraCapabilities.FocusMode currentFocusMode) {
249e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        if (!mInitialized) {
250e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling            return;
251e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        }
2528872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
253831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong        if (!needAutoFocusCall(currentFocusMode)) {
254eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong            // Focus is not needed.
255eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong            capture();
256eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong        } else if (mState == STATE_SUCCESS || mState == STATE_FAIL) {
257eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong            // Focus is done already.
2588872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            capture();
2598872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        } else if (mState == STATE_FOCUSING) {
260eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong            // Still focusing and will not trigger snap upon finish.
2618872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mState = STATE_FOCUSING_SNAP_ON_FINISH;
2628872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        } else if (mState == STATE_IDLE) {
263eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong            autoFocusAndCapture();
2648872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
2658872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
2668872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
2678872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void onAutoFocus(boolean focused, boolean shutterButtonPressed) {
2688872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        if (mState == STATE_FOCUSING_SNAP_ON_FINISH) {
2698872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // Take the picture no matter focus succeeds or fails. No need
2708872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // to play the AF sound if we're about to play the shutter
2718872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // sound.
2728872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            if (focused) {
2738872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                mState = STATE_SUCCESS;
2748872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            } else {
2758872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                mState = STATE_FAIL;
2768872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            }
2778872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            updateFocusUI();
2788872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            capture();
2798872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        } else if (mState == STATE_FOCUSING) {
2808872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // This happens when (1) user is half-pressing the focus key or
2818872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // (2) touch focus is triggered. Play the focus tone. Do not
2828872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // take the picture now.
2838872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            if (focused) {
2848872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                mState = STATE_SUCCESS;
2858872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            } else {
2868872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                mState = STATE_FAIL;
2878872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            }
2888872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            updateFocusUI();
2898872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // If this is triggered by touch focus, cancel focus after a
2908872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // while.
291b05794393444ebd13bd24c2ecfb3fbd9963f688eMichael Kolb            if (mFocusArea != null) {
292fb33336bc6f4b70b0686b5e060819d6bd41f3b6fKevin Gabayan                mFocusLocked = true;
2938872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                mHandler.sendEmptyMessageDelayed(RESET_TOUCH_FOCUS, RESET_TOUCH_FOCUS_DELAY);
2948872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            }
2958872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            if (shutterButtonPressed) {
2968872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                // Lock AE & AWB so users can half-press shutter and recompose.
2978872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                lockAeAwbIfNeeded();
2988872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            }
2998872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        } else if (mState == STATE_IDLE) {
3008872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // User has released the focus key before focus completes.
3018872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // Do nothing.
3028872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
3038872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
3048872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
3058872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void onAutoFocusMoving(boolean moving) {
306e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        if (!mInitialized) {
307e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling            return;
308e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        }
309d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
310d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
3118872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // Ignore if the camera has detected some faces.
312d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        if (mUI.hasFaces()) {
313d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mUI.clearFocus();
3148872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            return;
3158872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
3168872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
3178872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // Ignore if we have requested autofocus. This method only handles
3188872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // continuous autofocus.
319e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        if (mState != STATE_IDLE) {
320e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling            return;
321e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        }
3228872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
323e3de7223ee3fe56e097d68f50c5a59ae61370d65Michael Kolb        // animate on false->true trasition only b/8219520
324e3de7223ee3fe56e097d68f50c5a59ae61370d65Michael Kolb        if (moving && !mPreviousMoving) {
325ca4a5668c5bcda027bd896ebf17c8ef374e2ac75Doris Liu            // Auto focus at the center of the preview.
32610a035c93e2cb3ed65f59258fa4d0aca89555bcdDoris Liu            mUI.setFocusPosition(mPreviewRect.centerX(), mPreviewRect.centerY(), true);
327d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mUI.onFocusStarted();
328e3de7223ee3fe56e097d68f50c5a59ae61370d65Michael Kolb        } else if (!moving) {
329e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling            mUI.onFocusSucceeded();
3308872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
331e3de7223ee3fe56e097d68f50c5a59ae61370d65Michael Kolb        mPreviousMoving = moving;
3328872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
3338872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
334638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberling    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
3350718d480a144ba0a44c07c48f90e85cf4ec669c6Michael Kolb    private void initializeFocusAreas(int x, int y) {
3368872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        if (mFocusArea == null) {
337a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling            mFocusArea = new ArrayList<Area>();
3388872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mFocusArea.add(new Area(new Rect(), 1));
3398872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
3408872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
3418872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // Convert the coordinates to driver format.
342a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling        calculateTapArea(x, y, 1f, mFocusArea.get(0).rect);
3438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
3448872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
345638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberling    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
3460718d480a144ba0a44c07c48f90e85cf4ec669c6Michael Kolb    private void initializeMeteringAreas(int x, int y) {
3478872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        if (mMeteringArea == null) {
348a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling            mMeteringArea = new ArrayList<Area>();
3498872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mMeteringArea.add(new Area(new Rect(), 1));
3508872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
3518872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
3528872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // Convert the coordinates to driver format.
3538872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // AE area is bigger because exposure is sensitive and
3548872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // easy to over- or underexposure if area is too small.
355a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling        calculateTapArea(x, y, 1.5f, mMeteringArea.get(0).rect);
3568872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
3578872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
3588872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void onSingleTapUp(int x, int y) {
359e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        if (!mInitialized || mState == STATE_FOCUSING_SNAP_ON_FINISH) {
360e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling            return;
361e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        }
3628872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
3638872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // Let users be able to cancel previous touch focus.
364b05794393444ebd13bd24c2ecfb3fbd9963f688eMichael Kolb        if ((mFocusArea != null) && (mState == STATE_FOCUSING ||
3658872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                    mState == STATE_SUCCESS || mState == STATE_FAIL)) {
3668872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            cancelAutoFocus();
3678872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
368e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        if (mPreviewRect.width() == 0 || mPreviewRect.height() == 0) {
369e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling            return;
370e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        }
371b05794393444ebd13bd24c2ecfb3fbd9963f688eMichael Kolb        // Initialize variables.
3728872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // Initialize mFocusArea.
3738872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        if (mFocusAreaSupported) {
3740718d480a144ba0a44c07c48f90e85cf4ec669c6Michael Kolb            initializeFocusAreas(x, y);
3758872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
3768872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // Initialize mMeteringArea.
3778872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        if (mMeteringAreaSupported) {
3780718d480a144ba0a44c07c48f90e85cf4ec669c6Michael Kolb            initializeMeteringAreas(x, y);
3798872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
3808872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
3818872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // Use margin to set the focus indicator to the touched area.
38210a035c93e2cb3ed65f59258fa4d0aca89555bcdDoris Liu        mUI.setFocusPosition(x, y, false);
383b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers        // Log manual tap to focus.
384b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers        mTouchCoordinate = new TouchCoordinate(x, y, mPreviewRect.width(), mPreviewRect.height());
385b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers        mTouchTime = System.currentTimeMillis();
3868872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
3878872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // Stop face detection because we want to specify focus and metering area.
3888872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mListener.stopFaceDetection();
3898872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
3908872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // Set the focus area and metering area.
3918872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mListener.setFocusParameters();
3928872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        if (mFocusAreaSupported) {
3938872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            autoFocus();
3948872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        } else {  // Just show the indicator in all other cases.
3958872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            updateFocusUI();
396d4a68ca4e34ad256cd4cd2f7b1faae234d240dfaKevin Gabayan            // Reset the metering area in 4 seconds.
3978872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mHandler.removeMessages(RESET_TOUCH_FOCUS);
3988872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mHandler.sendEmptyMessageDelayed(RESET_TOUCH_FOCUS, RESET_TOUCH_FOCUS_DELAY);
3998872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
4008872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
4018872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
4028872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void onPreviewStarted() {
4038872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mState = STATE_IDLE;
4048872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
4058872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
4068872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void onPreviewStopped() {
4078872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // If auto focus was in progress, it would have been stopped.
4088872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mState = STATE_IDLE;
4098872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        resetTouchFocus();
4108872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        updateFocusUI();
4118872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
4128872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
4138872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void onCameraReleased() {
4148872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        onPreviewStopped();
4158872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
4168872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
417fb33336bc6f4b70b0686b5e060819d6bd41f3b6fKevin Gabayan    @Override
418fb33336bc6f4b70b0686b5e060819d6bd41f3b6fKevin Gabayan    public void onMoving() {
419fb33336bc6f4b70b0686b5e060819d6bd41f3b6fKevin Gabayan        if (mFocusLocked) {
420fb33336bc6f4b70b0686b5e060819d6bd41f3b6fKevin Gabayan            Log.d(TAG, "onMoving: Early focus unlock.");
421fb33336bc6f4b70b0686b5e060819d6bd41f3b6fKevin Gabayan            cancelAutoFocus();
422fb33336bc6f4b70b0686b5e060819d6bd41f3b6fKevin Gabayan        }
423fb33336bc6f4b70b0686b5e060819d6bd41f3b6fKevin Gabayan    }
424fb33336bc6f4b70b0686b5e060819d6bd41f3b6fKevin Gabayan
425eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong    /**
426eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong     * Triggers the autofocus and sets the specified state.
427eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong     *
428eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong     * @param focusingState The state to use when focus is in progress.
429eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong     */
430eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong    private void autoFocus(int focusingState) {
4318872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mListener.autoFocus();
432eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong        mState = focusingState;
4338872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // Pause the face view because the driver will keep sending face
4348872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // callbacks after the focus completes.
435d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mUI.pauseFaceDetection();
4368872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        updateFocusUI();
4378872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mHandler.removeMessages(RESET_TOUCH_FOCUS);
4388872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
4398872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
440eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong    /**
441eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong     * Triggers the autofocus and set the state to indicate the focus is in
442eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong     * progress.
443eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong     */
444eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong    private void autoFocus() {
445eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong        autoFocus(STATE_FOCUSING);
446eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong    }
447eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong
448eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong    /**
449eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong     * Triggers the autofocus and set the state to which a capture will happen
450eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong     * in the following autofocus callback.
451eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong     */
452eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong    private void autoFocusAndCapture() {
453eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong        autoFocus(STATE_FOCUSING_SNAP_ON_FINISH);
454eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong    }
455eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong
4568872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private void cancelAutoFocus() {
457516c11a6885f6e524927bd369567f5bbd592f8efKevin Gabayan        Log.v(TAG, "Cancel autofocus.");
4588872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // Reset the tap area before calling mListener.cancelAutofocus.
4598872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // Otherwise, focus mode stays at auto and the tap area passed to the
4608872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // driver is not reset.
4618872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        resetTouchFocus();
4628872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mListener.cancelAutoFocus();
463d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mUI.resumeFaceDetection();
4648872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mState = STATE_IDLE;
465fb33336bc6f4b70b0686b5e060819d6bd41f3b6fKevin Gabayan        mFocusLocked = false;
4668872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        updateFocusUI();
4678872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mHandler.removeMessages(RESET_TOUCH_FOCUS);
4688872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
4698872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
4708872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private void capture() {
4718872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        if (mListener.capture()) {
4728872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mState = STATE_IDLE;
4738872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mHandler.removeMessages(RESET_TOUCH_FOCUS);
4748872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
4758872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
4768872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
477831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong    public CameraCapabilities.FocusMode getFocusMode(
478831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong            final CameraCapabilities.FocusMode currentFocusMode) {
479831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong        if (mOverrideFocusMode != null) {
480ec4a3fc5e87bf545fb718189b37538f1f1da68dfAlan Newberger            Log.v(TAG, "returning override focus: " + mOverrideFocusMode);
481831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong            return mOverrideFocusMode;
482831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong        }
483831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong        if (mCapabilities == null) {
484ec4a3fc5e87bf545fb718189b37538f1f1da68dfAlan Newberger            Log.v(TAG, "no capabilities, returning default AUTO focus mode");
485831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong            return CameraCapabilities.FocusMode.AUTO;
486831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong        }
4878872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
488b05794393444ebd13bd24c2ecfb3fbd9963f688eMichael Kolb        if (mFocusAreaSupported && mFocusArea != null) {
489ec4a3fc5e87bf545fb718189b37538f1f1da68dfAlan Newberger            Log.v(TAG, "in tap to focus, returning AUTO focus mode");
4908872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // Always use autofocus in tap-to-focus.
491831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong            mFocusMode = CameraCapabilities.FocusMode.AUTO;
4928872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        } else {
493ec4a3fc5e87bf545fb718189b37538f1f1da68dfAlan Newberger            String focusSetting = mSettingsManager.getString(mAppController.getCameraScope(),
494ec4a3fc5e87bf545fb718189b37538f1f1da68dfAlan Newberger                    Keys.KEY_FOCUS_MODE);
495ec4a3fc5e87bf545fb718189b37538f1f1da68dfAlan Newberger            Log.v(TAG, "stored focus setting for camera: " + focusSetting);
4968872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // The default is continuous autofocus.
497ec4a3fc5e87bf545fb718189b37538f1f1da68dfAlan Newberger            mFocusMode = mCapabilities.getStringifier().focusModeFromString(focusSetting);
498ec4a3fc5e87bf545fb718189b37538f1f1da68dfAlan Newberger            Log.v(TAG, "focus mode resolved from setting: " + mFocusMode);
4998872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // Try to find a supported focus mode from the default list.
5008872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            if (mFocusMode == null) {
501831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong                for (CameraCapabilities.FocusMode mode : mDefaultFocusModes) {
502831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong                    if (mCapabilities.supports(mode)) {
5038872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                        mFocusMode = mode;
504ec4a3fc5e87bf545fb718189b37538f1f1da68dfAlan Newberger                        Log.v(TAG, "selected supported focus mode from default list" + mode);
5058872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                        break;
5068872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                    }
5078872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                }
5088872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            }
5098872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
510831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong        if (!mCapabilities.supports(mFocusMode)) {
5118872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // For some reasons, the driver does not support the current
5128872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // focus mode. Fall back to auto.
513831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong            if (mCapabilities.supports(CameraCapabilities.FocusMode.AUTO)) {
514ec4a3fc5e87bf545fb718189b37538f1f1da68dfAlan Newberger                Log.v(TAG, "no supported focus mode, falling back to AUTO");
515831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong                mFocusMode = CameraCapabilities.FocusMode.AUTO;
5168872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            } else {
517ec4a3fc5e87bf545fb718189b37538f1f1da68dfAlan Newberger                Log.v(TAG, "no supported focus mode, falling back to current: " + currentFocusMode);
518831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong                mFocusMode = currentFocusMode;
5198872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            }
5208872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
5218872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return mFocusMode;
5228872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
5238872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
524a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling    public List<Area> getFocusAreas() {
5258872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return mFocusArea;
5268872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
5278872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
528a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling    public List<Area> getMeteringAreas() {
5298872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return mMeteringArea;
5308872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
5318872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
5328872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void updateFocusUI() {
533e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        if (!mInitialized) {
534e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling            // Show only focus indicator or face indicator.
535e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling            return;
536e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        }
5378872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        if (mState == STATE_IDLE) {
538b05794393444ebd13bd24c2ecfb3fbd9963f688eMichael Kolb            if (mFocusArea == null) {
539d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb                mUI.clearFocus();
5408872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            } else {
5418872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                // Users touch on the preview and the indicator represents the
5428872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                // metering area. Either focus area is not supported or
5438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                // autoFocus call is not required.
544d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb                mUI.onFocusStarted();
5458872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            }
5468872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        } else if (mState == STATE_FOCUSING || mState == STATE_FOCUSING_SNAP_ON_FINISH) {
547d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mUI.onFocusStarted();
5488872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        } else {
549831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong            if (mFocusMode == CameraCapabilities.FocusMode.CONTINUOUS_PICTURE) {
5508872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                // TODO: check HAL behavior and decide if this can be removed.
551e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling                mUI.onFocusSucceeded();
5528872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            } else if (mState == STATE_SUCCESS) {
553e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling                mUI.onFocusSucceeded();
5548872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            } else if (mState == STATE_FAIL) {
555e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling                mUI.onFocusFailed();
5568872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            }
5578872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
5588872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
5598872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
5608872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void resetTouchFocus() {
561e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        if (!mInitialized) {
562e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling            return;
563e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        }
5648872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
5658872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // Put focus indicator to the center. clear reset position
566d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mUI.clearFocus();
5670718d480a144ba0a44c07c48f90e85cf4ec669c6Michael Kolb        // Initialize mFocusArea.
568b05794393444ebd13bd24c2ecfb3fbd9963f688eMichael Kolb        mFocusArea = null;
569b05794393444ebd13bd24c2ecfb3fbd9963f688eMichael Kolb        mMeteringArea = null;
570b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers
571b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers        if (mTouchCoordinate != null) {
572b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers            UsageStatistics.instance().tapToFocus(mTouchCoordinate,
573b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers                    0.001f * (System.currentTimeMillis() - mTouchTime));
574b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers            mTouchCoordinate = null;
575b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers        }
5768872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
5778872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
5780718d480a144ba0a44c07c48f90e85cf4ec669c6Michael Kolb    private void calculateTapArea(int x, int y, float areaMultiple, Rect rect) {
579b3749f2071f866c43ea5f70de219f23157097077Doris Liu        int areaSize = (int) (getAreaSize() * areaMultiple);
58036ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu        int left = CameraUtil.clamp(x - areaSize / 2, mPreviewRect.left,
58136ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu                mPreviewRect.right - areaSize);
58236ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu        int top = CameraUtil.clamp(y - areaSize / 2, mPreviewRect.top,
58336ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu                mPreviewRect.bottom - areaSize);
5848872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
585b3749f2071f866c43ea5f70de219f23157097077Doris Liu        RectF rectF = new RectF(left, top, left + areaSize, top + areaSize);
5868872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mMatrix.mapRect(rectF);
587b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong        CameraUtil.rectFToRect(rectF, rect);
5888872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
5898872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
590b3749f2071f866c43ea5f70de219f23157097077Doris Liu    private int getAreaSize() {
591b3749f2071f866c43ea5f70de219f23157097077Doris Liu        // Recommended focus area size from the manufacture is 1/8 of the image
5922ba03263340639635120be467f8cabec2889aa08Doris Liu        // width (i.e. longer edge of the image)
59336ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu        return Math.max(mPreviewRect.width(), mPreviewRect.height()) / 8;
594b3749f2071f866c43ea5f70de219f23157097077Doris Liu    }
595b3749f2071f866c43ea5f70de219f23157097077Doris Liu
5968872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    /* package */ int getFocusState() {
5978872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return mState;
5988872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
5998872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
6008872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public boolean isFocusCompleted() {
6018872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return mState == STATE_SUCCESS || mState == STATE_FAIL;
6028872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6038872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
6048872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public boolean isFocusingSnapOnFinish() {
6058872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return mState == STATE_FOCUSING_SNAP_ON_FINISH;
6068872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6078872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
6088872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void removeMessages() {
6098872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mHandler.removeMessages(RESET_TOUCH_FOCUS);
6108872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6118872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
612831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong    public void overrideFocusMode(CameraCapabilities.FocusMode focusMode) {
6138872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mOverrideFocusMode = focusMode;
6148872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6158872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
6168872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void setAeAwbLock(boolean lock) {
6178872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mAeAwbLock = lock;
6188872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6198872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
6208872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public boolean getAeAwbLock() {
6218872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return mAeAwbLock;
6228872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6238872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
624831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong    private boolean needAutoFocusCall(CameraCapabilities.FocusMode focusMode) {
625831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong        return !(focusMode == CameraCapabilities.FocusMode.INFINITY
626831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong                || focusMode == CameraCapabilities.FocusMode.FIXED
627831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong                || focusMode == CameraCapabilities.FocusMode.EXTENDED_DOF);
6288872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6298872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb}
630