/*
 * Copyright 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.hardware.camera2.cts;

import static com.android.ex.camera2.blocking.BlockingStateCallback.*;

import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.PointF;
import android.graphics.Rect;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CaptureFailure;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.cts.helpers.CameraUtils;
import android.util.Size;
import android.hardware.camera2.params.MeteringRectangle;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.Image;
import android.media.ImageReader;
import android.media.Image.Plane;
import android.os.Handler;
import android.util.Log;
import android.view.Surface;

import com.android.ex.camera2.blocking.BlockingCameraManager;
import com.android.ex.camera2.blocking.BlockingCameraManager.BlockingOpenException;
import com.android.ex.camera2.blocking.BlockingSessionCallback;
import com.android.ex.camera2.blocking.BlockingStateCallback;
import com.android.ex.camera2.exceptions.TimeoutRuntimeException;

import junit.framework.Assert;

import org.mockito.Mockito;

import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Array;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * A package private utility class for wrapping up the camera2 cts test common utility functions
 */
public class CameraTestUtils extends Assert {
    private static final String TAG = "CameraTestUtils";
    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
    public static final Size SIZE_BOUND_1080P = new Size(1920, 1088);
    public static final Size SIZE_BOUND_2160P = new Size(3840, 2160);
    // Only test the preview size that is no larger than 1080p.
    public static final Size PREVIEW_SIZE_BOUND = SIZE_BOUND_1080P;
    // Default timeouts for reaching various states
    public static final int CAMERA_OPEN_TIMEOUT_MS = 3000;
    public static final int CAMERA_CLOSE_TIMEOUT_MS = 3000;
    public static final int CAMERA_IDLE_TIMEOUT_MS = 3000;
    public static final int CAMERA_ACTIVE_TIMEOUT_MS = 1000;
    public static final int CAMERA_BUSY_TIMEOUT_MS = 1000;
    public static final int CAMERA_UNCONFIGURED_TIMEOUT_MS = 1000;
    public static final int CAMERA_CONFIGURE_TIMEOUT_MS = 3000;
    public static final int CAPTURE_RESULT_TIMEOUT_MS = 3000;
    public static final int CAPTURE_IMAGE_TIMEOUT_MS = 3000;

    public static final int SESSION_CONFIGURE_TIMEOUT_MS = 3000;
    public static final int SESSION_CLOSE_TIMEOUT_MS = 3000;
    public static final int SESSION_READY_TIMEOUT_MS = 3000;
    public static final int SESSION_ACTIVE_TIMEOUT_MS = 1000;

    public static final int MAX_READER_IMAGES = 5;

    /**
     * Create an {@link android.media.ImageReader} object and get the surface.
     *
     * @param size The size of this ImageReader to be created.
     * @param format The format of this ImageReader to be created
     * @param maxNumImages The max number of images that can be acquired simultaneously.
     * @param listener The listener used by this ImageReader to notify callbacks.
     * @param handler The handler to use for any listener callbacks.
     */
    public static ImageReader makeImageReader(Size size, int format, int maxNumImages,
            ImageReader.OnImageAvailableListener listener, Handler handler) {
        ImageReader reader =  ImageReader.newInstance(size.getWidth(), size.getHeight(), format,
                maxNumImages);
        reader.setOnImageAvailableListener(listener, handler);
        if (VERBOSE) Log.v(TAG, "Created ImageReader size " + size);
        return reader;
    }

    /**
     * Close pending images and clean up an {@link android.media.ImageReader} object.
     * @param reader an {@link android.media.ImageReader} to close.
     */
    public static void closeImageReader(ImageReader reader) {
        if (reader != null) {
            reader.close();
        }
    }

    /**
     * Dummy listener that release the image immediately once it is available.
     *
     * <p>
     * It can be used for the case where we don't care the image data at all.
     * </p>
     */
    public static class ImageDropperListener implements ImageReader.OnImageAvailableListener {
        @Override
        public void onImageAvailable(ImageReader reader) {
            Image image = null;
            try {
                image = reader.acquireNextImage();
            } finally {
                if (image != null) {
                    image.close();
                }
            }
        }
    }

    /**
     * Image listener that release the image immediately after validating the image
     */
    public static class ImageVerifierListener implements ImageReader.OnImageAvailableListener {
        private Size mSize;
        private int mFormat;

        public ImageVerifierListener(Size sz, int format) {
            mSize = sz;
            mFormat = format;
        }

        @Override
        public void onImageAvailable(ImageReader reader) {
            Image image = null;
            try {
                image = reader.acquireNextImage();
            } finally {
                if (image != null) {
                    validateImage(image, mSize.getWidth(), mSize.getHeight(), mFormat, null);
                    image.close();
                }
            }
        }
    }

    public static class SimpleImageReaderListener
            implements ImageReader.OnImageAvailableListener {
        private final LinkedBlockingQueue<Image> mQueue =
                new LinkedBlockingQueue<Image>();

        @Override
        public void onImageAvailable(ImageReader reader) {
            try {
                mQueue.put(reader.acquireNextImage());
            } catch (InterruptedException e) {
                throw new UnsupportedOperationException(
                        "Can't handle InterruptedException in onImageAvailable");
            }
        }

        /**
         * Get an image from the image reader.
         *
         * @param timeout Timeout value for the wait.
         * @return The image from the image reader.
         */
        public Image getImage(long timeout) throws InterruptedException {
            Image image = mQueue.poll(timeout, TimeUnit.MILLISECONDS);
            assertNotNull("Wait for an image timed out in " + timeout + "ms", image);
            return image;
        }
    }

    public static class SimpleCaptureCallback extends CameraCaptureSession.CaptureCallback {
        private final LinkedBlockingQueue<CaptureResult> mQueue =
                new LinkedBlockingQueue<CaptureResult>();

        @Override
        public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request,
                long timestamp, long frameNumber)
        {
        }

        @Override
        public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
                TotalCaptureResult result) {
            try {
                mQueue.put(result);
            } catch (InterruptedException e) {
                throw new UnsupportedOperationException(
                        "Can't handle InterruptedException in onCaptureCompleted");
            }
        }

        @Override
        public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request,
                CaptureFailure failure) {
        }

        @Override
        public void onCaptureSequenceCompleted(CameraCaptureSession session, int sequenceId,
                long frameNumber) {
        }

        public CaptureResult getCaptureResult(long timeout) {
            try {
                CaptureResult result = mQueue.poll(timeout, TimeUnit.MILLISECONDS);
                assertNotNull("Wait for a capture result timed out in " + timeout + "ms", result);
                return result;
            } catch (InterruptedException e) {
                throw new UnsupportedOperationException("Unhandled interrupted exception", e);
            }
        }

        /**
         * Get the {@link #CaptureResult capture result} for a given
         * {@link #CaptureRequest capture request}.
         *
         * @param myRequest The {@link #CaptureRequest capture request} whose
         *            corresponding {@link #CaptureResult capture result} was
         *            being waited for
         * @param numResultsWait Number of frames to wait for the capture result
         *            before timeout.
         * @throws TimeoutRuntimeException If more than numResultsWait results are
         *            seen before the result matching myRequest arrives, or each
         *            individual wait for result times out after
         *            {@value #CAPTURE_RESULT_TIMEOUT_MS}ms.
         */
        public CaptureResult getCaptureResultForRequest(CaptureRequest myRequest,
                int numResultsWait) {
            if (numResultsWait < 0) {
                throw new IllegalArgumentException("numResultsWait must be no less than 0");
            }

            CaptureResult result;
            int i = 0;
            do {
                result = getCaptureResult(CAPTURE_RESULT_TIMEOUT_MS);
                if (result.getRequest().equals(myRequest)) {
                    return result;
                }
            } while (i++ < numResultsWait);

            throw new TimeoutRuntimeException("Unable to get the expected capture result after "
                    + "waiting for " + numResultsWait + " results");
        }

        public boolean hasMoreResults()
        {
            return mQueue.isEmpty();
        }
    }

    /**
     * Block until the camera is opened.
     *
     * <p>Don't use this to test #onDisconnected/#onError since this will throw
     * an AssertionError if it fails to open the camera device.</p>
     *
     * @return CameraDevice opened camera device
     *
     * @throws IllegalArgumentException
     *            If the handler is null, or if the handler's looper is current.
     * @throws CameraAccessException
     *            If open fails immediately.
     * @throws BlockingOpenException
     *            If open fails after blocking for some amount of time.
     * @throws TimeoutRuntimeException
     *            If opening times out. Typically unrecoverable.
     */
    public static CameraDevice openCamera(CameraManager manager, String cameraId,
            CameraDevice.StateCallback listener, Handler handler) throws CameraAccessException,
            BlockingOpenException {

        /**
         * Although camera2 API allows 'null' Handler (it will just use the current
         * thread's Looper), this is not what we want for CTS.
         *
         * In CTS the default looper is used only to process events in between test runs,
         * so anything sent there would not be executed inside a test and the test would fail.
         *
         * In this case, BlockingCameraManager#openCamera performs the check for us.
         */
        return (new BlockingCameraManager(manager)).openCamera(cameraId, listener, handler);
    }


    /**
     * Block until the camera is opened.
     *
     * <p>Don't use this to test #onDisconnected/#onError since this will throw
     * an AssertionError if it fails to open the camera device.</p>
     *
     * @throws IllegalArgumentException
     *            If the handler is null, or if the handler's looper is current.
     * @throws CameraAccessException
     *            If open fails immediately.
     * @throws BlockingOpenException
     *            If open fails after blocking for some amount of time.
     * @throws TimeoutRuntimeException
     *            If opening times out. Typically unrecoverable.
     */
    public static CameraDevice openCamera(CameraManager manager, String cameraId, Handler handler)
            throws CameraAccessException,
            BlockingOpenException {
        return openCamera(manager, cameraId, /*listener*/null, handler);
    }

    /**
     * Configure a new camera session with output surfaces.
     *
     * @param camera The CameraDevice to be configured.
     * @param outputSurfaces The surface list that used for camera output.
     * @param listener The callback CameraDevice will notify when capture results are available.
     */
    public static CameraCaptureSession configureCameraSession(CameraDevice camera,
            List<Surface> outputSurfaces,
            CameraCaptureSession.StateCallback listener, Handler handler)
            throws CameraAccessException {
        BlockingSessionCallback sessionListener = new BlockingSessionCallback(listener);
        camera.createCaptureSession(outputSurfaces, sessionListener, handler);

        return sessionListener.waitAndGetSession(SESSION_CONFIGURE_TIMEOUT_MS);
    }

    public static <T> void assertArrayNotEmpty(T arr, String message) {
        assertTrue(message, arr != null && Array.getLength(arr) > 0);
    }

    /**
     * Check if the format is a legal YUV format camera supported.
     */
    public static void checkYuvFormat(int format) {
        if ((format != ImageFormat.YUV_420_888) &&
                (format != ImageFormat.NV21) &&
                (format != ImageFormat.YV12)) {
            fail("Wrong formats: " + format);
        }
    }

    /**
     * Check if image size and format match given size and format.
     */
    public static void checkImage(Image image, int width, int height, int format) {
        assertNotNull("Input image is invalid", image);
        assertEquals("Format doesn't match", format, image.getFormat());
        assertEquals("Width doesn't match", width, image.getWidth());
        assertEquals("Height doesn't match", height, image.getHeight());
    }

    /**
     * <p>Read data from all planes of an Image into a contiguous unpadded, unpacked
     * 1-D linear byte array, such that it can be write into disk, or accessed by
     * software conveniently. It supports YUV_420_888/NV21/YV12 and JPEG input
     * Image format.</p>
     *
     * <p>For YUV_420_888/NV21/YV12/Y8/Y16, it returns a byte array that contains
     * the Y plane data first, followed by U(Cb), V(Cr) planes if there is any
     * (xstride = width, ystride = height for chroma and luma components).</p>
     *
     * <p>For JPEG, it returns a 1-D byte array contains a complete JPEG image.</p>
     */
    public static byte[] getDataFromImage(Image image) {
        assertNotNull("Invalid image:", image);
        int format = image.getFormat();
        int width = image.getWidth();
        int height = image.getHeight();
        int rowStride, pixelStride;
        byte[] data = null;

        // Read image data
        Plane[] planes = image.getPlanes();
        assertTrue("Fail to get image planes", planes != null && planes.length > 0);

        // Check image validity
        checkAndroidImageFormat(image);

        ByteBuffer buffer = null;
        // JPEG doesn't have pixelstride and rowstride, treat it as 1D buffer.
        if (format == ImageFormat.JPEG) {
            buffer = planes[0].getBuffer();
            assertNotNull("Fail to get jpeg ByteBuffer", buffer);
            data = new byte[buffer.remaining()];
            buffer.get(data);
            buffer.rewind();
            return data;
        }

        int offset = 0;
        data = new byte[width * height * ImageFormat.getBitsPerPixel(format) / 8];
        byte[] rowData = new byte[planes[0].getRowStride()];
        if(VERBOSE) Log.v(TAG, "get data from " + planes.length + " planes");
        for (int i = 0; i < planes.length; i++) {
            buffer = planes[i].getBuffer();
            assertNotNull("Fail to get bytebuffer from plane", buffer);
            rowStride = planes[i].getRowStride();
            pixelStride = planes[i].getPixelStride();
            assertTrue("pixel stride " + pixelStride + " is invalid", pixelStride > 0);
            if (VERBOSE) {
                Log.v(TAG, "pixelStride " + pixelStride);
                Log.v(TAG, "rowStride " + rowStride);
                Log.v(TAG, "width " + width);
                Log.v(TAG, "height " + height);
            }
            // For multi-planar yuv images, assuming yuv420 with 2x2 chroma subsampling.
            int w = (i == 0) ? width : width / 2;
            int h = (i == 0) ? height : height / 2;
            assertTrue("rowStride " + rowStride + " should be >= width " + w , rowStride >= w);
            for (int row = 0; row < h; row++) {
                int bytesPerPixel = ImageFormat.getBitsPerPixel(format) / 8;
                if (pixelStride == bytesPerPixel) {
                    // Special case: optimized read of the entire row
                    int length = w * bytesPerPixel;
                    buffer.get(data, offset, length);
                    // Advance buffer the remainder of the row stride
                    buffer.position(buffer.position() + rowStride - length);
                    offset += length;
                } else {
                    // Generic case: should work for any pixelStride but slower.
                    // Use intermediate buffer to avoid read byte-by-byte from
                    // DirectByteBuffer, which is very bad for performance
                    buffer.get(rowData, 0, rowStride);
                    for (int col = 0; col < w; col++) {
                        data[offset++] = rowData[col * pixelStride];
                    }
                }
            }
            if (VERBOSE) Log.v(TAG, "Finished reading data from plane " + i);
            buffer.rewind();
        }
        return data;
    }

    /**
     * <p>Check android image format validity for an image, only support below formats:</p>
     *
     * <p>YUV_420_888/NV21/YV12, can add more for future</p>
     */
    public static void checkAndroidImageFormat(Image image) {
        int format = image.getFormat();
        Plane[] planes = image.getPlanes();
        switch (format) {
            case ImageFormat.YUV_420_888:
            case ImageFormat.NV21:
            case ImageFormat.YV12:
                assertEquals("YUV420 format Images should have 3 planes", 3, planes.length);
                break;
            case ImageFormat.JPEG:
            case ImageFormat.RAW_SENSOR:
                assertEquals("Jpeg Image should have one plane", 1, planes.length);
                break;
            default:
                fail("Unsupported Image Format: " + format);
        }
    }

    public static void dumpFile(String fileName, byte[] data) {
        FileOutputStream outStream;
        try {
            Log.v(TAG, "output will be saved as " + fileName);
            outStream = new FileOutputStream(fileName);
        } catch (IOException ioe) {
            throw new RuntimeException("Unable to create debug output file " + fileName, ioe);
        }

        try {
            outStream.write(data);
            outStream.close();
        } catch (IOException ioe) {
            throw new RuntimeException("failed writing data to file " + fileName, ioe);
        }
    }

    /**
     * Get the available output sizes for the user-defined {@code format}.
     *
     * <p>Note that implementation-defined/hidden formats are not supported.</p>
     */
    public static Size[] getSupportedSizeForFormat(int format, String cameraId,
            CameraManager cameraManager) throws CameraAccessException {
        CameraCharacteristics properties = cameraManager.getCameraCharacteristics(cameraId);
        assertNotNull("Can't get camera characteristics!", properties);
        if (VERBOSE) {
            Log.v(TAG, "get camera characteristics for camera: " + cameraId);
        }
        StreamConfigurationMap configMap =
                properties.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
        Size[] availableSizes = configMap.getOutputSizes(format);
        assertArrayNotEmpty(availableSizes, "availableSizes should not be empty");
        if (VERBOSE) Log.v(TAG, "Supported sizes are: " + Arrays.deepToString(availableSizes));
        return availableSizes;
    }

    /**
     * Size comparator that compares the number of pixels it covers.
     *
     * <p>If two the areas of two sizes are same, compare the widths.</p>
     */
    public static class SizeComparator implements Comparator<Size> {
        @Override
        public int compare(Size lhs, Size rhs) {
            return CameraUtils
                    .compareSizes(lhs.getWidth(), lhs.getHeight(), rhs.getWidth(), rhs.getHeight());
        }
    }

    /**
     * Get sorted size list in descending order. Remove the sizes larger than
     * the bound. If the bound is null, don't do the size bound filtering.
     */
    static public List<Size> getSupportedPreviewSizes(String cameraId,
            CameraManager cameraManager, Size bound) throws CameraAccessException {
        return getSortedSizesForFormat(cameraId, cameraManager, ImageFormat.YUV_420_888, bound);
    }

    /**
     * Get a sorted list of sizes from a given size list.
     *
     * <p>
     * The size is compare by area it covers, if the areas are same, then
     * compare the widths.
     * </p>
     *
     * @param sizeList The input size list to be sorted
     * @param ascending True if the order is ascending, otherwise descending order
     * @return The ordered list of sizes
     */
    static public List<Size> getAscendingOrderSizes(final List<Size> sizeList, boolean ascending) {
        if (sizeList == null) {
            throw new IllegalArgumentException("sizeList shouldn't be null");
        }

        Comparator<Size> comparator = new SizeComparator();
        List<Size> sortedSizes = new ArrayList<Size>();
        sortedSizes.addAll(sizeList);
        Collections.sort(sortedSizes, comparator);
        if (!ascending) {
            Collections.reverse(sortedSizes);
        }

        return sortedSizes;
    }

    /**
     * Get sorted (descending order) size list for given format. Remove the sizes larger than
     * the bound. If the bound is null, don't do the size bound filtering.
     */
    static private List<Size> getSortedSizesForFormat(String cameraId,
            CameraManager cameraManager, int format, Size bound) throws CameraAccessException {
        Comparator<Size> comparator = new SizeComparator();
        Size[] sizes = getSupportedSizeForFormat(format, cameraId, cameraManager);
        List<Size> sortedSizes = null;
        if (bound != null) {
            sortedSizes = new ArrayList<Size>(/*capacity*/1);
            for (Size sz : sizes) {
                if (comparator.compare(sz, bound) <= 0) {
                    sortedSizes.add(sz);
                }
            }
        } else {
            sortedSizes = Arrays.asList(sizes);
        }
        assertTrue("Supported size list should have at least one element",
                sortedSizes.size() > 0);

        Collections.sort(sortedSizes, comparator);
        // Make it in descending order.
        Collections.reverse(sortedSizes);
        return sortedSizes;
    }

    /**
     * Get supported video size list for a given camera device.
     *
     * <p>
     * Filter out the sizes that are larger than the bound. If the bound is
     * null, don't do the size bound filtering.
     * </p>
     */
    static public List<Size> getSupportedVideoSizes(String cameraId,
            CameraManager cameraManager, Size bound) throws CameraAccessException {
        return getSortedSizesForFormat(cameraId, cameraManager, ImageFormat.YUV_420_888, bound);
    }

    /**
     * Get supported video size list (descending order) for a given camera device.
     *
     * <p>
     * Filter out the sizes that are larger than the bound. If the bound is
     * null, don't do the size bound filtering.
     * </p>
     */
    static public List<Size> getSupportedStillSizes(String cameraId,
            CameraManager cameraManager, Size bound) throws CameraAccessException {
        return getSortedSizesForFormat(cameraId, cameraManager, ImageFormat.JPEG, bound);
    }

    static public Size getMinPreviewSize(String cameraId, CameraManager cameraManager)
            throws CameraAccessException {
        List<Size> sizes = getSupportedPreviewSizes(cameraId, cameraManager, null);
        return sizes.get(sizes.size() - 1);
    }

    /**
     * Get max supported preview size for a camera device.
     */
    static public Size getMaxPreviewSize(String cameraId, CameraManager cameraManager)
            throws CameraAccessException {
        return getMaxPreviewSize(cameraId, cameraManager, /*bound*/null);
    }

    /**
     * Get max preview size for a camera device in the supported sizes that are no larger
     * than the bound.
     */
    static public Size getMaxPreviewSize(String cameraId, CameraManager cameraManager, Size bound)
            throws CameraAccessException {
        List<Size> sizes = getSupportedPreviewSizes(cameraId, cameraManager, bound);
        return sizes.get(0);
    }

    /**
     * Get the largest size by area.
     *
     * @param sizes an array of sizes, must have at least 1 element
     *
     * @return Largest Size
     *
     * @throws IllegalArgumentException if sizes was null or had 0 elements
     */
    public static Size getMaxSize(Size[] sizes) {
        if (sizes == null || sizes.length == 0) {
            throw new IllegalArgumentException("sizes was empty");
        }

        Size sz = sizes[0];
        for (Size size : sizes) {
            if (size.getWidth() * size.getHeight() > sz.getWidth() * sz.getHeight()) {
                sz = size;
            }
        }

        return sz;
    }

    /**
     * Get object array from byte array.
     *
     * @param array Input byte array to be converted
     * @return Byte object array converted from input byte array
     */
    public static Byte[] toObject(byte[] array) {
        return convertPrimitiveArrayToObjectArray(array, Byte.class);
    }

    /**
     * Get object array from int array.
     *
     * @param array Input int array to be converted
     * @return Integer object array converted from input int array
     */
    public static Integer[] toObject(int[] array) {
        return convertPrimitiveArrayToObjectArray(array, Integer.class);
    }

    /**
     * Get object array from float array.
     *
     * @param array Input float array to be converted
     * @return Float object array converted from input float array
     */
    public static Float[] toObject(float[] array) {
        return convertPrimitiveArrayToObjectArray(array, Float.class);
    }

    /**
     * Get object array from double array.
     *
     * @param array Input double array to be converted
     * @return Double object array converted from input double array
     */
    public static Double[] toObject(double[] array) {
        return convertPrimitiveArrayToObjectArray(array, Double.class);
    }

    /**
     * Convert a primitive input array into its object array version (e.g. from int[] to Integer[]).
     *
     * @param array Input array object
     * @param wrapperClass The boxed class it converts to
     * @return Boxed version of primitive array
     */
    private static <T> T[] convertPrimitiveArrayToObjectArray(final Object array,
            final Class<T> wrapperClass) {
        // getLength does the null check and isArray check already.
        int arrayLength = Array.getLength(array);
        if (arrayLength == 0) {
            throw new IllegalArgumentException("Input array shouldn't be empty");
        }

        @SuppressWarnings("unchecked")
        final T[] result = (T[]) Array.newInstance(wrapperClass, arrayLength);
        for (int i = 0; i < arrayLength; i++) {
            Array.set(result, i, Array.get(array, i));
        }
        return result;
    }

    /**
     * Validate image based on format and size.
     * <p>
     * Only RAW_SENSOR, YUV420_888 and JPEG formats are supported. Calling this
     * method with other formats will cause a UnsupportedOperationException.
     * </p>
     *
     * @param image The image to be validated.
     * @param width The image width.
     * @param height The image height.
     * @param format The image format.
     * @param filePath The debug dump file path, null if don't want to dump to
     *            file.
     * @throws UnsupportedOperationException if calling with format other than
     *             RAW_SENSOR, YUV420_888 or JPEG.
     */
    public static void validateImage(Image image, int width, int height, int format,
            String filePath) {
        checkImage(image, width, height, format);

        /**
         * TODO: validate timestamp:
         * 1. capture result timestamp against the image timestamp (need
         * consider frame drops)
         * 2. timestamps should be monotonically increasing for different requests
         */
        if(VERBOSE) Log.v(TAG, "validating Image");
        byte[] data = getDataFromImage(image);
        assertTrue("Invalid image data", data != null && data.length > 0);

        switch (format) {
            case ImageFormat.JPEG:
                validateJpegData(data, width, height, filePath);
                break;
            case ImageFormat.YUV_420_888:
                validateYuvData(data, width, height, format, image.getTimestamp(), filePath);
                break;
            case ImageFormat.RAW_SENSOR:
                validateRaw16Data(data, width, height, format, image.getTimestamp(), filePath);
                break;
            default:
                throw new UnsupportedOperationException("Unsupported format for validation: "
                        + format);
        }
    }

    /**
     * Provide a mock for {@link CameraDevice.StateCallback}.
     *
     * <p>Only useful because mockito can't mock {@link CameraDevice.StateCallback} which is an
     * abstract class.</p>
     *
     * <p>
     * Use this instead of other classes when needing to verify interactions, since
     * trying to spy on {@link BlockingStateCallback} (or others) will cause unnecessary extra
     * interactions which will cause false test failures.
     * </p>
     *
     */
    public static class MockStateCallback extends CameraDevice.StateCallback {

        @Override
        public void onOpened(CameraDevice camera) {
        }

        @Override
        public void onDisconnected(CameraDevice camera) {
        }

        @Override
        public void onError(CameraDevice camera, int error) {
        }

        private MockStateCallback() {}

        /**
         * Create a Mockito-ready mocked StateCallback.
         */
        public static MockStateCallback mock() {
            return Mockito.spy(new MockStateCallback());
        }
    }

    private static void validateJpegData(byte[] jpegData, int width, int height, String filePath) {
        BitmapFactory.Options bmpOptions = new BitmapFactory.Options();
        // DecodeBound mode: only parse the frame header to get width/height.
        // it doesn't decode the pixel.
        bmpOptions.inJustDecodeBounds = true;
        BitmapFactory.decodeByteArray(jpegData, 0, jpegData.length, bmpOptions);
        assertEquals(width, bmpOptions.outWidth);
        assertEquals(height, bmpOptions.outHeight);

        // Pixel decoding mode: decode whole image. check if the image data
        // is decodable here.
        assertNotNull("Decoding jpeg failed",
                BitmapFactory.decodeByteArray(jpegData, 0, jpegData.length));
        if (DEBUG && filePath != null) {
            String fileName =
                    filePath + "/" + width + "x" + height + ".jpeg";
            dumpFile(fileName, jpegData);
        }
    }

    private static void validateYuvData(byte[] yuvData, int width, int height, int format,
            long ts, String filePath) {
        checkYuvFormat(format);
        if (VERBOSE) Log.v(TAG, "Validating YUV data");
        int expectedSize = width * height * ImageFormat.getBitsPerPixel(format) / 8;
        assertEquals("Yuv data doesn't match", expectedSize, yuvData.length);

        // TODO: Can add data validation for test pattern.

        if (DEBUG && filePath != null) {
            String fileName =
                    filePath + "/" + width + "x" + height + "_" + ts / 1e6 + ".yuv";
            dumpFile(fileName, yuvData);
        }
    }

    private static void validateRaw16Data(byte[] rawData, int width, int height, int format,
            long ts, String filePath) {
        if (VERBOSE) Log.v(TAG, "Validating raw data");
        int expectedSize = width * height * ImageFormat.getBitsPerPixel(format) / 8;
        assertEquals("Yuv data doesn't match", expectedSize, rawData.length);

        // TODO: Can add data validation for test pattern.

        if (DEBUG && filePath != null) {
            String fileName =
                    filePath + "/" + width + "x" + height + "_" + ts / 1e6 + ".raw16";
            dumpFile(fileName, rawData);
        }

        return;
    }

    public static <T> T getValueNotNull(CaptureResult result, CaptureResult.Key<T> key) {
        if (result == null) {
            throw new IllegalArgumentException("Result must not be null");
        }

        T value = result.get(key);
        assertNotNull("Value of Key " + key.getName() + "shouldn't be null", value);
        return value;
    }

    /**
     * Get a crop region for a given zoom factor and center position.
     * <p>
     * The center position is normalized position in range of [0, 1.0], where
     * (0, 0) represents top left corner, (1.0. 1.0) represents bottom right
     * corner. The center position could limit the effective minimal zoom
     * factor, for example, if the center position is (0.75, 0.75), the
     * effective minimal zoom position becomes 2.0. If the requested zoom factor
     * is smaller than 2.0, a crop region with 2.0 zoom factor will be returned.
     * </p>
     * <p>
     * The aspect ratio of the crop region is maintained the same as the aspect
     * ratio of active array.
     * </p>
     *
     * @param zoomFactor The zoom factor to generate the crop region, it must be
     *            >= 1.0
     * @param center The normalized zoom center point that is in the range of [0, 1].
     * @param maxZoom The max zoom factor supported by this device.
     * @param activeArray The active array size of this device.
     * @return crop region for the given normalized center and zoom factor.
     */
    public static Rect getCropRegionForZoom(float zoomFactor, final PointF center,
            final float maxZoom, final Rect activeArray) {
        if (zoomFactor < 1.0) {
            throw new IllegalArgumentException("zoom factor " + zoomFactor + " should be >= 1.0");
        }
        if (center.x > 1.0 || center.x < 0) {
            throw new IllegalArgumentException("center.x " + center.x
                    + " should be in range of [0, 1.0]");
        }
        if (center.y > 1.0 || center.y < 0) {
            throw new IllegalArgumentException("center.y " + center.y
                    + " should be in range of [0, 1.0]");
        }
        if (maxZoom < 1.0) {
            throw new IllegalArgumentException("max zoom factor " + maxZoom + " should be >= 1.0");
        }
        if (activeArray == null) {
            throw new IllegalArgumentException("activeArray must not be null");
        }

        float minCenterLength = Math.min(Math.min(center.x, 1.0f - center.x),
                Math.min(center.y, 1.0f - center.y));
        float minEffectiveZoom =  0.5f / minCenterLength;
        if (minEffectiveZoom > maxZoom) {
            throw new IllegalArgumentException("Requested center " + center.toString() +
                    " has minimal zoomable factor " + minEffectiveZoom + ", which exceeds max"
                            + " zoom factor " + maxZoom);
        }

        if (zoomFactor < minEffectiveZoom) {
            Log.w(TAG, "Requested zoomFactor " + zoomFactor + " > minimal zoomable factor "
                    + minEffectiveZoom + ". It will be overwritten by " + minEffectiveZoom);
            zoomFactor = minEffectiveZoom;
        }

        int cropCenterX = (int)(activeArray.width() * center.x);
        int cropCenterY = (int)(activeArray.height() * center.y);
        int cropWidth = (int) (activeArray.width() / zoomFactor);
        int cropHeight = (int) (activeArray.height() / zoomFactor);

        return new Rect(
                /*left*/cropCenterX - cropWidth / 2,
                /*top*/cropCenterY - cropHeight / 2,
                /*right*/ cropCenterX + cropWidth / 2 - 1,
                /*bottom*/cropCenterY + cropHeight / 2 - 1);
    }

    /**
     * Calculate output 3A region from the intersection of input 3A region and cropped region.
     *
     * @param requestRegions The input 3A regions
     * @param cropRect The cropped region
     * @return expected 3A regions output in capture result
     */
    public static MeteringRectangle[] getExpectedOutputRegion(
            MeteringRectangle[] requestRegions, Rect cropRect){
        MeteringRectangle[] resultRegions = new MeteringRectangle[requestRegions.length];
        for (int i = 0; i < requestRegions.length; i++) {
            Rect requestRect = requestRegions[i].getRect();
            Rect resultRect = new Rect();
            assertTrue("Input 3A region must intersect cropped region",
                        resultRect.setIntersect(requestRect, cropRect));
            resultRegions[i] = new MeteringRectangle(
                    resultRect,
                    requestRegions[i].getMeteringWeight());
        }
        return resultRegions;
    }
}
