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.stress;
186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport com.android.ex.camera2.blocking.BlockingSessionCallback;
206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport com.android.ex.camera2.exceptions.TimeoutRuntimeException;
216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport com.android.mediaframeworktest.Camera2SurfaceViewTestCase;
226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport com.android.mediaframeworktest.helpers.Camera2Focuser;
236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport com.android.mediaframeworktest.helpers.CameraTestUtils;
246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport com.android.mediaframeworktest.helpers.CameraTestUtils.SimpleCaptureCallback;
256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.graphics.ImageFormat;
276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.graphics.Point;
286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.CameraCharacteristics;
296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.CameraDevice;
306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.CaptureRequest;
316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.CaptureResult;
326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.DngCreator;
336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.params.MeteringRectangle;
346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.media.Image;
356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.media.ImageReader;
366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.os.ConditionVariable;
376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.util.Log;
386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.util.Pair;
396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.util.Rational;
406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.util.Size;
416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.view.Surface;
426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport java.io.ByteArrayOutputStream;
446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport java.util.ArrayList;
456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport java.util.List;
466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.CameraTestUtils.CAPTURE_IMAGE_TIMEOUT_MS;
486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.CameraTestUtils.MAX_READER_IMAGES;
496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.CameraTestUtils.SimpleImageReaderListener;
506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.CameraTestUtils.basicValidateJpegImage;
516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.CameraTestUtils.configureCameraSession;
526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.CameraTestUtils.dumpFile;
536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.CameraTestUtils.getDataFromImage;
546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.CameraTestUtils.getValueNotNull;
556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.CameraTestUtils.makeImageReader;
566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim/**
586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>Tests for still capture API.</p>
596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim *
606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * adb shell am instrument \
616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim *    -e class com.android.mediaframeworktest.stress.Camera2StillCaptureTest#testTakePicture \
6284789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim *    -e iterations 200 \
636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim *    -e waitIntervalMs 1000 \
646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim *    -e resultToFile false \
656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim *    -r -w com.android.mediaframeworktest/.Camera2InstrumentationTestRunner
666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */
676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimpublic class Camera2StillCaptureTest extends Camera2SurfaceViewTestCase {
686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final String TAG = "StillCaptureTest";
696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    // 60 second to accommodate the possible long exposure time.
726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final int MAX_REGIONS_AE_INDEX = 0;
736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final int MAX_REGIONS_AWB_INDEX = 1;
746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final int MAX_REGIONS_AF_INDEX = 2;
756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final int WAIT_FOR_FOCUS_DONE_TIMEOUT_MS = 6000;
766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final double AE_COMPENSATION_ERROR_TOLERANCE = 0.2;
776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    // 5 percent error margin for resulting metering regions
786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final float METERING_REGION_ERROR_PERCENT_DELTA = 0.05f;
796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    @Override
816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected void setUp() throws Exception {
826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        super.setUp();
836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    @Override
866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    protected void tearDown() throws Exception {
876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        super.tearDown();
886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Test normal still capture sequence.
926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * <p>
936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Preview and and jpeg output streams are configured. Max still capture
946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * size is used for jpeg capture. The sequence of still capture being test
956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * is: start preview, auto focus, precapture metering (if AE is not
966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * converged), then capture jpeg. The AWB and AE are in auto modes. AF mode
976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * is CONTINUOUS_PICTURE.
986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * </p>
996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
1006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public void testTakePicture() throws Exception{
1016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        for (String id : mCameraIds) {
1026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            try {
1036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                Log.i(TAG, "Testing basic take picture for Camera " + id);
1046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                openDevice(id);
1056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                if (!mStaticInfo.isColorOutputSupported()) {
1066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
1076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    continue;
1086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
1096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                // Test iteration starts...
11184789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim                for (int iteration = 0; iteration < getIterationCount(); ++iteration) {
11284789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim                    Log.v(TAG, String.format("Taking pictures: %d/%d", iteration + 1,
11384789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim                            getIterationCount()));
1146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    takePictureTestByCamera(/*aeRegions*/null, /*awbRegions*/null,
1156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            /*afRegions*/null);
11684789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim                    getResultPrinter().printStatus(getIterationCount(), iteration + 1, id);
1176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    Thread.sleep(getTestWaitIntervalMs());
1186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
1196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            } finally {
1206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                closeDevice();
1216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                closeImageReader();
1226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
1236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
1246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
1256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
1276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Test the full raw capture use case.
1286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
1296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * This includes:
1306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * - Configuring the camera with a preview, jpeg, and raw output stream.
1316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * - Running preview until AE/AF can settle.
1326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * - Capturing with a request targeting all three output streams.
1336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
1346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public void testFullRawCapture() throws Exception {
1356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        for (int i = 0; i < mCameraIds.length; i++) {
1366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            try {
1376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                Log.i(TAG, "Testing raw capture for Camera " + mCameraIds[i]);
1386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                openDevice(mCameraIds[i]);
1396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                if (!mStaticInfo.isCapabilitySupported(
1406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
1416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    Log.i(TAG, "RAW capability is not supported in camera " + mCameraIds[i] +
1426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            ". Skip the test.");
1436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    continue;
1446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
1456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                // Test iteration starts...
14784789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim                for (int iteration = 0; iteration < getIterationCount(); ++iteration) {
14884789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim                    Log.v(TAG, String.format("Taking full RAW pictures: %d/%d", iteration + 1,
14984789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim                            getIterationCount()));
1506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    fullRawCaptureTestByCamera();
15184789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim                    getResultPrinter().printStatus(getIterationCount(), iteration + 1,
15284789bef994180b7bf1bacb6c5d0cb843a1113bcHyungtae Tim Kim                            mCameraIds[i]);
1536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    Thread.sleep(getTestWaitIntervalMs());
1546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
1556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            } finally {
1566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                closeDevice();
1576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                closeImageReader();
1586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
1596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
1606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
1616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
1636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Take a picture for a given set of 3A regions for a particular camera.
1646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * <p>
1656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Before take a still capture, it triggers an auto focus and lock it first,
1666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * then wait for AWB to converge and lock it, then trigger a precapture
1676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * metering sequence and wait for AE converged. After capture is received, the
1686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * capture result and image are validated.
1696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * </p>
1706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
1716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param aeRegions AE regions for this capture
1726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param awbRegions AWB regions for this capture
1736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param afRegions AF regions for this capture
1746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
1756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private void takePictureTestByCamera(
1766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            MeteringRectangle[] aeRegions, MeteringRectangle[] awbRegions,
1776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            MeteringRectangle[] afRegions) throws Exception {
1786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        takePictureTestByCamera(aeRegions, awbRegions, afRegions,
1796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                /*addAeTriggerCancel*/false);
1806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
1816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
1836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Take a picture for a given set of 3A regions for a particular camera.
1846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * <p>
1856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Before take a still capture, it triggers an auto focus and lock it first,
1866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * then wait for AWB to converge and lock it, then trigger a precapture
1876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * metering sequence and wait for AE converged. After capture is received, the
1886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * capture result and image are validated. If {@code addAeTriggerCancel} is true,
1896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * a precapture trigger cancel will be inserted between two adjacent triggers, which
1906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * should effective cancel the first trigger.
1916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * </p>
1926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
1936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param aeRegions AE regions for this capture
1946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param awbRegions AWB regions for this capture
1956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param afRegions AF regions for this capture
1966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param addAeTriggerCancel If a AE precapture trigger cancel is sent after the trigger.
1976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
1986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private void takePictureTestByCamera(
1996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            MeteringRectangle[] aeRegions, MeteringRectangle[] awbRegions,
2006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            MeteringRectangle[] afRegions, boolean addAeTriggerCancel) throws Exception {
2016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        boolean hasFocuser = mStaticInfo.hasFocuser();
2036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Size maxStillSz = mOrderedStillSizes.get(0);
2056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Size maxPreviewSz = mOrderedPreviewSizes.get(0);
2066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        CaptureResult result;
2076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
2086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        SimpleImageReaderListener imageListener = new SimpleImageReaderListener();
2096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        CaptureRequest.Builder previewRequest =
2106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
2116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        CaptureRequest.Builder stillRequest =
2126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
2136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        prepareStillCaptureAndStartPreview(previewRequest, stillRequest, maxPreviewSz,
2146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                maxStillSz, resultListener, imageListener);
2156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // Set AE mode to ON_AUTO_FLASH if flash is available.
2176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (mStaticInfo.hasFlash()) {
2186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            previewRequest.set(CaptureRequest.CONTROL_AE_MODE,
2196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
2206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            stillRequest.set(CaptureRequest.CONTROL_AE_MODE,
2216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
2226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
2236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Camera2Focuser focuser = null;
2256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        /**
2266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim         * Step 1: trigger an auto focus run, and wait for AF locked.
2276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim         */
2286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        boolean canSetAfRegion = hasFocuser && (afRegions != null) &&
2296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                isRegionsSupportedFor3A(MAX_REGIONS_AF_INDEX);
2306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (hasFocuser) {
2316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            SimpleAutoFocusListener afListener = new SimpleAutoFocusListener();
2326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            focuser = new Camera2Focuser(mCamera, mSession, mPreviewSurface, afListener,
2336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    mStaticInfo.getCharacteristics(), mHandler);
2346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            if (canSetAfRegion) {
2356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                stillRequest.set(CaptureRequest.CONTROL_AF_REGIONS, afRegions);
2366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
2376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            focuser.startAutoFocus(afRegions);
2386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            afListener.waitForAutoFocusDone(WAIT_FOR_FOCUS_DONE_TIMEOUT_MS);
2396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
2406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        /**
2426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim         * Have to get the current AF mode to be used for other 3A repeating
2436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim         * request, otherwise, the new AF mode in AE/AWB request could be
2446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim         * different with existing repeating requests being sent by focuser,
2456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim         * then it could make AF unlocked too early. Beside that, for still
2466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim         * capture, AF mode must not be different with the one in current
2476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim         * repeating request, otherwise, the still capture itself would trigger
2486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim         * an AF mode change, and the AF lock would be lost for this capture.
2496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim         */
2506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        int currentAfMode = CaptureRequest.CONTROL_AF_MODE_OFF;
2516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (hasFocuser) {
2526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            currentAfMode = focuser.getCurrentAfMode();
2536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
2546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        previewRequest.set(CaptureRequest.CONTROL_AF_MODE, currentAfMode);
2556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        stillRequest.set(CaptureRequest.CONTROL_AF_MODE, currentAfMode);
2566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        /**
2586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim         * Step 2: AF is already locked, wait for AWB converged, then lock it.
2596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim         */
2606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        resultListener = new SimpleCaptureCallback();
2616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        boolean canSetAwbRegion =
2626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                (awbRegions != null) && isRegionsSupportedFor3A(MAX_REGIONS_AWB_INDEX);
2636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (canSetAwbRegion) {
2646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            previewRequest.set(CaptureRequest.CONTROL_AWB_REGIONS, awbRegions);
2656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            stillRequest.set(CaptureRequest.CONTROL_AWB_REGIONS, awbRegions);
2666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
2676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mSession.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
2686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
2696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            waitForResultValue(resultListener, CaptureResult.CONTROL_AWB_STATE,
2706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    CaptureResult.CONTROL_AWB_STATE_CONVERGED, NUM_RESULTS_WAIT_TIMEOUT);
2716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        } else {
2726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // LEGACY Devices don't have the AWB_STATE reported in results, so just wait
2736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            waitForSettingsApplied(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
2746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
2756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        boolean canSetAwbLock = mStaticInfo.isAwbLockSupported();
2766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (canSetAwbLock) {
2776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            previewRequest.set(CaptureRequest.CONTROL_AWB_LOCK, true);
2786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
2796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mSession.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
2806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // Validate the next result immediately for region and mode.
2816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        result = resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
2826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mCollector.expectEquals("AWB mode in result and request should be same",
2836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                previewRequest.get(CaptureRequest.CONTROL_AWB_MODE),
2846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                result.get(CaptureResult.CONTROL_AWB_MODE));
2856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (canSetAwbRegion) {
2866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            MeteringRectangle[] resultAwbRegions =
2876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    getValueNotNull(result, CaptureResult.CONTROL_AWB_REGIONS);
2886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mCollector.expectEquals("AWB regions in result and request should be same",
2896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    awbRegions, resultAwbRegions);
2906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
2916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        /**
2936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim         * Step 3: trigger an AE precapture metering sequence and wait for AE converged.
2946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim         */
2956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        resultListener = new SimpleCaptureCallback();
2966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        boolean canSetAeRegion =
2976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                (aeRegions != null) && isRegionsSupportedFor3A(MAX_REGIONS_AE_INDEX);
2986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (canSetAeRegion) {
2996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            previewRequest.set(CaptureRequest.CONTROL_AE_REGIONS, aeRegions);
3006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            stillRequest.set(CaptureRequest.CONTROL_AE_REGIONS, aeRegions);
3016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
3026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mSession.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
3036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        previewRequest.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
3046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
3056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mSession.capture(previewRequest.build(), resultListener, mHandler);
3066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (addAeTriggerCancel) {
3076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // Cancel the current precapture trigger, then send another trigger.
3086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // The camera device should behave as if the first trigger is not sent.
3096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // Wait one request to make the trigger start doing something before cancel.
3106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            waitForNumResults(resultListener, /*numResultsWait*/ 1);
3116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            previewRequest.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
3126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL);
3136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mSession.capture(previewRequest.build(), resultListener, mHandler);
3146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            waitForResultValue(resultListener, CaptureResult.CONTROL_AE_PRECAPTURE_TRIGGER,
3156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    CaptureResult.CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL,
3166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
3176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // Issue another trigger
3186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            previewRequest.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
3196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
3206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mSession.capture(previewRequest.build(), resultListener, mHandler);
3216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
3226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        waitForAeStable(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
3236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // Validate the next result immediately for region and mode.
3256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        result = resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
3266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mCollector.expectEquals("AE mode in result and request should be same",
3276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                previewRequest.get(CaptureRequest.CONTROL_AE_MODE),
3286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                result.get(CaptureResult.CONTROL_AE_MODE));
3296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (canSetAeRegion) {
3306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            MeteringRectangle[] resultAeRegions =
3316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    getValueNotNull(result, CaptureResult.CONTROL_AE_REGIONS);
3326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mCollector.expectMeteringRegionsAreSimilar(
3346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    "AE regions in result and request should be similar",
3356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    aeRegions,
3366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    resultAeRegions,
3376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    METERING_REGION_ERROR_PERCENT_DELTA);
3386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
3396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        /**
3416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim         * Step 4: take a picture when all 3A are in good state.
3426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim         */
3436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        resultListener = new SimpleCaptureCallback();
3446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        CaptureRequest request = stillRequest.build();
3456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mSession.capture(request, resultListener, mHandler);
3466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // Validate the next result immediately for region and mode.
3476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        result = resultListener.getCaptureResultForRequest(request, WAIT_FOR_RESULT_TIMEOUT_MS);
3486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mCollector.expectEquals("AF mode in result and request should be same",
3496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                stillRequest.get(CaptureRequest.CONTROL_AF_MODE),
3506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                result.get(CaptureResult.CONTROL_AF_MODE));
3516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (canSetAfRegion) {
3526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            MeteringRectangle[] resultAfRegions =
3536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    getValueNotNull(result, CaptureResult.CONTROL_AF_REGIONS);
3546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mCollector.expectMeteringRegionsAreSimilar(
3556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    "AF regions in result and request should be similar",
3566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    afRegions,
3576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    resultAfRegions,
3586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    METERING_REGION_ERROR_PERCENT_DELTA);
3596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
3606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (hasFocuser) {
3626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // Unlock auto focus.
3636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            focuser.cancelAutoFocus();
3646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
3656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // validate image
3676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Image image = imageListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
3686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        validateJpegCapture(image, maxStillSz);
3696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // Free image resources
3716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        image.close();
3726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        stopPreview();
3746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
3756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private void fullRawCaptureTestByCamera() throws Exception {
3776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Size maxPreviewSz = mOrderedPreviewSizes.get(0);
3786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Size maxStillSz = mOrderedStillSizes.get(0);
3796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
3816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        SimpleImageReaderListener jpegListener = new SimpleImageReaderListener();
3826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        SimpleImageReaderListener rawListener = new SimpleImageReaderListener();
3836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Size size = mStaticInfo.getRawDimensChecked();
3856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (VERBOSE) {
3876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Log.v(TAG, "Testing multi capture with size " + size.toString()
3886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    + ", preview size " + maxPreviewSz);
3896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
3906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // Prepare raw capture and start preview.
3926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        CaptureRequest.Builder previewBuilder =
3936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
3946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        CaptureRequest.Builder multiBuilder =
3956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
3966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        ImageReader rawReader = null;
3986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        ImageReader jpegReader = null;
3996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        try {
4016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // Create ImageReaders.
4026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            rawReader = makeImageReader(size,
4036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    ImageFormat.RAW_SENSOR, MAX_READER_IMAGES, rawListener, mHandler);
4046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            jpegReader = makeImageReader(maxStillSz,
4056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    ImageFormat.JPEG, MAX_READER_IMAGES, jpegListener, mHandler);
4066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            updatePreviewSurface(maxPreviewSz);
4076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // Configure output streams with preview and jpeg streams.
4096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            List<Surface> outputSurfaces = new ArrayList<Surface>();
4106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            outputSurfaces.add(rawReader.getSurface());
4116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            outputSurfaces.add(jpegReader.getSurface());
4126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            outputSurfaces.add(mPreviewSurface);
4136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mSessionListener = new BlockingSessionCallback();
4146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mSession = configureCameraSession(mCamera, outputSurfaces,
4156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    mSessionListener, mHandler);
4166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // Configure the requests.
4186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            previewBuilder.addTarget(mPreviewSurface);
4196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            multiBuilder.addTarget(mPreviewSurface);
4206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            multiBuilder.addTarget(rawReader.getSurface());
4216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            multiBuilder.addTarget(jpegReader.getSurface());
4226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // Start preview.
4246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mSession.setRepeatingRequest(previewBuilder.build(), null, mHandler);
4256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // Poor man's 3A, wait 2 seconds for AE/AF (if any) to settle.
4276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // TODO: Do proper 3A trigger and lock (see testTakePictureTest).
4286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Thread.sleep(3000);
4296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            multiBuilder.set(CaptureRequest.STATISTICS_LENS_SHADING_MAP_MODE,
4316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    CaptureRequest.STATISTICS_LENS_SHADING_MAP_MODE_ON);
4326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            CaptureRequest multiRequest = multiBuilder.build();
4336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mSession.capture(multiRequest, resultListener, mHandler);
4356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            CaptureResult result = resultListener.getCaptureResultForRequest(multiRequest,
4376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    NUM_RESULTS_WAIT_TIMEOUT);
4386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Image jpegImage = jpegListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
4396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            basicValidateJpegImage(jpegImage, maxStillSz);
4406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Image rawImage = rawListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
4416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            validateRaw16Image(rawImage, size);
4426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            verifyRawCaptureResult(multiRequest, result);
4436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
4466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            try (DngCreator dngCreator = new DngCreator(mStaticInfo.getCharacteristics(), result)) {
4476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                dngCreator.writeImage(outputStream, rawImage);
4486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
4496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            if (DEBUG) {
4516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                byte[] rawBuffer = outputStream.toByteArray();
4526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                String rawFileName = DEBUG_FILE_NAME_BASE + "/raw16_" + TAG + size.toString() +
4536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        "_cam_" + mCamera.getId() + ".dng";
4546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                Log.d(TAG, "Dump raw file into " + rawFileName);
4556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                dumpFile(rawFileName, rawBuffer);
4566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                byte[] jpegBuffer = getDataFromImage(jpegImage);
4586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                String jpegFileName = DEBUG_FILE_NAME_BASE + "/jpeg_" + TAG + size.toString() +
4596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        "_cam_" + mCamera.getId() + ".jpg";
4606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                Log.d(TAG, "Dump jpeg file into " + rawFileName);
4616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                dumpFile(jpegFileName, jpegBuffer);
4626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
4636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            stopPreview();
4656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        } finally {
4666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            CameraTestUtils.closeImageReader(rawReader);
4676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            CameraTestUtils.closeImageReader(jpegReader);
4686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            rawReader = null;
4696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            jpegReader = null;
4706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
4716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
4726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
4746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Validate that raw {@link CaptureResult}.
4756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
4766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param rawRequest a {@link CaptureRequest} use to capture a RAW16 image.
4776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param rawResult the {@link CaptureResult} corresponding to the given request.
4786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
4796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private void verifyRawCaptureResult(CaptureRequest rawRequest, CaptureResult rawResult) {
4806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        assertNotNull(rawRequest);
4816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        assertNotNull(rawResult);
4826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Rational[] empty = new Rational[] { Rational.ZERO, Rational.ZERO, Rational.ZERO};
4846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Rational[] neutralColorPoint = mCollector.expectKeyValueNotNull("NeutralColorPoint",
4856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                rawResult, CaptureResult.SENSOR_NEUTRAL_COLOR_POINT);
4866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (neutralColorPoint != null) {
4876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mCollector.expectEquals("NeutralColorPoint length", empty.length,
4886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    neutralColorPoint.length);
4896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mCollector.expectNotEquals("NeutralColorPoint cannot be all zeroes, ", empty,
4906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    neutralColorPoint);
4916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mCollector.expectValuesGreaterOrEqual("NeutralColorPoint", neutralColorPoint,
4926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    Rational.ZERO);
4936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
4946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        mCollector.expectKeyValueGreaterOrEqual(rawResult, CaptureResult.SENSOR_GREEN_SPLIT, 0.0f);
4966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
4976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Pair<Double, Double>[] noiseProfile = mCollector.expectKeyValueNotNull("NoiseProfile",
4986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                rawResult, CaptureResult.SENSOR_NOISE_PROFILE);
4996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (noiseProfile != null) {
5006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mCollector.expectEquals("NoiseProfile length", noiseProfile.length,
5016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                /*Num CFA channels*/4);
5026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            for (Pair<Double, Double> p : noiseProfile) {
5036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mCollector.expectTrue("NoiseProfile coefficients " + p +
5046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        " must have: S > 0, O >= 0", p.first > 0 && p.second >= 0);
5056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
5066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
5076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Integer hotPixelMode = mCollector.expectKeyValueNotNull("HotPixelMode", rawResult,
5096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                CaptureResult.HOT_PIXEL_MODE);
5106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Boolean hotPixelMapMode = mCollector.expectKeyValueNotNull("HotPixelMapMode", rawResult,
5116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                CaptureResult.STATISTICS_HOT_PIXEL_MAP_MODE);
5126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Point[] hotPixelMap = rawResult.get(CaptureResult.STATISTICS_HOT_PIXEL_MAP);
5136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Size pixelArraySize = mStaticInfo.getPixelArraySizeChecked();
5156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        boolean[] availableHotPixelMapModes = mStaticInfo.getValueFromKeyNonNull(
5166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        CameraCharacteristics.STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES);
5176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (hotPixelMode != null) {
5196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Integer requestMode = mCollector.expectKeyValueNotNull(rawRequest,
5206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    CaptureRequest.HOT_PIXEL_MODE);
5216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            if (requestMode != null) {
5226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mCollector.expectKeyValueEquals(rawResult, CaptureResult.HOT_PIXEL_MODE,
5236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        requestMode);
5246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
5256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
5266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (hotPixelMapMode != null) {
5286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Boolean requestMapMode = mCollector.expectKeyValueNotNull(rawRequest,
5296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    CaptureRequest.STATISTICS_HOT_PIXEL_MAP_MODE);
5306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            if (requestMapMode != null) {
5316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mCollector.expectKeyValueEquals(rawResult,
5326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        CaptureResult.STATISTICS_HOT_PIXEL_MAP_MODE, requestMapMode);
5336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
5346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            if (!hotPixelMapMode) {
5366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mCollector.expectTrue("HotPixelMap must be empty", hotPixelMap == null ||
5376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        hotPixelMap.length == 0);
5386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            } else {
5396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mCollector.expectTrue("HotPixelMap must not be empty", hotPixelMap != null);
5406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                mCollector.expectNotNull("AvailableHotPixelMapModes must not be null",
5416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        availableHotPixelMapModes);
5426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                if (availableHotPixelMapModes != null) {
5436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    mCollector.expectContains("HotPixelMapMode", availableHotPixelMapModes, true);
5446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
5456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                int height = pixelArraySize.getHeight();
5476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                int width = pixelArraySize.getWidth();
5486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                for (Point p : hotPixelMap) {
5496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    mCollector.expectTrue("Hotpixel " + p + " must be in pixelArray " +
5506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                            pixelArraySize, p.x >= 0 && p.x < width && p.y >= 0 && p.y < height);
5516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
5526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
5536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
5546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // TODO: profileHueSatMap, and profileToneCurve aren't supported yet.
5556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
5576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    //----------------------------------------------------------------
5596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    //---------Below are common functions for all tests.--------------
5606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    //----------------------------------------------------------------
5616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
5626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Validate standard raw (RAW16) capture image.
5636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
5646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param image The raw16 format image captured
5656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param rawSize The expected raw size
5666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
5676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static void validateRaw16Image(Image image, Size rawSize) {
5686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        CameraTestUtils.validateImage(image, rawSize.getWidth(), rawSize.getHeight(),
5696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                ImageFormat.RAW_SENSOR, /*filePath*/null);
5706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
5716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /**
5736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Validate JPEG capture image object sanity and test.
5746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * <p>
5756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * In addition to image object sanity, this function also does the decoding
5766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * test, which is slower.
5776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * </p>
5786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
5796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param image The JPEG image to be verified.
5806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * @param jpegSize The JPEG capture size to be verified against.
5816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
5826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static void validateJpegCapture(Image image, Size jpegSize) {
5836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        CameraTestUtils.validateImage(image, jpegSize.getWidth(), jpegSize.getHeight(),
5846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                ImageFormat.JPEG, /*filePath*/null);
5856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
5866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static class SimpleAutoFocusListener implements Camera2Focuser.AutoFocusListener {
5886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        final ConditionVariable focusDone = new ConditionVariable();
5896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        @Override
5906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        public void onAutoFocusLocked(boolean success) {
5916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            focusDone.open();
5926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
5936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
5946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        public void waitForAutoFocusDone(long timeoutMs) {
5956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            if (focusDone.block(timeoutMs)) {
5966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                focusDone.close();
5976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            } else {
5986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                throw new TimeoutRuntimeException("Wait for auto focus done timed out after "
5996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        + timeoutMs + "ms");
6006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
6016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
6026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
6036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
6046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private boolean isRegionsSupportedFor3A(int index) {
6056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        int maxRegions = 0;
6066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        switch (index) {
6076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            case MAX_REGIONS_AE_INDEX:
6086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                maxRegions = mStaticInfo.getAeMaxRegionsChecked();
6096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                break;
6106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            case MAX_REGIONS_AWB_INDEX:
6116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                maxRegions = mStaticInfo.getAwbMaxRegionsChecked();
6126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                break;
6136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            case  MAX_REGIONS_AF_INDEX:
6146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                maxRegions = mStaticInfo.getAfMaxRegionsChecked();
6156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                break;
6166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            default:
6176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                throw new IllegalArgumentException("Unknown algorithm index");
6186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
6196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        boolean isRegionsSupported = maxRegions > 0;
6206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (index == MAX_REGIONS_AF_INDEX && isRegionsSupported) {
6216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            mCollector.expectTrue(
6226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    "Device reports non-zero max AF region count for a camera without focuser!",
6236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    mStaticInfo.hasFocuser());
6246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            isRegionsSupported = isRegionsSupported && mStaticInfo.hasFocuser();
6256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
6266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
6276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return isRegionsSupported;
6286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
6296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim}
630