Camera2SurfaceViewTestCase.java revision 84789bef994180b7bf1bacb6c5d0cb843a1113bc
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;
186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport com.android.ex.camera2.blocking.BlockingSessionCallback;
206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport com.android.ex.camera2.blocking.BlockingStateCallback;
216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport com.android.ex.camera2.exceptions.TimeoutRuntimeException;
226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport com.android.mediaframeworktest.helpers.CameraErrorCollector;
236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport com.android.mediaframeworktest.helpers.CameraTestResultPrinter;
246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport com.android.mediaframeworktest.helpers.CameraTestUtils;
256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport com.android.mediaframeworktest.helpers.CameraTestUtils.SimpleCaptureCallback;
266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport com.android.mediaframeworktest.helpers.StaticMetadata;
276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport com.android.mediaframeworktest.helpers.StaticMetadata.CheckLevel;
286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.content.Context;
306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.graphics.ImageFormat;
316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.CameraAccessException;
326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.CameraCaptureSession;
336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.CameraCaptureSession.CaptureCallback;
346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.CameraCharacteristics;
356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.CameraDevice;
366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.CameraManager;
376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.CameraMetadata;
386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.CaptureRequest;
396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.CaptureResult;
406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.media.ImageReader;
416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.os.Bundle;
426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.os.Environment;
436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.os.Handler;
446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.os.HandlerThread;
456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.os.Looper;
466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.test.ActivityInstrumentationTestCase2;
476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.test.InstrumentationTestRunner;
486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.util.Log;
496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.util.Range;
506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.util.Size;
516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.view.Surface;
526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.view.SurfaceHolder;
536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.view.WindowManager;
546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport java.text.NumberFormat;
566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport java.text.ParseException;
576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport java.util.ArrayList;
586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport java.util.HashMap;
596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport java.util.List;
606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.ex.camera2.blocking.BlockingStateCallback.STATE_CLOSED;
626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.CameraTestUtils.CAMERA_CLOSE_TIMEOUT_MS;
636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.CameraTestUtils.MAX_READER_IMAGES;
646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.CameraTestUtils.PREVIEW_SIZE_BOUND;
656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.CameraTestUtils.configureCameraSession;
666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.CameraTestUtils.getPreviewSizeBound;
676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.CameraTestUtils.getSupportedPreviewSizes;
686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.CameraTestUtils.getSupportedStillSizes;
696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.CameraTestUtils.getSupportedVideoSizes;
706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.CameraTestUtils.makeImageReader;
716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim/**
736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Camera2 Preview test case base class by using SurfaceView as rendering target.
746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim *
756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>This class encapsulates the SurfaceView based preview common functionalities.
766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * The setup and teardown of CameraManager, test HandlerThread, Activity, Camera IDs
776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * and CameraStateCallback are handled in this class. Some basic preview related utility
786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * functions are provided to facilitate the derived preview-based test classes.
796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * </p>
806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */
816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim/**
826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * (non-Javadoc)
836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @see android.hardware.camera2.cts.Camera2SurfaceViewTestCase
846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */
856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimpublic class Camera2SurfaceViewTestCase extends
866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        ActivityInstrumentationTestCase2<Camera2SurfaceViewActivity> {
876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final String TAG = "SurfaceViewTestCase";
896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final int WAIT_FOR_SURFACE_CHANGE_TIMEOUT_MS = 1000;
916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    // Instrumentation arguments
9384789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim    protected static final String ARG_KEY_ITERATIONS = "iterations";
946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected static final String ARG_KEY_WAIT_INTERVAL_MS = "waitIntervalMs";
956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected static final String ARG_KEY_RESULT_TO_FILE = "resultToFile";
966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    // TODO: Use internal storage for this to make sure the file is only visible to test.
986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected static final String DEBUG_FILE_NAME_BASE =
996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Environment.getExternalStorageDirectory().getPath();
1006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected static final int WAIT_FOR_RESULT_TIMEOUT_MS = 3000;
1016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected static final float FRAME_DURATION_ERROR_MARGIN = 0.005f; // 0.5 percent error margin.
1026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected static final int NUM_RESULTS_WAIT_TIMEOUT = 100;
1036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected static final int NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY = 8;
1046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected static final int MIN_FRAME_DURATION_ERROR_MARGIN = 100; // ns
1056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected Context mContext;
1076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected CameraManager mCameraManager;
1086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected String[] mCameraIds;
1096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected HandlerThread mHandlerThread;
1106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected Handler mHandler;
1116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected BlockingStateCallback mCameraListener;
1126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected BlockingSessionCallback mSessionListener;
1136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected CameraErrorCollector mCollector;
1146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    // Per device fields:
1156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected StaticMetadata mStaticInfo;
1166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected CameraDevice mCamera;
1176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected CameraCaptureSession mSession;
1186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected ImageReader mReader;
1196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected Surface mReaderSurface;
1206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected Surface mPreviewSurface;
1216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected Size mPreviewSize;
1226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected List<Size> mOrderedPreviewSizes; // In descending order.
1236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected List<Size> mOrderedVideoSizes; // In descending order.
1246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected List<Size> mOrderedStillSizes; // In descending order.
1256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected HashMap<Size, Long> mMinPreviewFrameDurationMap;
1266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected WindowManager mWindowManager;
1286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
12984789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim    // Set the number of iterations to run stress testing. Default to 1.
13084789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim    protected int mIterations = 1;
1316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    // The interval between test iterations used for stress test.
1326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected long mTestWaitIntervalMs = 1 * 1000;  // 1 sec
1336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected boolean mWriteToFile = true;
1346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected CameraTestResultPrinter mResultPrinter;
1356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public Camera2SurfaceViewTestCase() {
1386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        super(Camera2SurfaceViewActivity.class);
1396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
1406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    @Override
1426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected void setUp() throws Exception {
1436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        /**
1446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim         * Set up the camera preview required environments, including activity,
1456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim         * CameraManager, HandlerThread, Camera IDs, and CameraStateCallback.
1466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim         */
1476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        super.setUp();
1486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mContext = getActivity();
1496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        /**
1506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim         * Workaround for mockito and JB-MR2 incompatibility
1516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim         *
1526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim         * Avoid java.lang.IllegalArgumentException: dexcache == null
1536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim         * https://code.google.com/p/dexmaker/issues/detail?id=2
1546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim         */
1556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        System.setProperty("dexmaker.dexcache", mContext.getCacheDir().toString());
1566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mCameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
1576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        assertNotNull("Unable to get CameraManager", mCameraManager);
1586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mCameraIds = mCameraManager.getCameraIdList();
1596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        assertNotNull("Unable to get camera ids", mCameraIds);
1606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mHandlerThread = new HandlerThread(TAG);
1616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mHandlerThread.start();
1626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mHandler = new Handler(mHandlerThread.getLooper());
1636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mCameraListener = new BlockingStateCallback();
1646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mCollector = new CameraErrorCollector();
1656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
1676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
16884789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim        mIterations = getArgumentsAsNumber(ARG_KEY_ITERATIONS, 1).intValue();
1696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mTestWaitIntervalMs = getArgumentsAsNumber(ARG_KEY_WAIT_INTERVAL_MS, 1000).longValue();
1706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mWriteToFile = getArgumentsAsBoolean(ARG_KEY_RESULT_TO_FILE, true);
17184789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim        Log.i(TAG, "Argument: iteration count=" + mIterations);
1726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Log.i(TAG, "Argument: interval (ms)=" + mTestWaitIntervalMs);
1736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Log.i(TAG, "Argument: result to file=" + (mWriteToFile ? "true" : "false"));
1746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mResultPrinter = new CameraTestResultPrinter(getInstrumentation(), mWriteToFile);
1756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
1766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    @Override
1786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected void tearDown() throws Exception {
1796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // Teardown the camera preview required environments.
1806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mHandlerThread.quitSafely();
1816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mHandler = null;
1826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mCameraListener = null;
1836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        try {
1856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mCollector.verify();
1866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        } catch (Throwable e) {
1876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // When new Exception(e) is used, exception info will be printed twice.
1886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throw new Exception(e.getMessage());
1896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        } finally {
1906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            super.tearDown();
1916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
1926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
1936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
1956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Start camera preview by using the given request, preview size and capture
1966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * listener.
1976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * <p>
1986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * If preview is already started, calling this function will stop the
1996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * current preview stream and start a new preview stream with given
2006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * parameters. No need to call stopPreview between two startPreview calls.
2016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * </p>
2026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
2036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param request The request builder used to start the preview.
2046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param previewSz The size of the camera device output preview stream.
2056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param listener The callbacks the camera device will notify when preview
2066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *            capture is available.
2076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
2086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected void startPreview(CaptureRequest.Builder request, Size previewSz,
2096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            CaptureCallback listener) throws Exception {
2106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // Update preview size.
2116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        updatePreviewSurface(previewSz);
2126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (VERBOSE) {
2136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Log.v(TAG, "start preview with size " + mPreviewSize.toString());
2146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
2156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        configurePreviewOutput(request);
2176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mSession.setRepeatingRequest(request.build(), listener, mHandler);
2196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
2206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
2226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Configure the preview output stream.
2236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
2246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param request The request to be configured with preview surface
2256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
2266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected void configurePreviewOutput(CaptureRequest.Builder request)
2276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throws CameraAccessException {
2286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        List<Surface> outputSurfaces = new ArrayList<Surface>(/*capacity*/1);
2296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        outputSurfaces.add(mPreviewSurface);
2306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mSessionListener = new BlockingSessionCallback();
2316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mSession = configureCameraSession(mCamera, outputSurfaces, mSessionListener, mHandler);
2326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        request.addTarget(mPreviewSurface);
2346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
2356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
2376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Create a {@link CaptureRequest#Builder} and add the default preview surface.
2386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
2396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @return The {@link CaptureRequest#Builder} to be created
2406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @throws CameraAccessException When create capture request from camera fails
2416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
2426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected CaptureRequest.Builder createRequestForPreview() throws CameraAccessException {
2436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (mPreviewSurface == null) {
2446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throw new IllegalStateException(
2456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    "Preview surface is not set yet, call updatePreviewSurface or startPreview"
2466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    + "first to set the preview surface properly.");
2476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
2486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        CaptureRequest.Builder requestBuilder =
2496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
2506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        requestBuilder.addTarget(mPreviewSurface);
2516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return requestBuilder;
2526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
2536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
2556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Stop preview for current camera device.
2566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
2576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected void stopPreview() throws Exception {
2586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (VERBOSE) Log.v(TAG, "Stopping preview and waiting for idle");
2596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // Stop repeat, wait for captures to complete, and disconnect from surfaces
2606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mSession.close();
2616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
2626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
2646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Setup still (JPEG) capture configuration and start preview.
2656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * <p>
2666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * The default max number of image is set to image reader.
2676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * </p>
2686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
2696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param previewRequest The capture request to be used for preview
2706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param stillRequest The capture request to be used for still capture
2716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param previewSz Preview size
2726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param stillSz The still capture size
2736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param resultListener Capture result listener
2746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param imageListener The still capture image listener
2756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
2766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected void prepareStillCaptureAndStartPreview(CaptureRequest.Builder previewRequest,
2776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            CaptureRequest.Builder stillRequest, Size previewSz, Size stillSz,
2786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            CaptureCallback resultListener,
2796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            ImageReader.OnImageAvailableListener imageListener) throws Exception {
2806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        prepareCaptureAndStartPreview(previewRequest, stillRequest, previewSz, stillSz,
2816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                ImageFormat.JPEG, resultListener, MAX_READER_IMAGES, imageListener);
2826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
2836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
2856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Setup still (JPEG) capture configuration and start preview.
2866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
2876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param previewRequest The capture request to be used for preview
2886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param stillRequest The capture request to be used for still capture
2896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param previewSz Preview size
2906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param stillSz The still capture size
2916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param resultListener Capture result listener
2926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param maxNumImages The max number of images set to the image reader
2936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param imageListener The still capture image listener
2946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
2956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected void prepareStillCaptureAndStartPreview(CaptureRequest.Builder previewRequest,
2966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            CaptureRequest.Builder stillRequest, Size previewSz, Size stillSz,
2976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            CaptureCallback resultListener, int maxNumImages,
2986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            ImageReader.OnImageAvailableListener imageListener) throws Exception {
2996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        prepareCaptureAndStartPreview(previewRequest, stillRequest, previewSz, stillSz,
3006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                ImageFormat.JPEG, resultListener, maxNumImages, imageListener);
3016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
3026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
3046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Setup raw capture configuration and start preview.
3056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
3066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * <p>
3076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * The default max number of image is set to image reader.
3086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * </p>
3096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
3106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param previewRequest The capture request to be used for preview
3116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param rawRequest The capture request to be used for raw capture
3126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param previewSz Preview size
3136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param rawSz The raw capture size
3146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param resultListener Capture result listener
3156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param imageListener The raw capture image listener
3166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
3176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected void prepareRawCaptureAndStartPreview(CaptureRequest.Builder previewRequest,
3186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            CaptureRequest.Builder rawRequest, Size previewSz, Size rawSz,
3196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            CaptureCallback resultListener,
3206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            ImageReader.OnImageAvailableListener imageListener) throws Exception {
3216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        prepareCaptureAndStartPreview(previewRequest, rawRequest, previewSz, rawSz,
3226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                ImageFormat.RAW_SENSOR, resultListener, MAX_READER_IMAGES, imageListener);
3236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
3246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
3266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Wait for expected result key value available in a certain number of results.
3276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
3286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * <p>
3296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Check the result immediately if numFramesWait is 0.
3306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * </p>
3316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
3326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param listener The capture listener to get capture result
3336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param resultKey The capture result key associated with the result value
3346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param expectedValue The result value need to be waited for
3356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param numResultsWait Number of frame to wait before times out
3366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @throws TimeoutRuntimeException If more than numResultsWait results are
3376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * seen before the result matching myRequest arrives, or each individual wait
3386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * for result times out after {@value #WAIT_FOR_RESULT_TIMEOUT_MS}ms.
3396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
3406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected static <T> void waitForResultValue(SimpleCaptureCallback listener,
3416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            CaptureResult.Key<T> resultKey,
3426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            T expectedValue, int numResultsWait) {
3436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        List<T> expectedValues = new ArrayList<T>();
3446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        expectedValues.add(expectedValue);
3456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        waitForAnyResultValue(listener, resultKey, expectedValues, numResultsWait);
3466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
3476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
3496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Wait for any expected result key values available in a certain number of results.
3506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
3516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * <p>
3526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Check the result immediately if numFramesWait is 0.
3536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * </p>
3546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
3556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param listener The capture listener to get capture result.
3566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param resultKey The capture result key associated with the result value.
3576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param expectedValues The list of result value need to be waited for,
3586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * return immediately if the list is empty.
3596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param numResultsWait Number of frame to wait before times out.
3606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @throws TimeoutRuntimeException If more than numResultsWait results are.
3616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * seen before the result matching myRequest arrives, or each individual wait
3626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * for result times out after {@value #WAIT_FOR_RESULT_TIMEOUT_MS}ms.
3636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
3646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected static <T> void waitForAnyResultValue(SimpleCaptureCallback listener,
3656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            CaptureResult.Key<T> resultKey,
3666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            List<T> expectedValues, int numResultsWait) {
3676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (numResultsWait < 0 || listener == null || expectedValues == null) {
3686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throw new IllegalArgumentException(
3696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    "Input must be non-negative number and listener/expectedValues "
3706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    + "must be non-null");
3716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
3726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        int i = 0;
3746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        CaptureResult result;
3756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        do {
3766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            result = listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
3776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            T value = result.get(resultKey);
3786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            for ( T expectedValue : expectedValues) {
3796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                if (VERBOSE) {
3806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    Log.v(TAG, "Current result value for key " + resultKey.getName() + " is: "
3816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            + value.toString());
3826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
3836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                if (value.equals(expectedValue)) {
3846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    return;
3856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
3866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
3876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        } while (i++ < numResultsWait);
3886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        throw new TimeoutRuntimeException(
3906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                "Unable to get the expected result value " + expectedValues + " for key " +
3916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        resultKey.getName() + " after waiting for " + numResultsWait + " results");
3926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
3936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
3956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Submit a capture once, then submit additional captures in order to ensure that
3966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * the camera will be synchronized.
3976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
3986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * <p>
3996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * The additional capture count is determined by android.sync.maxLatency (or
4006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * a fixed {@value #NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY}) captures if maxLatency is unknown).
4016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * </p>
4026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
4036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * <p>Returns the number of captures that were submitted (at least 1), which is useful
4046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * with {@link #waitForNumResults}.</p>
4056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
4066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param request capture request to forward to {@link CameraDevice#capture}
4076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param listener request listener to forward to {@link CameraDevice#capture}
4086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param handler handler to forward to {@link CameraDevice#capture}
4096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
4106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @return the number of captures that were submitted
4116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
4126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @throws CameraAccessException if capturing failed
4136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
4146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected int captureRequestsSynchronized(
4156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            CaptureRequest request, CaptureCallback listener, Handler handler)
4166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    throws CameraAccessException {
4176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return captureRequestsSynchronized(request, /*count*/1, listener, handler);
4186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
4196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
4216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Submit a capture {@code count} times, then submit additional captures in order to ensure that
4226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * the camera will be synchronized.
4236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
4246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * <p>
4256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * The additional capture count is determined by android.sync.maxLatency (or
4266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * a fixed {@value #NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY}) captures if maxLatency is unknown).
4276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * </p>
4286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
4296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * <p>Returns the number of captures that were submitted (at least 1), which is useful
4306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * with {@link #waitForNumResults}.</p>
4316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
4326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param request capture request to forward to {@link CameraDevice#capture}
4336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param count the number of times to submit the request (minimally), must be at least 1
4346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param listener request listener to forward to {@link CameraDevice#capture}
4356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param handler handler to forward to {@link CameraDevice#capture}
4366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
4376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @return the number of captures that were submitted
4386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
4396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @throws IllegalArgumentException if {@code count} was not at least 1
4406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @throws CameraAccessException if capturing failed
4416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
4426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected int captureRequestsSynchronized(
4436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            CaptureRequest request, int count, CaptureCallback listener, Handler handler)
4446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    throws CameraAccessException {
4456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (count < 1) {
4466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throw new IllegalArgumentException("count must be positive");
4476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
4486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        int maxLatency = mStaticInfo.getSyncMaxLatency();
4506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (maxLatency == CameraMetadata.SYNC_MAX_LATENCY_UNKNOWN) {
4516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            maxLatency = NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY;
4526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
4536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        assertTrue("maxLatency is non-negative", maxLatency >= 0);
4556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        int numCaptures = maxLatency + count;
4576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        for (int i = 0; i < numCaptures; ++i) {
4596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mSession.capture(request, listener, handler);
4606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
4616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return numCaptures;
4636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
4646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
4666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Wait for numResultWait frames
4676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
4686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param resultListener The capture listener to get capture result back.
4696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param numResultsWait Number of frame to wait
4706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
4716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @return the last result, or {@code null} if there was none
4726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
4736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected static CaptureResult waitForNumResults(SimpleCaptureCallback resultListener,
4746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            int numResultsWait) {
4756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (numResultsWait < 0 || resultListener == null) {
4766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throw new IllegalArgumentException(
4776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    "Input must be positive number and listener must be non-null");
4786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
4796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        CaptureResult result = null;
4816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        for (int i = 0; i < numResultsWait; i++) {
4826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            result = resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
4836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
4846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return result;
4866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
4876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
4896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Wait for enough results for settings to be applied
4906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
4916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param resultListener The capture listener to get capture result back.
4926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param numResultWaitForUnknownLatency Number of frame to wait if camera device latency is
4936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *                                       unknown.
4946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
4956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected void waitForSettingsApplied(SimpleCaptureCallback resultListener,
4966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            int numResultWaitForUnknownLatency) {
4976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        int maxLatency = mStaticInfo.getSyncMaxLatency();
4986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (maxLatency == CameraMetadata.SYNC_MAX_LATENCY_UNKNOWN) {
4996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            maxLatency = numResultWaitForUnknownLatency;
5006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
5016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // Wait for settings to take effect
5026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        waitForNumResults(resultListener, maxLatency);
5036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
5046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
5076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Wait for AE to be stabilized before capture: CONVERGED or FLASH_REQUIRED.
5086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
5096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * <p>Waits for {@code android.sync.maxLatency} number of results first, to make sure
5106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * that the result is synchronized (or {@code numResultWaitForUnknownLatency} if the latency
5116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * is unknown.</p>
5126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
5136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * <p>This is a no-op for {@code LEGACY} devices since they don't report
5146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * the {@code aeState} result.</p>
5156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
5166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param resultListener The capture listener to get capture result back.
5176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param numResultWaitForUnknownLatency Number of frame to wait if camera device latency is
5186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *                                       unknown.
5196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
5206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected void waitForAeStable(SimpleCaptureCallback resultListener,
5216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            int numResultWaitForUnknownLatency) {
5226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        waitForSettingsApplied(resultListener, numResultWaitForUnknownLatency);
5236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (!mStaticInfo.isHardwareLevelLimitedOrBetter()) {
5256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // No-op for metadata
5266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            return;
5276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
5286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        List<Integer> expectedAeStates = new ArrayList<Integer>();
5296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        expectedAeStates.add(new Integer(CaptureResult.CONTROL_AE_STATE_CONVERGED));
5306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        expectedAeStates.add(new Integer(CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED));
5316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        waitForAnyResultValue(resultListener, CaptureResult.CONTROL_AE_STATE, expectedAeStates,
5326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                NUM_RESULTS_WAIT_TIMEOUT);
5336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
5346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
5366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Wait for AE to be: LOCKED
5376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
5386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * <p>Waits for {@code android.sync.maxLatency} number of results first, to make sure
5396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * that the result is synchronized (or {@code numResultWaitForUnknownLatency} if the latency
5406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * is unknown.</p>
5416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
5426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * <p>This is a no-op for {@code LEGACY} devices since they don't report
5436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * the {@code aeState} result.</p>
5446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
5456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param resultListener The capture listener to get capture result back.
5466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param numResultWaitForUnknownLatency Number of frame to wait if camera device latency is
5476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *                                       unknown.
5486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
5496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected void waitForAeLocked(SimpleCaptureCallback resultListener,
5506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            int numResultWaitForUnknownLatency) {
5516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        waitForSettingsApplied(resultListener, numResultWaitForUnknownLatency);
5536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (!mStaticInfo.isHardwareLevelLimitedOrBetter()) {
5556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // No-op for legacy devices
5566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            return;
5576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
5586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        List<Integer> expectedAeStates = new ArrayList<Integer>();
5606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        expectedAeStates.add(new Integer(CaptureResult.CONTROL_AE_STATE_LOCKED));
5616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        waitForAnyResultValue(resultListener, CaptureResult.CONTROL_AE_STATE, expectedAeStates,
5626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                NUM_RESULTS_WAIT_TIMEOUT);
5636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
5646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
5666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Create an {@link ImageReader} object and get the surface.
5676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
5686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param size The size of this ImageReader to be created.
5696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param format The format of this ImageReader to be created
5706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param maxNumImages The max number of images that can be acquired simultaneously.
5716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param listener The listener used by this ImageReader to notify callbacks.
5726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
5736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected void createImageReader(Size size, int format, int maxNumImages,
5746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            ImageReader.OnImageAvailableListener listener) throws Exception {
5756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        closeImageReader();
5766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        ImageReader r = makeImageReader(size, format, maxNumImages, listener,
5786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mHandler);
5796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mReader = r;
5806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mReaderSurface = r.getSurface();
5816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
5826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
5846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Close the pending images then close current active {@link ImageReader} object.
5856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
5866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected void closeImageReader() {
5876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        CameraTestUtils.closeImageReader(mReader);
5886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mReader = null;
5896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mReaderSurface = null;
5906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
5916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
5936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Open a camera device and get the StaticMetadata for a given camera id.
5946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
5956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param cameraId The id of the camera device to be opened.
5966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
5976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected void openDevice(String cameraId) throws Exception {
5986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mCamera = CameraTestUtils.openCamera(
5996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mCameraManager, cameraId, mCameraListener, mHandler);
6006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mCollector.setCameraId(cameraId);
6016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mStaticInfo = new StaticMetadata(mCameraManager.getCameraCharacteristics(cameraId),
6026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                CheckLevel.ASSERT, /*collector*/null);
6036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (mStaticInfo.isColorOutputSupported()) {
6046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mOrderedPreviewSizes = getSupportedPreviewSizes(cameraId, mCameraManager,
6056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    getPreviewSizeBound(mWindowManager, PREVIEW_SIZE_BOUND));
6066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mOrderedVideoSizes = getSupportedVideoSizes(cameraId, mCameraManager, PREVIEW_SIZE_BOUND);
6076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mOrderedStillSizes = getSupportedStillSizes(cameraId, mCameraManager, null);
6086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // Use ImageFormat.YUV_420_888 for now. TODO: need figure out what's format for preview
6096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // in public API side.
6106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mMinPreviewFrameDurationMap =
6116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mStaticInfo.getAvailableMinFrameDurationsForFormatChecked(ImageFormat.YUV_420_888);
6126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
6136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
6146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
6156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
6166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Close the current actively used camera device.
6176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
6186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected void closeDevice() {
6196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (mCamera != null) {
6206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mCamera.close();
6216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mCameraListener.waitForState(STATE_CLOSED, CAMERA_CLOSE_TIMEOUT_MS);
6226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mCamera = null;
6236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mSession = null;
6246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mSessionListener = null;
6256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mStaticInfo = null;
6266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mOrderedPreviewSizes = null;
6276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mOrderedVideoSizes = null;
6286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mOrderedStillSizes = null;
6296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
6306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
6316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
6326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
6336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Update the preview surface size.
6346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
6356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param size The preview size to be updated.
6366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
6376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected void updatePreviewSurface(Size size) {
6386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (size.equals(mPreviewSize) && mPreviewSurface != null) {
6396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Log.w(TAG, "Skipping update preview surface size...");
6406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            return;
6416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
6426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
6436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mPreviewSize = size;
6446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Camera2SurfaceViewActivity ctsActivity = getActivity();
6456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        final SurfaceHolder holder = ctsActivity.getSurfaceView().getHolder();
6466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Handler handler = new Handler(Looper.getMainLooper());
6476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        handler.post(new Runnable() {
6486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            @Override
6496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            public void run() {
6506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                holder.setFixedSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
6516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
6526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        });
6536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
6546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        boolean res = ctsActivity.waitForSurfaceSizeChanged(
6556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                WAIT_FOR_SURFACE_CHANGE_TIMEOUT_MS, mPreviewSize.getWidth(),
6566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mPreviewSize.getHeight());
6576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        assertTrue("wait for surface change to " + mPreviewSize.toString() + " timed out", res);
6586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mPreviewSurface = holder.getSurface();
6596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        assertNotNull("Preview surface is null", mPreviewSurface);
6606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        assertTrue("Preview surface is invalid", mPreviewSurface.isValid());
6616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
6626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
6636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
6646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Setup single capture configuration and start preview.
6656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
6666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param previewRequest The capture request to be used for preview
6676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param stillRequest The capture request to be used for still capture
6686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param previewSz Preview size
6696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param captureSz Still capture size
6706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param format The single capture image format
6716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param resultListener Capture result listener
6726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param maxNumImages The max number of images set to the image reader
6736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param imageListener The single capture capture image listener
6746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
6756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected void prepareCaptureAndStartPreview(CaptureRequest.Builder previewRequest,
6766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            CaptureRequest.Builder stillRequest, Size previewSz, Size captureSz, int format,
6776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            CaptureCallback resultListener, int maxNumImages,
6786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            ImageReader.OnImageAvailableListener imageListener) throws Exception {
6796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (VERBOSE) {
6806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Log.v(TAG, String.format("Prepare single capture (%s) and preview (%s)",
6816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    captureSz.toString(), previewSz.toString()));
6826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
6836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
6846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // Update preview size.
6856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        updatePreviewSurface(previewSz);
6866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
6876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // Create ImageReader.
6886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        createImageReader(captureSz, format, maxNumImages, imageListener);
6896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
6906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // Configure output streams with preview and jpeg streams.
6916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        List<Surface> outputSurfaces = new ArrayList<Surface>();
6926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        outputSurfaces.add(mPreviewSurface);
6936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        outputSurfaces.add(mReaderSurface);
6946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mSessionListener = new BlockingSessionCallback();
6956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mSession = configureCameraSession(mCamera, outputSurfaces, mSessionListener, mHandler);
6966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
6976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // Configure the requests.
6986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        previewRequest.addTarget(mPreviewSurface);
6996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        stillRequest.addTarget(mPreviewSurface);
7006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        stillRequest.addTarget(mReaderSurface);
7016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
7026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // Start preview.
7036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mSession.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
7046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
7056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
7066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
7076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Get the max preview size that supports the given fpsRange.
7086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
7096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param fpsRange The fps range the returned size must support.
7106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @return max size that support the given fps range.
7116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
7126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected Size getMaxPreviewSizeForFpsRange(Range<Integer> fpsRange) {
7136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (fpsRange == null || fpsRange.getLower() <= 0 || fpsRange.getUpper() <= 0) {
7146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throw new IllegalArgumentException("Invalid fps range argument");
7156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
7166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (mOrderedPreviewSizes == null || mMinPreviewFrameDurationMap == null) {
7176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throw new IllegalStateException("mOrderedPreviewSizes and mMinPreviewFrameDurationMap"
7186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    + " must be initialized");
7196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
7206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
7216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        long[] frameDurationRange =
7226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                new long[]{(long) (1e9 / fpsRange.getUpper()), (long) (1e9 / fpsRange.getLower())};
7236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        for (Size size : mOrderedPreviewSizes) {
7246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Long minDuration = mMinPreviewFrameDurationMap.get(size);
7256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            if (minDuration == null ||
7266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    minDuration == 0) {
7276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                if (mStaticInfo.isCapabilitySupported(
7286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
7296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    throw new IllegalArgumentException(
7306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            "No min frame duration available for the size " + size);
7316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
7326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                continue;
7336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
7346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            if (minDuration <= (frameDurationRange[0] + MIN_FRAME_DURATION_ERROR_MARGIN)) {
7356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                return size;
7366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
7376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
7386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
7396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return null;
7406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
7416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
7426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected boolean isReprocessSupported(String cameraId, int format)
7436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throws CameraAccessException {
7446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (format != ImageFormat.YUV_420_888 && format != ImageFormat.PRIVATE) {
7456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throw new IllegalArgumentException(
7466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    "format " + format + " is not supported for reprocessing");
7476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
7486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
7496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        StaticMetadata info =
7506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                new StaticMetadata(mCameraManager.getCameraCharacteristics(cameraId),
7516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                                   CheckLevel.ASSERT, /*collector*/ null);
7526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        int cap = CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING;
7536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (format == ImageFormat.PRIVATE) {
7546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            cap = CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING;
7556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
7566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return info.isCapabilitySupported(cap);
7576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
7586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
7596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    //--------------------------------------------------------------------------------
7606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    //---------Below are common functions for Camera framework test run.--------------
7616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    //--------------------------------------------------------------------------------
7626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
7636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected Bundle getArguments() {
7646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return ((InstrumentationTestRunner)getInstrumentation()).getArguments();
7656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
7666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
7676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected <E extends Number> Number getArgumentsAsNumber(String key, E defaultValue) {
7686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        String stringValue = getArguments().getString(key);
7696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (stringValue != null) {
7706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            try {
7716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                return NumberFormat.getInstance().parse(stringValue);
7726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            } catch (ParseException e) {
7736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                Log.w(TAG, "Unable to parse arg " + key + " with value " + stringValue
7746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        + " to a integer.", e);
7756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
7766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
7776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return defaultValue;
7786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
7796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
7806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected boolean getArgumentsAsBoolean(String key, boolean defaultValue) {
7816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        String stringValue = getArguments().getString(key);
7826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (stringValue != null) {
7836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            try {
7846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                return Boolean.parseBoolean(stringValue);
7856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            } catch (Exception e) {
7866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                Log.w(TAG, "Unable to parse arg " + key + " with value " + stringValue
7876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        + " to a boolean.", e);
7886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
7896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
7906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return defaultValue;
7916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
7926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
79384789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim    protected int getIterationCount() {
79484789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim        return mIterations;
7956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
7966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
7976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected long getTestWaitIntervalMs() {
7986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return mTestWaitIntervalMs;
7996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
8006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
8016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public CameraTestResultPrinter getResultPrinter() {
8026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return mResultPrinter;
8036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
8046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim}
805