16d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim/*
26d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Copyright (C) 2016 The Android Open Source Project
36d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim *
46d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Licensed under the Apache License, Version 2.0 (the "License");
56d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * you may not use this file except in compliance with the License.
66d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * You may obtain a copy of the License at
76d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim *
86d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim *      http://www.apache.org/licenses/LICENSE-2.0
96d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim *
106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Unless required by applicable law or agreed to in writing, software
116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * distributed under the License is distributed on an "AS IS" BASIS,
126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * See the License for the specific language governing permissions and
146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * limitations under the License.
156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */
166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimpackage com.android.mediaframeworktest.helpers;
186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport com.android.ex.camera2.pos.AutoFocusStateMachine;
206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport com.android.ex.camera2.pos.AutoFocusStateMachine.AutoFocusStateListener;
216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.CameraAccessException;
236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.CameraCaptureSession;
246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.CameraCaptureSession.CaptureCallback;
256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.CameraCharacteristics;
266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.CameraDevice;
276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.CaptureRequest;
286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.CaptureResult;
296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.TotalCaptureResult;
306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.params.MeteringRectangle;
316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.os.Handler;
326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.util.Log;
336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.view.Surface;
346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim/**
366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * A focuser utility class to assist camera to do auto focus.
376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>
386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * This class need create repeating request and single request to do auto focus.
396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * The repeating request is used to get the auto focus states; the single
406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * request is used to trigger the auto focus. This class assumes the camera device
416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * supports auto-focus. Don't use this class if the camera device doesn't have focuser
426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * unit.
436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * </p>
446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */
456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim/**
466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * (non-Javadoc)
476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @see android.hardware.camera2.cts.helpers.Camera2Focuser
486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */
496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimpublic class Camera2Focuser implements AutoFocusStateListener {
506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final String TAG = "Focuser";
516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private final AutoFocusStateMachine mAutoFocus = new AutoFocusStateMachine(this);
546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private final Handler mHandler;
556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private final AutoFocusListener mAutoFocusListener;
566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private final CameraDevice mCamera;
576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private final CameraCaptureSession mSession;
586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private final Surface mRequestSurface;
596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private final StaticMetadata mStaticInfo;
606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private int mAfRun = 0;
626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private MeteringRectangle[] mAfRegions;
636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private boolean mLocked = false;
646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private boolean mSuccess = false;
656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private CaptureRequest.Builder mRepeatingBuilder;
666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * The callback interface to notify auto focus result.
696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public interface AutoFocusListener {
716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        /**
726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim         * This callback is called when auto focus completes and locked.
736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim         *
746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim         * @param success true if focus was successful, false if otherwise
756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim         */
766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        void onAutoFocusLocked(boolean success);
776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Construct a focuser object, with given capture requestSurface, listener
816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * and handler.
826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * <p>
836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * The focuser object will use camera and requestSurface to submit capture
846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * request and receive focus state changes. The {@link AutoFocusListener} is
856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * used to notify the auto focus callback.
866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * </p>
876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param camera The camera device associated with this focuser
896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param session The camera capture session associated with this focuser
906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param requestSurface The surface to issue the capture request with
916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param listener The auto focus listener to notify AF result
926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param staticInfo The CameraCharacteristics of the camera device
936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param handler The handler used to post auto focus callbacks
946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @throws CameraAccessException
956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public Camera2Focuser(CameraDevice camera, CameraCaptureSession session, Surface requestSurface,
976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            AutoFocusListener listener, CameraCharacteristics staticInfo, Handler handler)
986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throws CameraAccessException {
996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (camera == null) {
1006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throw new IllegalArgumentException("camera must not be null");
1016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
1026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (session == null) {
1036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throw new IllegalArgumentException("session must not be null");
1046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
1056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (listener == null) {
1066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throw new IllegalArgumentException("listener must not be null");
1076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
1086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (handler == null) {
1096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throw new IllegalArgumentException("handler must not be null");
1106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
1116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (requestSurface == null) {
1126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throw new IllegalArgumentException("requestSurface must not be null");
1136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
1146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (staticInfo == null) {
1156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throw new IllegalArgumentException("staticInfo must not be null");
1166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
1176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mCamera = camera;
1196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mSession = session;
1206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mRequestSurface = requestSurface;
1216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mAutoFocusListener = listener;
1226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mStaticInfo = new StaticMetadata(staticInfo,
1236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                StaticMetadata.CheckLevel.ASSERT, /*collector*/null);
1246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mHandler = handler;
1256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (!mStaticInfo.hasFocuser()) {
1276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throw new IllegalArgumentException("this camera doesn't have a focuser");
1286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
1296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        /**
1316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim         * Begin by always being in passive auto focus.
1326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim         */
1336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        cancelAutoFocus();
1346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
1356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    @Override
1376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public synchronized void onAutoFocusSuccess(CaptureResult result, boolean locked) {
1386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mSuccess = true;
1396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mLocked = locked;
1406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (locked) {
1426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            dispatchAutoFocusStatusLocked(/*success*/true);
1436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
1446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
1456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    @Override
1476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public synchronized void onAutoFocusFail(CaptureResult result, boolean locked) {
1486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mSuccess = false;
1496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mLocked = locked;
1506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (locked) {
1526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            dispatchAutoFocusStatusLocked(/*success*/false);
1536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
1546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
1556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    @Override
1576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public synchronized void onAutoFocusScan(CaptureResult result) {
1586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mSuccess = false;
1596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mLocked = false;
1606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
1616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    @Override
1636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public synchronized void onAutoFocusInactive(CaptureResult result) {
1646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mSuccess = false;
1656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mLocked = false;
1666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
1676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
1696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Start a active auto focus scan based on the given regions.
1706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
1716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * <p>This is usually used for touch for focus, it can make the auto-focus converge based
1726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * on some particular region aggressively. But it is usually slow as a full active scan
1736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * is initiated. After the auto focus is converged, the {@link cancelAutoFocus} must be called
1746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * to resume the continuous auto-focus.</p>
1756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
1766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param afRegions The AF regions used by focuser auto focus, full active
1776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * array size is used if afRegions is null.
1786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @throws CameraAccessException
1796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
1806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public synchronized void touchForAutoFocus(MeteringRectangle[] afRegions)
1816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throws CameraAccessException {
1826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        startAutoFocusLocked(/*active*/true, afRegions);
1836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
1846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
1866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Start auto focus scan.
1876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * <p>
1886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Start an auto focus scan if it was not done yet. If AF passively focused,
1896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * lock it. If AF is already locked, return. Otherwise, initiate a full
1906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * active scan. This is suitable for still capture: focus should need to be
1916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * accurate, but the AF latency also need to be as short as possible.
1926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * </p>
1936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
1946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param afRegions The AF regions used by focuser auto focus, full active
1956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *            array size is used if afRegions is null.
1966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @throws CameraAccessException
1976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
1986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public synchronized void startAutoFocus(MeteringRectangle[] afRegions)
1996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throws CameraAccessException {
2006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        startAutoFocusLocked(/*forceActive*/false, afRegions);
2016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
2026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
2046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Cancel ongoing auto focus, unlock the auto-focus if it was locked, and
2056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * resume to passive continuous auto focus.
2066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
2076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @throws CameraAccessException
2086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
2096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public synchronized void cancelAutoFocus() throws CameraAccessException {
2106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mSuccess = false;
2116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mLocked = false;
2126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // reset the AF regions:
2146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        setAfRegions(null);
2156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // Create request builders, the af regions are automatically updated.
2176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mRepeatingBuilder = createRequestBuilder();
2186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        CaptureRequest.Builder requestBuilder = createRequestBuilder();
2196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mAutoFocus.setPassiveAutoFocus(/*picture*/true, mRepeatingBuilder);
2206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mAutoFocus.unlockAutoFocus(mRepeatingBuilder, requestBuilder);
2216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        CaptureCallback listener = createCaptureListener();
2226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mSession.setRepeatingRequest(mRepeatingBuilder.build(), listener, mHandler);
2236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mSession.capture(requestBuilder.build(), listener, mHandler);
2246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
2256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
2276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Get current AF mode.
2286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @return current AF mode
2296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @throws IllegalStateException if there auto focus is not running.
2306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
2316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public synchronized int getCurrentAfMode() {
2326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (mRepeatingBuilder == null) {
2336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throw new IllegalStateException("Auto focus is not running, unable to get AF mode");
2346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
2356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return mRepeatingBuilder.get(CaptureRequest.CONTROL_AF_MODE);
2376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
2386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private void startAutoFocusLocked(
2406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            boolean forceActive, MeteringRectangle[] afRegions) throws CameraAccessException {
2416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        setAfRegions(afRegions);
2436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mAfRun++;
2446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // Create request builders, the af regions are automatically updated.
2466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mRepeatingBuilder = createRequestBuilder();
2476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        CaptureRequest.Builder requestBuilder = createRequestBuilder();
2486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (forceActive) {
2496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            startAutoFocusFullActiveLocked();
2506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        } else {
2516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // Not forcing a full active scan. If AF passively focused, lock it. If AF is already
2526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // locked, return. Otherwise, initiate a full active scan.
2536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            if (mSuccess && mLocked) {
2546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                dispatchAutoFocusStatusLocked(/*success*/true);
2556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                return;
2566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            } else if (mSuccess) {
2576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mAutoFocus.lockAutoFocus(mRepeatingBuilder, requestBuilder);
2586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                CaptureCallback listener = createCaptureListener();
2596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mSession.setRepeatingRequest(mRepeatingBuilder.build(), listener, mHandler);
2606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mSession.capture(requestBuilder.build(), listener, mHandler);
2616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            } else {
2626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                startAutoFocusFullActiveLocked();
2636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
2646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
2656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
2666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private void startAutoFocusFullActiveLocked() throws CameraAccessException {
2686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // Create request builders, the af regions are automatically updated.
2696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mRepeatingBuilder = createRequestBuilder();
2706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        CaptureRequest.Builder requestBuilder = createRequestBuilder();
2716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mAutoFocus.setActiveAutoFocus(mRepeatingBuilder, requestBuilder);
2726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (mRepeatingBuilder.get(CaptureRequest.CONTROL_AF_TRIGGER)
2736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                != CaptureRequest.CONTROL_AF_TRIGGER_IDLE) {
2746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throw new AssertionError("Wrong trigger set in repeating request");
2756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
2766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (requestBuilder.get(CaptureRequest.CONTROL_AF_TRIGGER)
2776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                != CaptureRequest.CONTROL_AF_TRIGGER_START) {
2786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throw new AssertionError("Wrong trigger set in queued request");
2796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
2806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mAutoFocus.resetState();
2816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        CaptureCallback listener = createCaptureListener();
2836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mSession.setRepeatingRequest(mRepeatingBuilder.build(), listener, mHandler);
2846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mSession.capture(requestBuilder.build(), listener, mHandler);
2856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
2866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private void dispatchAutoFocusStatusLocked(final boolean success) {
2886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mHandler.post(new Runnable() {
2896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            @Override
2906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            public void run() {
2916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mAutoFocusListener.onAutoFocusLocked(success);
2926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
2936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        });
2946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
2956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
2976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Create request builder, set the af regions.
2986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @throws CameraAccessException
2996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
3006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private CaptureRequest.Builder createRequestBuilder() throws CameraAccessException {
3016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        CaptureRequest.Builder requestBuilder =
3026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
3036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        requestBuilder.set(CaptureRequest.CONTROL_AF_REGIONS, mAfRegions);
3056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        requestBuilder.addTarget(mRequestSurface);
3066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return requestBuilder;
3086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
3096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
3116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Set AF regions, fall back to default region if afRegions is null.
3126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
3136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param afRegions The AF regions to set
3146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @throws IllegalArgumentException if the region is malformed (length is 0).
3156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
3166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private void setAfRegions(MeteringRectangle[] afRegions) {
3176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (afRegions == null) {
3186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            setDefaultAfRegions();
3196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            return;
3206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
3216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // Throw IAE if AF regions are malformed.
3226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (afRegions.length == 0) {
3236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throw new IllegalArgumentException("afRegions is malformed, length: 0");
3246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
3256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mAfRegions = afRegions;
3276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
3286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
3306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Set default AF region to full active array size.
3316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
3326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private void setDefaultAfRegions() {
3336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // Initialize AF regions with all zeros, meaning that it is up to camera device to device
3346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // the regions used by AF.
3356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mAfRegions = new MeteringRectangle[] {
3366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                new MeteringRectangle(0, 0, 0, 0, MeteringRectangle.METERING_WEIGHT_DONT_CARE)};
3376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
3386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private CaptureCallback createCaptureListener() {
3396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        int thisAfRun;
3416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        synchronized (this) {
3426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            thisAfRun = mAfRun;
3436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
3446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        final int finalAfRun = thisAfRun;
3466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return new CaptureCallback() {
3486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            private long mLatestFrameCount = -1;
3496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            @Override
3516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request,
3526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    CaptureResult result) {
3536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                // In case of a partial result, send to focuser if necessary
3546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                // 3A fields are present
3556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                if (result.get(CaptureResult.CONTROL_AF_STATE) != null &&
3566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        result.get(CaptureResult.CONTROL_AF_MODE) != null) {
3576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    if (VERBOSE) {
3586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        Log.v(TAG, "Focuser - got early AF state");
3596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    }
3606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    dispatchToFocuser(result);
3626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
3636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
3646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            @Override
3666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
3676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    TotalCaptureResult result) {
3686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    dispatchToFocuser(result);
3696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
3706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            private void dispatchToFocuser(CaptureResult result) {
3726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                int afRun;
3736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                synchronized (Camera2Focuser.this) {
3746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    // In case of partial results, don't send AF update twice
3756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    long frameCount = result.getFrameNumber();
3766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    if (frameCount <= mLatestFrameCount) return;
3776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    mLatestFrameCount = frameCount;
3786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    afRun = mAfRun;
3806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
3816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                if (afRun != finalAfRun) {
3836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    if (VERBOSE) {
3846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        Log.w(TAG,
3856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                                "onCaptureCompleted - Ignoring results from previous AF run "
3866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                                + finalAfRun);
3876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    }
3886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    return;
3896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
3906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mAutoFocus.onCaptureCompleted(result);
3926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
3936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        };
3946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
3956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim}
396