1fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin/*
2fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin * Copyright 2013 The Android Open Source Project
3fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin *
4fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin * Licensed under the Apache License, Version 2.0 (the "License");
5fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin * you may not use this file except in compliance with the License.
6fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin * You may obtain a copy of the License at
7fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin *
8fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin *      http://www.apache.org/licenses/LICENSE-2.0
9fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin *
10fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin * Unless required by applicable law or agreed to in writing, software
11fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin * distributed under the License is distributed on an "AS IS" BASIS,
12fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin * See the License for the specific language governing permissions and
14fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin * limitations under the License.
15fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin */
16fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkinpackage com.android.ex.camera2.pos;
17fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
18fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkinimport android.hardware.camera2.CameraDevice;
1900a9b46b5a85c2e7ff03d94e517f732d397eb020Igor Murashkinimport android.hardware.camera2.CaptureResult.Key;
20fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkinimport android.hardware.camera2.CaptureRequest;
21fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkinimport android.hardware.camera2.CaptureResult;
22fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkinimport android.util.Log;
23fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
242d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkinimport com.android.ex.camera2.utils.SysTrace;
252d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin
26fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin/**
27fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin * Manage the auto focus state machine for CameraDevice.
28fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin *
29fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin * <p>Requests are created only when the AF needs to be manipulated from the user,
30fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin * but automatic camera-caused AF state changes are broadcasted from any new result.</p>
31fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin */
32fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkinpublic class AutoFocusStateMachine {
33fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
34e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin    /**
35e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin     * Observe state AF state transitions triggered by
36e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin     * {@link AutoFocusStateMachine#onCaptureCompleted onCaptureCompleted}.
37e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin     */
38fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin    public interface AutoFocusStateListener {
39fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        /**
40fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin         * The camera is currently focused (either active or passive).
41fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin         *
42fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin         * @param locked True if the lens has been locked from moving, false otherwise.
43fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin         */
44fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        void onAutoFocusSuccess(CaptureResult result, boolean locked);
45fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
46fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        /**
47fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin         * The camera is currently not focused (either active or passive).
48fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin         *
49fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin         * @param locked False if the AF is still scanning, true if needs a restart.
50fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin         */
51fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        void onAutoFocusFail(CaptureResult result, boolean locked);
52fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
53fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        /**
54fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin         * The camera is currently scanning (either active or passive)
55fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin         * and has not yet converged.
56fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin         *
57fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin         * <p>This is not called for results where the AF either succeeds or fails.</p>
58fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin         */
59fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        void onAutoFocusScan(CaptureResult result);
60fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
61fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        /**
62fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin         * The camera is currently not doing anything with the autofocus.
63fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin         *
64fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin         * <p>Autofocus could be off, or this could be an intermediate state transition as
65fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin         * scanning restarts.</p>
66fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin         */
67fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        void onAutoFocusInactive(CaptureResult result);
68fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin    }
69fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
70fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin    private static final String TAG = "AutoFocusStateMachine";
71fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin    private static final boolean DEBUG_LOGGING = Log.isLoggable(TAG, Log.DEBUG);
72fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin    private static final boolean VERBOSE_LOGGING = Log.isLoggable(TAG, Log.VERBOSE);
73fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin    private static final int AF_UNINITIALIZED = -1;
74fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
75fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin    private final AutoFocusStateListener mListener;
76fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin    private int mLastAfState = AF_UNINITIALIZED;
77fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin    private int mLastAfMode = AF_UNINITIALIZED;
78fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin    private int mCurrentAfMode = AF_UNINITIALIZED;
79fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin    private int mCurrentAfTrigger = AF_UNINITIALIZED;
80fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
812d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin    private int mCurrentAfCookie = AF_UNINITIALIZED;
822d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin    private String mCurrentAfTrace = "";
832d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin    private int mLastAfCookie = 0;
842d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin
85fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin    public AutoFocusStateMachine(AutoFocusStateListener listener) {
86fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        if (listener == null) {
87fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin            throw new IllegalArgumentException("listener should not be null");
88fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        }
89fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        mListener = listener;
90fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin    }
91fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
92fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin    /**
93fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * Invoke every time we get a new CaptureResult via
94bb013aa3e197e881756be5ad13e6ad30bfb4aeffEino-Ville Talvala     * {@link CameraDevice.CaptureCallback#onCaptureCompleted}.
95fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     *
96fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * <p>This function is responsible for dispatching updates via the
97fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * {@link AutoFocusStateListener} so without calling this on a regular basis, no
98fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * AF changes will be observed.</p>
99fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     *
100fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * @param result CaptureResult
101fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     */
102fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin    public synchronized void onCaptureCompleted(CaptureResult result) {
103fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
104806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin        /**
105806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin         * Work-around for b/11269834
106806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin         * Although these should never-ever happen, harden for ship
107806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin         */
108806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin        if (result == null) {
109806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin            Log.w(TAG, "onCaptureCompleted - missing result, skipping AF update");
110806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin            return;
111806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin        }
112806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin
113806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin        Key<Integer> keyAfState = CaptureResult.CONTROL_AF_STATE;
114806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin        if (keyAfState == null) {
115806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin            Log.e(TAG, "onCaptureCompleted - missing android.control.afState key, " +
116806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin                    "skipping AF update");
117806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin            return;
118806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin        }
119806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin
120806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin        Key<Integer> keyAfMode = CaptureResult.CONTROL_AF_MODE;
121806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin        if (keyAfMode == null) {
122806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin            Log.e(TAG, "onCaptureCompleted - missing android.control.afMode key, " +
123806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin                    "skipping AF update");
124806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin            return;
125806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin        }
126806d114d5975c89843c9ba16eadfcaf143afdebbIgor Murashkin
127ba7f02549047afd96f033eda9729592a7668e039Igor Murashkin        Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
128ba7f02549047afd96f033eda9729592a7668e039Igor Murashkin        Integer afMode = result.get(CaptureResult.CONTROL_AF_MODE);
129ba7f02549047afd96f033eda9729592a7668e039Igor Murashkin
130ba7f02549047afd96f033eda9729592a7668e039Igor Murashkin        /**
131ba7f02549047afd96f033eda9729592a7668e039Igor Murashkin         * Work-around for b/11238865
132ba7f02549047afd96f033eda9729592a7668e039Igor Murashkin         * This is a HAL bug as these fields should be there always.
133ba7f02549047afd96f033eda9729592a7668e039Igor Murashkin         */
134ba7f02549047afd96f033eda9729592a7668e039Igor Murashkin        if (afState == null) {
135ba7f02549047afd96f033eda9729592a7668e039Igor Murashkin            Log.w(TAG, "onCaptureCompleted - missing android.control.afState !");
136ba7f02549047afd96f033eda9729592a7668e039Igor Murashkin            return;
137ba7f02549047afd96f033eda9729592a7668e039Igor Murashkin        } else if (afMode == null) {
138ba7f02549047afd96f033eda9729592a7668e039Igor Murashkin            Log.w(TAG, "onCaptureCompleted - missing android.control.afMode !");
139ba7f02549047afd96f033eda9729592a7668e039Igor Murashkin            return;
140ba7f02549047afd96f033eda9729592a7668e039Igor Murashkin        }
141fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
142a47d6986cb4aa66e277c61df79a3947bbecd5de8Igor Murashkin        if (DEBUG_LOGGING) Log.d(TAG, "onCaptureCompleted - new AF mode = " + afMode +
143a47d6986cb4aa66e277c61df79a3947bbecd5de8Igor Murashkin                " new AF state = " + afState);
144fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
145a47d6986cb4aa66e277c61df79a3947bbecd5de8Igor Murashkin        if (mLastAfState == afState && afMode == mLastAfMode) {
146fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin            // Same AF state as last time, nothing else needs to be done.
147fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin            return;
148fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        }
149fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
150a47d6986cb4aa66e277c61df79a3947bbecd5de8Igor Murashkin        if (VERBOSE_LOGGING) Log.v(TAG, "onCaptureCompleted - new AF mode = " + afMode +
151a47d6986cb4aa66e277c61df79a3947bbecd5de8Igor Murashkin                " new AF state = " + afState);
152fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
153fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        mLastAfState = afState;
154a47d6986cb4aa66e277c61df79a3947bbecd5de8Igor Murashkin        mLastAfMode = afMode;
155fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
156fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        switch (afState) {
157fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin            case CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED:
158fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin                mListener.onAutoFocusSuccess(result, /*locked*/true);
1592d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin                endTraceAsync();
160fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin                break;
161fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin            case CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
162fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin                mListener.onAutoFocusFail(result, /*locked*/true);
1632d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin                endTraceAsync();
164fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin                break;
165fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin            case CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED:
166134cd3193ddc17e97cb6364594d85e5b203c7cc6Igor Murashkin                mListener.onAutoFocusSuccess(result, /*locked*/false);
167134cd3193ddc17e97cb6364594d85e5b203c7cc6Igor Murashkin                break;
168134cd3193ddc17e97cb6364594d85e5b203c7cc6Igor Murashkin            case CaptureResult.CONTROL_AF_STATE_PASSIVE_UNFOCUSED:
169134cd3193ddc17e97cb6364594d85e5b203c7cc6Igor Murashkin                mListener.onAutoFocusFail(result, /*locked*/false);
170fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin                break;
171fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin            case CaptureResult.CONTROL_AF_STATE_ACTIVE_SCAN:
172fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin                mListener.onAutoFocusScan(result);
173fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin                break;
174fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin            case CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN:
175fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin                mListener.onAutoFocusScan(result);
176fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin                break;
177fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin            case CaptureResult.CONTROL_AF_STATE_INACTIVE:
178fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin                mListener.onAutoFocusInactive(result);
179fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin                break;
180fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        }
181fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin    }
182fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
183fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin    /**
184e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin     * Reset the current AF state.
185e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin     *
186e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin     * <p>
187e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin     * When dropping capture results (by not invoking {@link #onCaptureCompleted} when a new
188e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin     * {@link CaptureResult} is available), call this function to reset the state. Otherwise
189e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin     * the next time a new state is observed this class may incorrectly consider it as the same
190e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin     * state as before, and not issue any callbacks by {@link AutoFocusStateListener}.
191e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin     * </p>
192e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin     */
193e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin    public synchronized void resetState() {
194e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin        if (VERBOSE_LOGGING) Log.v(TAG, "resetState - last state was " + mLastAfState);
195e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin
196e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin        mLastAfState = AF_UNINITIALIZED;
197e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin    }
198e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin
199e2fa3d7185929f5e51a851d23db2618a41f18d9dIgor Murashkin    /**
200fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * Lock the lens from moving. Typically used before taking a picture.
201fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     *
202fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * <p>After calling this function, submit the new requestBuilder as a separate capture.
203fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * Do not submit it as a repeating request or the AF lock will be repeated every time.</p>
204fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     *
205fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * <p>Create a new repeating request from repeatingBuilder and set that as the updated
206fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * repeating request.</p>
207fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     *
208fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * <p>If the lock succeeds, {@link AutoFocusStateListener#onAutoFocusSuccess} with
209fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * {@code locked == true} will be invoked. If the lock fails,
210fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * {@link AutoFocusStateListener#onAutoFocusFail} with {@code scanning == false} will be
211fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * invoked.</p>
212fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     *
213fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * @param repeatingBuilder Builder for a repeating request.
214fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * @param requestBuilder Builder for a non-repeating request.
215fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     *
216fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     */
217fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin    public synchronized void lockAutoFocus(CaptureRequest.Builder repeatingBuilder,
218fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin            CaptureRequest.Builder requestBuilder) {
219fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
220fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        if (VERBOSE_LOGGING) Log.v(TAG, "lockAutoFocus");
221fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
222fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        if (mCurrentAfMode == AF_UNINITIALIZED) {
223fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin            throw new IllegalStateException("AF mode was not enabled");
224fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        }
225fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
2262d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin        beginTraceAsync("AFSM_lockAutoFocus");
2272d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin
228fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        mCurrentAfTrigger = CaptureRequest.CONTROL_AF_TRIGGER_START;
229fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
230fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        repeatingBuilder.set(CaptureRequest.CONTROL_AF_MODE, mCurrentAfMode);
231fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        requestBuilder.set(CaptureRequest.CONTROL_AF_MODE, mCurrentAfMode);
232fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
233fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        repeatingBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
234fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin                CaptureRequest.CONTROL_AF_TRIGGER_IDLE);
235fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        requestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
236fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin                CaptureRequest.CONTROL_AF_TRIGGER_START);
237fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin    }
238fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
239fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin    /**
240fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * Unlock the lens, allowing it to move again. Typically used after taking a picture.
241fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     *
242fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * <p>After calling this function, submit the new requestBuilder as a separate capture.
243fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * Do not submit it as a repeating request or the AF lock will be repeated every time.</p>
244fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     *
245fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * <p>Create a new repeating request from repeatingBuilder and set that as the updated
246fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * repeating request.</p>
247fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     *
248fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * <p>Once the unlock takes effect, {@link AutoFocusStateListener#onAutoFocusInactive} is
249fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * invoked, and after that the effects depend on which mode you were in:
250fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * <ul>
251fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * <li>Passive - Scanning restarts with {@link AutoFocusStateListener#onAutoFocusScan}</li>
252fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * <li>Active - The lens goes back to a default position (no callbacks)</li>
253fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * </ul>
254fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * </p>
255fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     *
256fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * @param repeatingBuilder Builder for a repeating request.
257fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * @param requestBuilder Builder for a non-repeating request.
258fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     *
259fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     */
260fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin    public synchronized void unlockAutoFocus(CaptureRequest.Builder repeatingBuilder,
261fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin            CaptureRequest.Builder requestBuilder) {
262fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
263fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        if (VERBOSE_LOGGING) Log.v(TAG, "unlockAutoFocus");
264fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
265fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        if (mCurrentAfMode == AF_UNINITIALIZED) {
266fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin            throw new IllegalStateException("AF mode was not enabled");
267fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        }
268fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
269fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        mCurrentAfTrigger = CaptureRequest.CONTROL_AF_TRIGGER_CANCEL;
270fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
271fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        repeatingBuilder.set(CaptureRequest.CONTROL_AF_MODE, mCurrentAfMode);
272fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        requestBuilder.set(CaptureRequest.CONTROL_AF_MODE, mCurrentAfMode);
273fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
274fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        repeatingBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
275fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin                CaptureRequest.CONTROL_AF_TRIGGER_IDLE);
276fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        requestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
277fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin                CaptureRequest.CONTROL_AF_TRIGGER_CANCEL);
278fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin    }
279fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
280fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin    /**
281fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * Enable active auto focus, immediately triggering a converging scan.
282fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     *
283fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * <p>This is typically only used when locking the passive AF has failed.</p>
284fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     *
285fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * <p>Once active AF scanning starts, {@link AutoFocusStateListener#onAutoFocusScan} will be
286fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * invoked.</p>
287fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     *
288fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * <p>If the active scan succeeds, {@link AutoFocusStateListener#onAutoFocusSuccess} with
289fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * {@code locked == true} will be invoked. If the active scan fails,
290fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * {@link AutoFocusStateListener#onAutoFocusFail} with {@code scanning == false} will be
291fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * invoked.</p>
292fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     *
293fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * <p>After calling this function, submit the new requestBuilder as a separate capture.
294fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * Do not submit it as a repeating request or the AF trigger will be repeated every time.</p>
295fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     *
296fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * <p>Create a new repeating request from repeatingBuilder and set that as the updated
297fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * repeating request.</p>
298fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     *
299fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * @param repeatingBuilder Builder for a repeating request.
300fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * @param requestBuilder Builder for a non-repeating request.
301fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     *
302fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * @param repeatingBuilder Builder for a repeating request.
303fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     */
304fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin    public synchronized void setActiveAutoFocus(CaptureRequest.Builder repeatingBuilder,
305fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin            CaptureRequest.Builder requestBuilder) {
306fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        if (VERBOSE_LOGGING) Log.v(TAG, "setActiveAutoFocus");
307fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
3082d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin        beginTraceAsync("AFSM_setActiveAutoFocus");
3092d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin
310fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        mCurrentAfMode = CaptureRequest.CONTROL_AF_MODE_AUTO;
311fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
312fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        repeatingBuilder.set(CaptureRequest.CONTROL_AF_MODE, mCurrentAfMode);
313fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        requestBuilder.set(CaptureRequest.CONTROL_AF_MODE, mCurrentAfMode);
314fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
315fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        repeatingBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
316fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin                CaptureRequest.CONTROL_AF_TRIGGER_IDLE);
317fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        requestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
318fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin                CaptureRequest.CONTROL_AF_TRIGGER_START);
319fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin    }
320fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
321fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin    /**
322fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * Enable passive autofocus, immediately triggering a non-converging scan.
323fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     *
324fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * <p>While passive autofocus is enabled, use {@link #lockAutoFocus} to lock
325fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * the lens before taking a picture. Once a picture is taken, use {@link #unlockAutoFocus}
326fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * to let the lens go back into passive scanning.</p>
327fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     *
328fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * <p>Once passive AF scanning starts, {@link AutoFocusStateListener#onAutoFocusScan} will be
329fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * invoked.</p>
330fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     *
331fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * @param repeatingBuilder Builder for a repeating request.
332fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     * @param picture True for still capture AF, false for video AF.
333fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin     */
334fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin    public synchronized void setPassiveAutoFocus(boolean picture,
335fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin            CaptureRequest.Builder repeatingBuilder) {
336fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        if (VERBOSE_LOGGING) Log.v(TAG, "setPassiveAutoFocus - picture " + picture);
337fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
338fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        if (picture) {
339fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin            mCurrentAfMode = CaptureResult.CONTROL_AF_MODE_CONTINUOUS_PICTURE;
340fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        } else {
341fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin            mCurrentAfMode = CaptureResult.CONTROL_AF_MODE_CONTINUOUS_VIDEO;
342fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        }
343fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin
344fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin        repeatingBuilder.set(CaptureRequest.CONTROL_AF_MODE, mCurrentAfMode);
345fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin    }
3462d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin
3472d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin    private synchronized void beginTraceAsync(String sectionName) {
3482d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin        if (mCurrentAfCookie != AF_UNINITIALIZED) {
3492d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin            // Terminate any currently active async sections before beginning another section
3502d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin            SysTrace.endSectionAsync(mCurrentAfTrace, mCurrentAfCookie);
3512d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin        }
3522d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin
3532d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin        mLastAfCookie++;
3542d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin        mCurrentAfCookie = mLastAfCookie;
3552d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin        mCurrentAfTrace = sectionName;
3562d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin
3572d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin        SysTrace.beginSectionAsync(sectionName, mCurrentAfCookie);
3582d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin    }
3592d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin
3602d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin    private synchronized void endTraceAsync() {
3612d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin        if (mCurrentAfCookie == AF_UNINITIALIZED) {
3622d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin            Log.w(TAG, "endTraceAsync - no current trace active");
3632d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin            return;
3642d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin        }
3652d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin
3662d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin        SysTrace.endSectionAsync(mCurrentAfTrace, mCurrentAfCookie);
3672d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin        mCurrentAfCookie = AF_UNINITIALIZED;
3682d8e55f45e52ac0b18c0e46de602e6a6d5ab1001Igor Murashkin    }
369d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He
370d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He    /**
371d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He     * Update the repeating request with current focus mode.
372d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He     *
373d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He     * <p>This is typically used when a new repeating request is created to update preview with
374d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He     * new metadata (i.e. crop region). The current auto focus mode needs to be carried over for
375d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He     * correct auto focus behavior.<p>
376d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He     *
377d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He     * @param repeatingBuilder Builder for a repeating request.
378d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He     */
379d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He    public synchronized void updateCaptureRequest(CaptureRequest.Builder repeatingBuilder) {
380d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He        if (repeatingBuilder == null) {
381d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He            throw new IllegalArgumentException("repeatingBuilder shouldn't be null");
382d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He        }
383d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He
384d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He        if (mCurrentAfMode == AF_UNINITIALIZED) {
385d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He            throw new IllegalStateException("AF mode was not enabled");
386d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He        }
387d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He
388d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He        repeatingBuilder.set(CaptureRequest.CONTROL_AF_MODE, mCurrentAfMode);
389d4429271623c05376ee1445d13fde9bcf76a0033Zhijun He    }
390fc121178a18d0860d020e9cb2253c5b00dbf19c3Igor Murashkin}
391