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