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;
32b868274c9dc8d9c772ec89fb5955215cc7911087Andy Huibersimport com.android.camera.one.Settings3A;
336190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgrenimport com.android.camera.settings.Keys;
34357b7673f03d9b45d281d585cc3f4f87dc7d727bErin Dahlgrenimport com.android.camera.settings.SettingsManager;
35482de029dc20e0a577388a602985fb31c3200309Doris Liuimport com.android.camera.ui.PreviewStatusListener;
36b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibersimport com.android.camera.ui.TouchCoordinate;
37b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kongimport com.android.camera.util.CameraUtil;
38b6605381f4c2d5d086cdd04c8d3972f22e525be5Andy Huibersimport com.android.camera.util.UsageStatistics;
395a344964cb003525727c31d295ca3a592c245606Sol Boucherimport com.android.ex.camera2.portability.CameraCapabilities;
408872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
41375f9d11af33688eb0074e3828c870076cfa21b3Sascha Haeberlingimport java.lang.ref.WeakReference;
42638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberlingimport java.util.ArrayList;
43638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberlingimport java.util.List;
44638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberling
458872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb/* A class that handles everything about focus in still picture mode.
468872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * This also handles the metering area because it is the same as focus area.
478872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *
488872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * The test cases:
498872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (1) The camera has continuous autofocus. Move the camera. Take a picture when
508872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *     CAF is not in progress.
518872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (2) The camera has continuous autofocus. Move the camera. Take a picture when
528872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *     CAF is in progress.
538872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (3) The camera has face detection. Point the camera at some faces. Hold the
548872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *     shutter. Release to take a picture.
558872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (4) The camera has face detection. Point the camera at some faces. Single tap
568872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *     the shutter to take a picture.
578872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (5) The camera has autofocus. Single tap the shutter to take a picture.
588872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (6) The camera has autofocus. Hold the shutter. Release to take a picture.
598872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (7) The camera has no autofocus. Single tap the shutter and take a picture.
608872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (8) The camera has autofocus and supports focus area. Touch the screen to
618872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *     trigger autofocus. Take a picture.
628872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (9) The camera has autofocus and supports focus area. Touch the screen to
638872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *     trigger autofocus. Wait until it times out.
648872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * (10) The camera has no autofocus and supports metering area. Touch the screen
658872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *     to change metering area.
668872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb */
67fb33336bc6f4b70b0686b5e060819d6bd41f3b6fKevin Gabayanpublic class FocusOverlayManager implements PreviewStatusListener.PreviewAreaChangedListener,
68fb33336bc6f4b70b0686b5e060819d6bd41f3b6fKevin Gabayan        MotionManager.MotionListener {
695596b4c902dcb685928b43678f428746ca5ffd08Angus Kong    private static final Log.Tag TAG = new Log.Tag("FocusOverlayMgr");
708872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
718872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private static final int RESET_TOUCH_FOCUS = 0;
72e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers
73b868274c9dc8d9c772ec89fb5955215cc7911087Andy Huibers    private static final int RESET_TOUCH_FOCUS_DELAY_MILLIS = Settings3A.getFocusHoldMillis();
74b868274c9dc8d9c772ec89fb5955215cc7911087Andy Huibers
75b868274c9dc8d9c772ec89fb5955215cc7911087Andy Huibers    public static final float AF_REGION_BOX = Settings3A.getAutoFocusRegionWidth();
76b868274c9dc8d9c772ec89fb5955215cc7911087Andy Huibers    public static final float AE_REGION_BOX = Settings3A.getMeteringRegionWidth();
778872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
788872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private int mState = STATE_IDLE;
798872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private static final int STATE_IDLE = 0; // Focus is not active.
808872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private static final int STATE_FOCUSING = 1; // Focus is in progress.
818872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    // Focus is in progress and the camera should take a picture after focus finishes.
828872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private static final int STATE_FOCUSING_SNAP_ON_FINISH = 2;
838872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private static final int STATE_SUCCESS = 3; // Focus finishes and succeeds.
848872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private static final int STATE_FAIL = 4; // Focus finishes and fails.
858872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
868872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private boolean mInitialized;
878872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private boolean mFocusAreaSupported;
888872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private boolean mMeteringAreaSupported;
898872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private boolean mLockAeAwbNeeded;
908872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private boolean mAeAwbLock;
91a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling    private final Matrix mMatrix;
928872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
938872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private boolean mMirror; // true if the camera is front-facing.
948872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private int mDisplayOrientation;
95a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling    private List<Area> mFocusArea; // focus area in driver format
96a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling    private List<Area> mMeteringArea; // metering area in driver format
97831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong    private CameraCapabilities.FocusMode mFocusMode;
98831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong    private final List<CameraCapabilities.FocusMode> mDefaultFocusModes;
99831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong    private CameraCapabilities.FocusMode mOverrideFocusMode;
10088289047ba6928e317d17f2e1d4b013693545c67Angus Kong    private CameraCapabilities mCapabilities;
1016190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren    private final AppController mAppController;
102a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling    private final SettingsManager mSettingsManager;
103a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling    private final Handler mHandler;
1048872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    Listener mListener;
105e3de7223ee3fe56e097d68f50c5a59ae61370d65Michael Kolb    private boolean mPreviousMoving;
106a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling    private final FocusUI mUI;
10736ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu    private final Rect mPreviewRect = new Rect(0, 0, 0, 0);
108fb33336bc6f4b70b0686b5e060819d6bd41f3b6fKevin Gabayan    private boolean mFocusLocked;
109d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
110b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers    /** Manual tap to focus parameters */
111b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers    private TouchCoordinate mTouchCoordinate;
112b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers    private long mTouchTime;
113b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers
114d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    public  interface FocusUI {
115d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        public boolean hasFaces();
116d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        public void clearFocus();
117e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers        public void setFocusPosition(int x, int y, boolean isPassiveScan, int aFsize, int aEsize);
118c0fe0b6915004303a550047e68a2124edae9fdb2Andy Huibers        public void setFocusPosition(int x, int y, boolean isPassiveScan);
119d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        public void onFocusStarted();
120e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling        public void onFocusSucceeded();
121e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling        public void onFocusFailed();
122ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers        public void setPassiveFocusSuccess(boolean success);
123ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers        public void showDebugMessage(String message);
124d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        public void pauseFaceDetection();
125d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        public void resumeFaceDetection();
126d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb    }
127d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
1288872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public interface Listener {
1298872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        public void autoFocus();
1308872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        public void cancelAutoFocus();
1318872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        public boolean capture();
1328872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        public void startFaceDetection();
1338872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        public void stopFaceDetection();
1348872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        public void setFocusParameters();
1358872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
1368872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
137375f9d11af33688eb0074e3828c870076cfa21b3Sascha Haeberling    /**
138375f9d11af33688eb0074e3828c870076cfa21b3Sascha Haeberling     * TODO: Refactor this so that we either don't need a handler or make
139375f9d11af33688eb0074e3828c870076cfa21b3Sascha Haeberling     * mListener not be the activity.
140375f9d11af33688eb0074e3828c870076cfa21b3Sascha Haeberling     */
141375f9d11af33688eb0074e3828c870076cfa21b3Sascha Haeberling    private static class MainHandler extends Handler {
142375f9d11af33688eb0074e3828c870076cfa21b3Sascha Haeberling        /**
143375f9d11af33688eb0074e3828c870076cfa21b3Sascha Haeberling         * The outer mListener at the moment is actually the CameraActivity,
144375f9d11af33688eb0074e3828c870076cfa21b3Sascha Haeberling         * which we would leak if we didn't break the GC path here using a
145375f9d11af33688eb0074e3828c870076cfa21b3Sascha Haeberling         * WeakReference.
146375f9d11af33688eb0074e3828c870076cfa21b3Sascha Haeberling         */
147375f9d11af33688eb0074e3828c870076cfa21b3Sascha Haeberling        final WeakReference<FocusOverlayManager> mManager;
148375f9d11af33688eb0074e3828c870076cfa21b3Sascha Haeberling        public MainHandler(FocusOverlayManager manager, Looper looper) {
1498872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            super(looper);
150375f9d11af33688eb0074e3828c870076cfa21b3Sascha Haeberling            mManager = new WeakReference<FocusOverlayManager>(manager);
1518872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
1528872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
1538872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        @Override
1548872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        public void handleMessage(Message msg) {
155375f9d11af33688eb0074e3828c870076cfa21b3Sascha Haeberling            FocusOverlayManager manager = mManager.get();
156375f9d11af33688eb0074e3828c870076cfa21b3Sascha Haeberling            if (manager == null) {
157375f9d11af33688eb0074e3828c870076cfa21b3Sascha Haeberling                return;
158375f9d11af33688eb0074e3828c870076cfa21b3Sascha Haeberling            }
159375f9d11af33688eb0074e3828c870076cfa21b3Sascha Haeberling
1608872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            switch (msg.what) {
1618872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                case RESET_TOUCH_FOCUS: {
162375f9d11af33688eb0074e3828c870076cfa21b3Sascha Haeberling                    manager.cancelAutoFocus();
163375f9d11af33688eb0074e3828c870076cfa21b3Sascha Haeberling                    manager.mListener.startFaceDetection();
1648872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                    break;
1658872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                }
1668872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            }
1678872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
1688872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
1698872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
1706190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren    public FocusOverlayManager(AppController appController,
171831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong            List<CameraCapabilities.FocusMode> defaultFocusModes, CameraCapabilities capabilities,
172831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong            Listener listener, boolean mirror, Looper looper, FocusUI ui) {
1736190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren        mAppController = appController;
1746190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren        mSettingsManager = appController.getSettingsManager();
175375f9d11af33688eb0074e3828c870076cfa21b3Sascha Haeberling        mHandler = new MainHandler(this, looper);
1768872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mMatrix = new Matrix();
177ee36c5f591ac181a10692b2ec2b96de5251c4abbSascha Haeberling        mDefaultFocusModes = new ArrayList<CameraCapabilities.FocusMode>(defaultFocusModes);
178831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong        updateCapabilities(capabilities);
1798872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mListener = listener;
1808872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        setMirror(mirror);
181d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mUI = ui;
182fb33336bc6f4b70b0686b5e060819d6bd41f3b6fKevin Gabayan        mFocusLocked = false;
1838872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
1848872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
185831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong    public void updateCapabilities(CameraCapabilities capabilities) {
18609e134056bf85ee87855a44bfc5d8e7b055fe2e9Andy Huibers        // capabilities can only be null when onConfigurationChanged is called
1878872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // before camera is open. We will just return in this case, because
18809e134056bf85ee87855a44bfc5d8e7b055fe2e9Andy Huibers        // capabilities will be set again later with the right capabilities after
1898872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // camera is open.
19009e134056bf85ee87855a44bfc5d8e7b055fe2e9Andy Huibers        if (capabilities == null) {
191e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling            return;
192e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        }
19388289047ba6928e317d17f2e1d4b013693545c67Angus Kong        mCapabilities = capabilities;
19488289047ba6928e317d17f2e1d4b013693545c67Angus Kong        mFocusAreaSupported = mCapabilities.supports(CameraCapabilities.Feature.FOCUS_AREA);
19588289047ba6928e317d17f2e1d4b013693545c67Angus Kong        mMeteringAreaSupported = mCapabilities.supports(CameraCapabilities.Feature.METERING_AREA);
19688289047ba6928e317d17f2e1d4b013693545c67Angus Kong        mLockAeAwbNeeded = (mCapabilities.supports(CameraCapabilities.Feature.AUTO_EXPOSURE_LOCK)
19788289047ba6928e317d17f2e1d4b013693545c67Angus Kong                || mCapabilities.supports(CameraCapabilities.Feature.AUTO_WHITE_BALANCE_LOCK));
1988872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
1998872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
20036ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu    /** This setter should be the only way to mutate mPreviewRect. */
20136ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu    public void setPreviewRect(Rect previewRect) {
20236ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu        if (!mPreviewRect.equals(previewRect)) {
20336ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu            mPreviewRect.set(previewRect);
2048872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            setMatrix();
2058872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
2068872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
2078872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
208482de029dc20e0a577388a602985fb31c3200309Doris Liu    @Override
2092bacca795a1b0adb0daf515c43c48234b44bbba5Angus Kong    public void onPreviewAreaChanged(RectF previewArea) {
210a1ec04a9f9526418f5cb17a5afbfc48aca1e02d0Doris Liu        setPreviewRect(CameraUtil.rectFToRect(previewArea));
211482de029dc20e0a577388a602985fb31c3200309Doris Liu    }
212482de029dc20e0a577388a602985fb31c3200309Doris Liu
21336ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu    /** Returns a copy of mPreviewRect so that outside class cannot modify preview
21436ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu     *  rect except deliberately doing so through the setter. */
21536ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu    public Rect getPreviewRect() {
21636ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu        return new Rect(mPreviewRect);
21736ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu    }
21836ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu
2198872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void setMirror(boolean mirror) {
2208872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mMirror = mirror;
2218872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        setMatrix();
2228872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
2238872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
2248872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void setDisplayOrientation(int displayOrientation) {
2258872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mDisplayOrientation = displayOrientation;
2268872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        setMatrix();
2278872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
2288872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
2298872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private void setMatrix() {
23036ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu        if (mPreviewRect.width() != 0 && mPreviewRect.height() != 0) {
2318872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            Matrix matrix = new Matrix();
23236ebcb11b15fb00d3a641499c0f8a16745a2fbb0Doris Liu            CameraUtil.prepareMatrix(matrix, mMirror, mDisplayOrientation, getPreviewRect());
2338872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // In face detection, the matrix converts the driver coordinates to UI
2348872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // coordinates. In tap focus, the inverted matrix converts the UI
2358872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // coordinates to driver coordinates.
2368872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            matrix.invert(mMatrix);
237d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mInitialized = true;
2388872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
2398872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
2408872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
2418872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private void lockAeAwbIfNeeded() {
2428872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        if (mLockAeAwbNeeded && !mAeAwbLock) {
2438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mAeAwbLock = true;
2448872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mListener.setFocusParameters();
2458872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
2468872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
2478872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
2488872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private void unlockAeAwbIfNeeded() {
2498872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        if (mLockAeAwbNeeded && mAeAwbLock && (mState != STATE_FOCUSING_SNAP_ON_FINISH)) {
2508872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mAeAwbLock = false;
2518872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mListener.setFocusParameters();
2528872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
2538872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
2548872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
255831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong    public void onShutterUp(CameraCapabilities.FocusMode currentFocusMode) {
256e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        if (!mInitialized) {
257e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling            return;
258e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        }
2598872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
260831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong        if (needAutoFocusCall(currentFocusMode)) {
2618872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // User releases half-pressed focus key.
2628872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            if (mState == STATE_FOCUSING || mState == STATE_SUCCESS
2638872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                    || mState == STATE_FAIL) {
2648872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                cancelAutoFocus();
2658872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            }
2668872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
2678872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
2688872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // Unlock AE and AWB after cancelAutoFocus. Camera API does not
2698872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // guarantee setParameters can be called during autofocus.
2708872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        unlockAeAwbIfNeeded();
2718872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
2728872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
273831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong    public void focusAndCapture(CameraCapabilities.FocusMode currentFocusMode) {
274e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        if (!mInitialized) {
275e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling            return;
276e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        }
2778872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
278831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong        if (!needAutoFocusCall(currentFocusMode)) {
279eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong            // Focus is not needed.
280eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong            capture();
281eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong        } else if (mState == STATE_SUCCESS || mState == STATE_FAIL) {
282eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong            // Focus is done already.
2838872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            capture();
2848872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        } else if (mState == STATE_FOCUSING) {
285eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong            // Still focusing and will not trigger snap upon finish.
2868872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mState = STATE_FOCUSING_SNAP_ON_FINISH;
2878872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        } else if (mState == STATE_IDLE) {
288eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong            autoFocusAndCapture();
2898872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
2908872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
2918872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
2928872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void onAutoFocus(boolean focused, boolean shutterButtonPressed) {
2938872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        if (mState == STATE_FOCUSING_SNAP_ON_FINISH) {
2948872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // Take the picture no matter focus succeeds or fails. No need
2958872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // to play the AF sound if we're about to play the shutter
2968872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // sound.
2978872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            if (focused) {
2988872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                mState = STATE_SUCCESS;
2998872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            } else {
3008872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                mState = STATE_FAIL;
3018872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            }
3028872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            updateFocusUI();
3038872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            capture();
3048872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        } else if (mState == STATE_FOCUSING) {
3058872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // This happens when (1) user is half-pressing the focus key or
3068872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // (2) touch focus is triggered. Play the focus tone. Do not
3078872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // take the picture now.
3088872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            if (focused) {
3098872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                mState = STATE_SUCCESS;
3108872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            } else {
3118872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                mState = STATE_FAIL;
3128872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            }
3138872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            updateFocusUI();
3148872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // If this is triggered by touch focus, cancel focus after a
3158872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // while.
316b05794393444ebd13bd24c2ecfb3fbd9963f688eMichael Kolb            if (mFocusArea != null) {
317fb33336bc6f4b70b0686b5e060819d6bd41f3b6fKevin Gabayan                mFocusLocked = true;
318b868274c9dc8d9c772ec89fb5955215cc7911087Andy Huibers                mHandler.sendEmptyMessageDelayed(RESET_TOUCH_FOCUS, RESET_TOUCH_FOCUS_DELAY_MILLIS);
3198872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            }
3208872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            if (shutterButtonPressed) {
3218872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                // Lock AE & AWB so users can half-press shutter and recompose.
3228872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                lockAeAwbIfNeeded();
3238872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            }
3248872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        } else if (mState == STATE_IDLE) {
3258872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // User has released the focus key before focus completes.
3268872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // Do nothing.
3278872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
3288872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
3298872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
3308872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void onAutoFocusMoving(boolean moving) {
331e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        if (!mInitialized) {
332e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling            return;
333e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        }
334d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
335d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb
3368872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // Ignore if the camera has detected some faces.
337d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        if (mUI.hasFaces()) {
338d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mUI.clearFocus();
3398872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            return;
3408872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
3418872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
3428872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // Ignore if we have requested autofocus. This method only handles
3438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // continuous autofocus.
344e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        if (mState != STATE_IDLE) {
345e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling            return;
346e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        }
3478872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
348e3de7223ee3fe56e097d68f50c5a59ae61370d65Michael Kolb        // animate on false->true trasition only b/8219520
349e3de7223ee3fe56e097d68f50c5a59ae61370d65Michael Kolb        if (moving && !mPreviousMoving) {
350ca4a5668c5bcda027bd896ebf17c8ef374e2ac75Doris Liu            // Auto focus at the center of the preview.
351e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers            mUI.setFocusPosition(mPreviewRect.centerX(), mPreviewRect.centerY(), true,
352e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers                    getAFRegionEdge(), getAERegionEdge());
353d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mUI.onFocusStarted();
354e3de7223ee3fe56e097d68f50c5a59ae61370d65Michael Kolb        } else if (!moving) {
355e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling            mUI.onFocusSucceeded();
3568872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
357e3de7223ee3fe56e097d68f50c5a59ae61370d65Michael Kolb        mPreviousMoving = moving;
3588872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
3598872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
360e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers    /** Returns width of auto focus region in pixels. */
361e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers    private int getAFRegionEdge() {
362e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers        return (int) (Math.min(mPreviewRect.width(), mPreviewRect.height()) * AF_REGION_BOX);
363e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers    }
364e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers
365e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers    /** Returns width of metering region in pixels. */
366e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers    private int getAERegionEdge() {
367b868274c9dc8d9c772ec89fb5955215cc7911087Andy Huibers        return (int) (Math.min(mPreviewRect.width(), mPreviewRect.height()) * AE_REGION_BOX);
368e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers    }
369e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers
370638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberling    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
3710718d480a144ba0a44c07c48f90e85cf4ec669c6Michael Kolb    private void initializeFocusAreas(int x, int y) {
3728872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        if (mFocusArea == null) {
373a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling            mFocusArea = new ArrayList<Area>();
3748872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mFocusArea.add(new Area(new Rect(), 1));
3758872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
3768872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
3778872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // Convert the coordinates to driver format.
378e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers        calculateTapArea(x, y, getAFRegionEdge(), mFocusArea.get(0).rect);
3798872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
3808872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
381638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberling    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
3820718d480a144ba0a44c07c48f90e85cf4ec669c6Michael Kolb    private void initializeMeteringAreas(int x, int y) {
3838872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        if (mMeteringArea == null) {
384a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling            mMeteringArea = new ArrayList<Area>();
3858872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mMeteringArea.add(new Area(new Rect(), 1));
3868872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
3878872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
3888872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // Convert the coordinates to driver format.
389e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers        calculateTapArea(x, y, getAERegionEdge(), mMeteringArea.get(0).rect);
3908872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
3918872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
3928872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void onSingleTapUp(int x, int y) {
393e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        if (!mInitialized || mState == STATE_FOCUSING_SNAP_ON_FINISH) {
394e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling            return;
395e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        }
3968872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
3978872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // Let users be able to cancel previous touch focus.
398b05794393444ebd13bd24c2ecfb3fbd9963f688eMichael Kolb        if ((mFocusArea != null) && (mState == STATE_FOCUSING ||
3998872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                    mState == STATE_SUCCESS || mState == STATE_FAIL)) {
4008872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            cancelAutoFocus();
4018872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
402e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        if (mPreviewRect.width() == 0 || mPreviewRect.height() == 0) {
403e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling            return;
404e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        }
405b05794393444ebd13bd24c2ecfb3fbd9963f688eMichael Kolb        // Initialize variables.
4068872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // Initialize mFocusArea.
4078872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        if (mFocusAreaSupported) {
4080718d480a144ba0a44c07c48f90e85cf4ec669c6Michael Kolb            initializeFocusAreas(x, y);
4098872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
4108872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // Initialize mMeteringArea.
4118872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        if (mMeteringAreaSupported) {
4120718d480a144ba0a44c07c48f90e85cf4ec669c6Michael Kolb            initializeMeteringAreas(x, y);
4138872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
4148872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
4158872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // Use margin to set the focus indicator to the touched area.
416e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers        mUI.setFocusPosition(x, y, false, getAFRegionEdge(), getAERegionEdge());
417b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers        // Log manual tap to focus.
418b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers        mTouchCoordinate = new TouchCoordinate(x, y, mPreviewRect.width(), mPreviewRect.height());
419b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers        mTouchTime = System.currentTimeMillis();
4208872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
4218872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // Stop face detection because we want to specify focus and metering area.
4228872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mListener.stopFaceDetection();
4238872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
4248872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // Set the focus area and metering area.
4258872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mListener.setFocusParameters();
4268872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        if (mFocusAreaSupported) {
4278872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            autoFocus();
4288872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        } else {  // Just show the indicator in all other cases.
4298872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            updateFocusUI();
430d4a68ca4e34ad256cd4cd2f7b1faae234d240dfaKevin Gabayan            // Reset the metering area in 4 seconds.
4318872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mHandler.removeMessages(RESET_TOUCH_FOCUS);
432b868274c9dc8d9c772ec89fb5955215cc7911087Andy Huibers            mHandler.sendEmptyMessageDelayed(RESET_TOUCH_FOCUS, RESET_TOUCH_FOCUS_DELAY_MILLIS);
4338872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
4348872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
4358872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
4368872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void onPreviewStarted() {
4378872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mState = STATE_IDLE;
438bd9b80b267195f78a8514847d0f02629e761a334Andy Huibers        resetTouchFocus();
4398872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
4408872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
4418872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void onPreviewStopped() {
4428872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // If auto focus was in progress, it would have been stopped.
4438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mState = STATE_IDLE;
4448872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        updateFocusUI();
4458872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
4468872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
4478872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void onCameraReleased() {
4488872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        onPreviewStopped();
4498872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
4508872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
451fb33336bc6f4b70b0686b5e060819d6bd41f3b6fKevin Gabayan    @Override
452fb33336bc6f4b70b0686b5e060819d6bd41f3b6fKevin Gabayan    public void onMoving() {
453fb33336bc6f4b70b0686b5e060819d6bd41f3b6fKevin Gabayan        if (mFocusLocked) {
454fb33336bc6f4b70b0686b5e060819d6bd41f3b6fKevin Gabayan            Log.d(TAG, "onMoving: Early focus unlock.");
455fb33336bc6f4b70b0686b5e060819d6bd41f3b6fKevin Gabayan            cancelAutoFocus();
456fb33336bc6f4b70b0686b5e060819d6bd41f3b6fKevin Gabayan        }
457fb33336bc6f4b70b0686b5e060819d6bd41f3b6fKevin Gabayan    }
458fb33336bc6f4b70b0686b5e060819d6bd41f3b6fKevin Gabayan
459eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong    /**
460eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong     * Triggers the autofocus and sets the specified state.
461eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong     *
462eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong     * @param focusingState The state to use when focus is in progress.
463eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong     */
464eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong    private void autoFocus(int focusingState) {
4658872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mListener.autoFocus();
466eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong        mState = focusingState;
4678872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // Pause the face view because the driver will keep sending face
4688872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // callbacks after the focus completes.
469d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mUI.pauseFaceDetection();
4708872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        updateFocusUI();
4718872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mHandler.removeMessages(RESET_TOUCH_FOCUS);
4728872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
4738872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
474eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong    /**
475eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong     * Triggers the autofocus and set the state to indicate the focus is in
476eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong     * progress.
477eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong     */
478eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong    private void autoFocus() {
479eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong        autoFocus(STATE_FOCUSING);
480eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong    }
481eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong
482eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong    /**
483eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong     * Triggers the autofocus and set the state to which a capture will happen
484eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong     * in the following autofocus callback.
485eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong     */
486eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong    private void autoFocusAndCapture() {
487eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong        autoFocus(STATE_FOCUSING_SNAP_ON_FINISH);
488eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong    }
489eaaf56d5ad909bf8d3eb23a2454983e7731e7644Angus Kong
4908872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private void cancelAutoFocus() {
491516c11a6885f6e524927bd369567f5bbd592f8efKevin Gabayan        Log.v(TAG, "Cancel autofocus.");
4928872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // Reset the tap area before calling mListener.cancelAutofocus.
4938872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // Otherwise, focus mode stays at auto and the tap area passed to the
4948872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // driver is not reset.
4958872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        resetTouchFocus();
4968872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mListener.cancelAutoFocus();
497d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mUI.resumeFaceDetection();
4988872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mState = STATE_IDLE;
499fb33336bc6f4b70b0686b5e060819d6bd41f3b6fKevin Gabayan        mFocusLocked = false;
5008872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        updateFocusUI();
5018872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mHandler.removeMessages(RESET_TOUCH_FOCUS);
5028872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
5038872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
5048872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private void capture() {
5058872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        if (mListener.capture()) {
5068872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mState = STATE_IDLE;
5078872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mHandler.removeMessages(RESET_TOUCH_FOCUS);
5088872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
5098872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
5108872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
511831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong    public CameraCapabilities.FocusMode getFocusMode(
512831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong            final CameraCapabilities.FocusMode currentFocusMode) {
513831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong        if (mOverrideFocusMode != null) {
514ec4a3fc5e87bf545fb718189b37538f1f1da68dfAlan Newberger            Log.v(TAG, "returning override focus: " + mOverrideFocusMode);
515831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong            return mOverrideFocusMode;
516831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong        }
517831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong        if (mCapabilities == null) {
518ec4a3fc5e87bf545fb718189b37538f1f1da68dfAlan Newberger            Log.v(TAG, "no capabilities, returning default AUTO focus mode");
519831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong            return CameraCapabilities.FocusMode.AUTO;
520831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong        }
5218872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
522b05794393444ebd13bd24c2ecfb3fbd9963f688eMichael Kolb        if (mFocusAreaSupported && mFocusArea != null) {
523ec4a3fc5e87bf545fb718189b37538f1f1da68dfAlan Newberger            Log.v(TAG, "in tap to focus, returning AUTO focus mode");
5248872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // Always use autofocus in tap-to-focus.
525831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong            mFocusMode = CameraCapabilities.FocusMode.AUTO;
5268872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        } else {
527ec4a3fc5e87bf545fb718189b37538f1f1da68dfAlan Newberger            String focusSetting = mSettingsManager.getString(mAppController.getCameraScope(),
528ec4a3fc5e87bf545fb718189b37538f1f1da68dfAlan Newberger                    Keys.KEY_FOCUS_MODE);
529ec4a3fc5e87bf545fb718189b37538f1f1da68dfAlan Newberger            Log.v(TAG, "stored focus setting for camera: " + focusSetting);
5308872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // The default is continuous autofocus.
531ec4a3fc5e87bf545fb718189b37538f1f1da68dfAlan Newberger            mFocusMode = mCapabilities.getStringifier().focusModeFromString(focusSetting);
532ec4a3fc5e87bf545fb718189b37538f1f1da68dfAlan Newberger            Log.v(TAG, "focus mode resolved from setting: " + mFocusMode);
5338872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // Try to find a supported focus mode from the default list.
5348872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            if (mFocusMode == null) {
535831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong                for (CameraCapabilities.FocusMode mode : mDefaultFocusModes) {
536831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong                    if (mCapabilities.supports(mode)) {
5378872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                        mFocusMode = mode;
538ec4a3fc5e87bf545fb718189b37538f1f1da68dfAlan Newberger                        Log.v(TAG, "selected supported focus mode from default list" + mode);
5398872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                        break;
5408872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                    }
5418872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                }
5428872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            }
5438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
544831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong        if (!mCapabilities.supports(mFocusMode)) {
5458872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // For some reasons, the driver does not support the current
5468872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // focus mode. Fall back to auto.
547831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong            if (mCapabilities.supports(CameraCapabilities.FocusMode.AUTO)) {
548ec4a3fc5e87bf545fb718189b37538f1f1da68dfAlan Newberger                Log.v(TAG, "no supported focus mode, falling back to AUTO");
549831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong                mFocusMode = CameraCapabilities.FocusMode.AUTO;
5508872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            } else {
551ec4a3fc5e87bf545fb718189b37538f1f1da68dfAlan Newberger                Log.v(TAG, "no supported focus mode, falling back to current: " + currentFocusMode);
552831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong                mFocusMode = currentFocusMode;
5538872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            }
5548872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
5558872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return mFocusMode;
5568872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
5578872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
558a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling    public List<Area> getFocusAreas() {
5598872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return mFocusArea;
5608872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
5618872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
562a63dbb6231f06031204fe20b19a87d0440bd1661Sascha Haeberling    public List<Area> getMeteringAreas() {
5638872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return mMeteringArea;
5648872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
5658872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
5668872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void updateFocusUI() {
567e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        if (!mInitialized) {
568e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling            // Show only focus indicator or face indicator.
569e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling            return;
570e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        }
5718872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        if (mState == STATE_IDLE) {
572b05794393444ebd13bd24c2ecfb3fbd9963f688eMichael Kolb            if (mFocusArea == null) {
573d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb                mUI.clearFocus();
5748872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            } else {
5758872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                // Users touch on the preview and the indicator represents the
5768872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                // metering area. Either focus area is not supported or
5778872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                // autoFocus call is not required.
578d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb                mUI.onFocusStarted();
5798872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            }
580076efc0354552ee3b0845ae3b5988e755f92d5b0Andy Huibers        } else if (mState == STATE_FOCUSING) {
581d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb            mUI.onFocusStarted();
5828872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        } else {
583831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong            if (mFocusMode == CameraCapabilities.FocusMode.CONTINUOUS_PICTURE) {
5848872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                // TODO: check HAL behavior and decide if this can be removed.
585e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling                mUI.onFocusSucceeded();
5868872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            } else if (mState == STATE_SUCCESS) {
587e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling                mUI.onFocusSucceeded();
5888872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            } else if (mState == STATE_FAIL) {
589e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling                mUI.onFocusFailed();
5908872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            }
5918872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
5928872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
5938872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
5948872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void resetTouchFocus() {
595e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        if (!mInitialized) {
596e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling            return;
597e3f9ce2932f65ad537c550d0ff1f0c5fa4856ee7Sascha Haeberling        }
5988872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
5998872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        // Put focus indicator to the center. clear reset position
600d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb        mUI.clearFocus();
6010718d480a144ba0a44c07c48f90e85cf4ec669c6Michael Kolb        // Initialize mFocusArea.
602b05794393444ebd13bd24c2ecfb3fbd9963f688eMichael Kolb        mFocusArea = null;
603b05794393444ebd13bd24c2ecfb3fbd9963f688eMichael Kolb        mMeteringArea = null;
604bd9b80b267195f78a8514847d0f02629e761a334Andy Huibers        // This will cause current module to call getFocusAreas() and
605bd9b80b267195f78a8514847d0f02629e761a334Andy Huibers        // getMeteringAreas() and send updated regions to camera.
606bd9b80b267195f78a8514847d0f02629e761a334Andy Huibers        mListener.setFocusParameters();
607b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers
608b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers        if (mTouchCoordinate != null) {
609b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers            UsageStatistics.instance().tapToFocus(mTouchCoordinate,
610b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers                    0.001f * (System.currentTimeMillis() - mTouchTime));
611b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers            mTouchCoordinate = null;
612b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers        }
6138872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6148872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
615e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers    private void calculateTapArea(int x, int y, int size, Rect rect) {
616e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers        int left = CameraUtil.clamp(x - size / 2, mPreviewRect.left,
617e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers                mPreviewRect.right - size);
618e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers        int top = CameraUtil.clamp(y - size / 2, mPreviewRect.top,
619e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers                mPreviewRect.bottom - size);
6208872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
621e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers        RectF rectF = new RectF(left, top, left + size, top + size);
6228872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mMatrix.mapRect(rectF);
623b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong        CameraUtil.rectFToRect(rectF, rect);
6248872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6258872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
6268872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    /* package */ int getFocusState() {
6278872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return mState;
6288872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6298872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
6308872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public boolean isFocusCompleted() {
6318872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return mState == STATE_SUCCESS || mState == STATE_FAIL;
6328872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6338872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
6348872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public boolean isFocusingSnapOnFinish() {
6358872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return mState == STATE_FOCUSING_SNAP_ON_FINISH;
6368872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6378872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
6388872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void removeMessages() {
6398872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mHandler.removeMessages(RESET_TOUCH_FOCUS);
6408872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6418872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
642831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong    public void overrideFocusMode(CameraCapabilities.FocusMode focusMode) {
6438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mOverrideFocusMode = focusMode;
6448872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6458872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
6468872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void setAeAwbLock(boolean lock) {
6478872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mAeAwbLock = lock;
6488872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6498872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
6508872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public boolean getAeAwbLock() {
6518872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return mAeAwbLock;
6528872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6538872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
654831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong    private boolean needAutoFocusCall(CameraCapabilities.FocusMode focusMode) {
655831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong        return !(focusMode == CameraCapabilities.FocusMode.INFINITY
656831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong                || focusMode == CameraCapabilities.FocusMode.FIXED
657831347d9cb5c0e3f03db7aadfc89e91b231104e7Angus Kong                || focusMode == CameraCapabilities.FocusMode.EXTENDED_DOF);
6588872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6598872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb}
660