/*
 * Copyright (C) 2011 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.cts;

import android.content.Context;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;

import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;

import android.os.ConditionVariable;
import android.os.Environment;
import android.os.Looper;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;

import android.test.ActivityInstrumentationTestCase2;
import android.test.MoreAsserts;
import android.test.UiThreadTest;
import android.test.suitebuilder.annotation.LargeTest;
import android.util.Log;

import com.android.cts.util.TimeoutReq;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.opengles.GL10;

/**
 * This test case must run with hardware. It can't be tested in emulator
 */
@LargeTest
public class CameraGLTest extends ActivityInstrumentationTestCase2<GLSurfaceViewCtsActivity> {
    private static final String TAG = "CameraGLTest";
    private static final String PACKAGE = "com.android.cts.hardware";
    private static final boolean LOGV = false;
    private static final boolean LOGVV = false;
    private static final int EGL_OPENGL_ES2_BIT = 0x0004;

    private boolean mSurfaceTextureCallbackResult = false;

    private static final int WAIT_FOR_COMMAND_TO_COMPLETE = 5000;  // Milliseconds.
    private static final int WAIT_FOR_FOCUS_TO_COMPLETE = 5000;
    private static final int WAIT_FOR_SNAPSHOT_TO_COMPLETE = 5000;

    private SurfaceTextureCallback mSurfaceTextureCallback = new SurfaceTextureCallback();
    private SurfaceTextureBurstCallback mSurfaceTextureBurstCallback = new SurfaceTextureBurstCallback();
    private PreviewCallback mPreviewCallback = new PreviewCallback();

    private Looper mLooper = null;
    private final ConditionVariable mSurfaceTextureDone = new ConditionVariable();
    private final ConditionVariable mPreviewDone = new ConditionVariable();

    Camera mCamera;
    SurfaceTexture mSurfaceTexture;
    private final Object mSurfaceTextureSyncLock = new Object();
    Renderer mRenderer;
    GLSurfaceView mGLView;

    public CameraGLTest() {
        super(PACKAGE, GLSurfaceViewCtsActivity.class);
        if (LOGV) Log.v(TAG, "CameraGLTest Constructor");
    }

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        // Set up renderer instance
        mRenderer = this.new Renderer();
        GLSurfaceViewCtsActivity.setRenderer(mRenderer);
        GLSurfaceViewCtsActivity.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
        GLSurfaceViewCtsActivity.setGlVersion(2);
        // Start CameraCtsActivity.
        GLSurfaceViewCtsActivity ctsActivity = getActivity();
        // Store a link to the view so we can redraw it when needed
        mGLView = ctsActivity.getView();
    }

    @Override
    protected void tearDown() throws Exception {
        if (mCamera != null) {
            terminateMessageLooper();
        }
        // Clean up static values in cts so it can be reused
        GLSurfaceViewCtsActivity.resetRenderMode();
        GLSurfaceViewCtsActivity.resetRenderer();
        GLSurfaceViewCtsActivity.resetGlVersion();

        super.tearDown();
    }

    /**
     * Initializes the message looper so that the Camera object can
     * receive the callback messages.
     */
    private void initializeMessageLooper(final int cameraId) {
        final ConditionVariable startDone = new ConditionVariable();
        new Thread() {
            @Override
            public void run() {
                Log.v(TAG, "Start camera/surfacetexture thread");
                // Set up a looper to be used by camera.
                Looper.prepare();
                // Save the looper so that we can terminate this thread
                // after we are done with it.
                mLooper = Looper.myLooper();
                // These must be instantiated outside the UI thread, since the
                // UI thread will be doing a lot of waiting, stopping callbacks.
                mCamera = Camera.open(cameraId);
                mSurfaceTexture = new SurfaceTexture(mRenderer.getTextureID());
                Log.v(TAG, "Camera " + cameraId + " is opened.");
                startDone.open();
                Looper.loop(); // Blocks forever until Looper.quit() is called.
                Log.v(TAG, "Stop camera/surfacetexture thread");
            }
        }.start();

        Log.v(TAG, "start waiting for looper");
        if (!startDone.block(WAIT_FOR_COMMAND_TO_COMPLETE)) {
            fail("initializeMessageLooper: start timeout");
        }
    }

    /**
     * Terminates the message looper thread.
     */
    private void terminateMessageLooper() throws Exception {
        if (LOGV) Log.v(TAG, "Shutting down camera");
        mCamera.release();
        mLooper.quit();
        // Looper.quit() is asynchronous. The looper may still has some
        // preview callbacks in the queue after quit is called. The preview
        // callback still uses the camera object (setHasPreviewCallback).
        // After camera is released, RuntimeException will be thrown from
        // the method. So we need to join the looper thread here.
        mLooper.getThread().join();
        mCamera = null;
        synchronized(mSurfaceTextureSyncLock) {
            mSurfaceTexture = null;
        }
        if (LOGV) Log.v(TAG, "Shutdown of camera complete.");
    }

    /** The camera preview callback. Stops capture after the first callback */
    private final class PreviewCallback
            implements android.hardware.Camera.PreviewCallback {
        public void onPreviewFrame(byte [] data, Camera camera) {
            if (LOGV) Log.v(TAG, "PreviewCallback");
            assertNotNull(data);
            Size size = camera.getParameters().getPreviewSize();
            assertEquals(size.width * size.height * 3 / 2, data.length);
            mCamera.stopPreview();
            mPreviewDone.open();
        }
    }

    /** A simple SurfaceTexture listener callback, meant to be used together with the camera preview
     * callback */
    private final class SurfaceTextureCallback
            implements android.graphics.SurfaceTexture.OnFrameAvailableListener {
        public void onFrameAvailable(SurfaceTexture surfaceTexture) {
            if (LOGV) Log.v(TAG, "SurfaceTextureCallback");
            mSurfaceTextureDone.open();
            // Assumes preview is stopped elsewhere
        }
    }

    /** A burst SurfaceTexture listener callback, used for multiple-frame capture */
    private final class SurfaceTextureBurstCallback
            implements android.graphics.SurfaceTexture.OnFrameAvailableListener {

        public void setBurstCount(int burstCount) {
            mBurstCount = burstCount;
        }

        public int getBurstCount() {
            return mBurstCount;
        }

        public void onFrameAvailable(SurfaceTexture surfaceTexture) {
            if (LOGVV) Log.v(TAG, "SurfaceTextureBurstCallback, frame #" + mBurstCount);
            mBurstCount--;
            if (!mSurfaceTextureCallbackResult) {
                if (mBurstCount <= 0) {
                    if (LOGV) Log.v(TAG, "SurfaceTextureBurstCallback stopping preview.");
                    mCamera.stopPreview();
                    if (LOGVV) Log.v(TAG, "SurfaceTextureBurstCallback preview stopped.");
                    mSurfaceTextureCallbackResult = true;
                }
                mSurfaceTextureDone.open();
            }
        }

        private int mBurstCount = 0;
    }

    /** Waits until surface texture callbacks have fired */
    private boolean waitForSurfaceTextureDone() {
        if (LOGVV) Log.v(TAG, "Wait for surface texture callback");
        if (!mSurfaceTextureDone.block(WAIT_FOR_COMMAND_TO_COMPLETE)) {
            // timeout could be expected or unexpected. The caller will decide.
            Log.v(TAG, "waitForSurfaceTextureDone: timeout");
            return false;
        }
        mSurfaceTextureDone.close();
        return true;
    }

    /** Waits until the camera preview callback has fired */
    private boolean waitForPreviewDone() {
        if (LOGVV) Log.v(TAG, "Wait for preview callback");
        if (!mPreviewDone.block(WAIT_FOR_COMMAND_TO_COMPLETE)) {
            // timeout could be expected or unexpected. The caller will decide.
            Log.v(TAG, "waitForPreviewDone: timeout");
            return false;
        }
        mPreviewDone.close();
        return true;
    }

    /** @return OpenGL ES major version 1 or 2 or some negative number for error */
    private static int getDetectedVersion() {
        /*
         * Get all the device configurations and check if any of the attributes specify the
         * the EGL_OPENGL_ES2_BIT to determine whether the device supports 2.0.
         */
        EGL10 egl = (EGL10) EGLContext.getEGL();
        EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
        int[] numConfigs = new int[1];

        if (egl.eglInitialize(display, null)) {
            try {
                if (egl.eglGetConfigs(display, null, 0, numConfigs)) {
                    EGLConfig[] configs = new EGLConfig[numConfigs[0]];
                    if (egl.eglGetConfigs(display, configs, numConfigs[0], numConfigs)) {
                        int[] value = new int[1];
                        for (int i = 0; i < numConfigs[0]; i++) {
                            if (egl.eglGetConfigAttrib(display, configs[i],
                                    EGL10.EGL_RENDERABLE_TYPE, value)) {
                                if ((value[0] & EGL_OPENGL_ES2_BIT) == EGL_OPENGL_ES2_BIT) {
                                    return 2;
                                }
                            } else {
                                Log.w(TAG, "Getting config attribute with "
                                        + "EGL10#eglGetConfigAttrib failed "
                                        + "(" + i + "/" + numConfigs[0] + "): "
                                        + egl.eglGetError());
                            }
                        }
                        return 1;
                    } else {
                        Log.e(TAG, "Getting configs with EGL10#eglGetConfigs failed: "
                                + egl.eglGetError());
                        return -1;
                    }
                } else {
                    Log.e(TAG, "Getting number of configs with EGL10#eglGetConfigs failed: "
                            + egl.eglGetError());
                    return -2;
                }
              } finally {
                  egl.eglTerminate(display);
              }
        } else {
            Log.e(TAG, "Couldn't initialize EGL.");
            return -3;
        }
    }

    /** Generic per-camera test interface */
    private interface RunPerCamera {
        void run(int cameraId) throws Exception;
    }

    /** Generic camera test runner, to minimize boilerplace duplication */
    private void runForAllCameras(RunPerCamera test) throws Exception {
        /* Currently OpenGL ES 2.0 is supported for this test, so just skip it
           if only 1.0 is available. */
        int glVersion = getDetectedVersion();
        assertTrue(glVersion > 0);
        if (glVersion != 2) {
            Log.w(TAG, "Skipping test because OpenGL ES 2 is not supported");
            return;
        }

        /* Make sure the screen stays on while testing - otherwise the OpenGL context may disappear */
        PowerManager pm = (PowerManager) getActivity().getSystemService(Context.POWER_SERVICE);
        PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "CameraGLTest");
        wl.acquire();
        try {
            /* Run the requested test per camera */
            int nCameras = Camera.getNumberOfCameras();
            for (int id = 0; id < nCameras; id++) {
                Log.v(TAG, "Camera id=" + id);
                test.run(id);
            }
        } finally {
            wl.release();
            // If an assert failed, camera might still be active. Clean up before next test.
            if (mCamera != null) {
                terminateMessageLooper();
            }
        }
    }

    /** Test Camera.setPreviewTexture in conjunction with the standard Camera preview callback */
    @UiThreadTest
    public void testSetPreviewTexturePreviewCallback() throws Exception {
        runForAllCameras(testSetPreviewTexturePreviewCallbackByCamera);
    }

    private RunPerCamera testSetPreviewTexturePreviewCallbackByCamera = new RunPerCamera() {
        public void run(int cameraId) throws Exception {
            boolean noTimeout;
            // Check the order: startPreview->setPreviewTexture, with a PreviewCallback as well
            mPreviewDone.close();
            initializeMessageLooper(cameraId);
            mCamera.setOneShotPreviewCallback(mPreviewCallback);
            mCamera.startPreview();
            mCamera.setPreviewTexture(mSurfaceTexture);
            noTimeout = waitForPreviewDone();
            assertTrue("Timeout waiting for new preview callback!", noTimeout);
            terminateMessageLooper();

            // Check the order: setPreviewTexture->startPreview.
            initializeMessageLooper(cameraId);
            mCamera.setOneShotPreviewCallback(mPreviewCallback);
            mCamera.setPreviewTexture(mSurfaceTexture);
            mCamera.startPreview();
            noTimeout = waitForPreviewDone();
            assertTrue("Timeout waiting for new preview callback!", noTimeout);

            // Check the order: setting preview display to null->startPreview->
            // setPreviewTexture.
            mCamera.setOneShotPreviewCallback(mPreviewCallback);
            mCamera.setPreviewTexture(null);
            mCamera.startPreview();
            mCamera.setPreviewTexture(mSurfaceTexture);
            noTimeout = waitForPreviewDone();
            assertTrue("Timeout waiting for new preview callback!", noTimeout);
            terminateMessageLooper();
        }
    };

    /** Test Camera.setPreviewTexture in conjunction with both the standard Camera preview callback,
        and the SurfaceTexture onFrameAvailable callback */
    @UiThreadTest
    public void testSetPreviewTextureBothCallbacks() throws Exception {
        runForAllCameras(testSetPreviewTextureBothCallbacksByCamera);
    }

    private RunPerCamera testSetPreviewTextureBothCallbacksByCamera = new RunPerCamera() {
        public void run(int cameraId) throws Exception {
            boolean noTimeout;
            // Check SurfaceTexture callback together with preview callback
            // Check the order: setPreviewTexture->startPreview
            mSurfaceTextureDone.close();
            initializeMessageLooper(cameraId);
            mRenderer.setCameraSizing(mCamera.getParameters().getPreviewSize());
            mCamera.setOneShotPreviewCallback(mPreviewCallback);
            mSurfaceTexture.setOnFrameAvailableListener(mSurfaceTextureCallback);
            mCamera.setPreviewTexture(mSurfaceTexture);
            mCamera.startPreview();

            noTimeout = waitForSurfaceTextureDone();
            assertTrue("Timeout waiting for new frame from SurfaceTexture!", noTimeout);
            noTimeout = waitForPreviewDone();
            assertTrue("Timeout waiting for new preview callback!",noTimeout);

            mGLView.requestRender();
            terminateMessageLooper();

            // Check the order: startPreview->setPreviewTexture
            mSurfaceTextureDone.close();
            initializeMessageLooper(cameraId);
            mRenderer.setCameraSizing(mCamera.getParameters().getPreviewSize());
            mCamera.setOneShotPreviewCallback(mPreviewCallback);
            mSurfaceTexture.setOnFrameAvailableListener(mSurfaceTextureCallback);
            mCamera.startPreview();
            mCamera.setPreviewTexture(mSurfaceTexture);

            noTimeout = waitForSurfaceTextureDone();
            assertTrue("Timeout waiting for new frame from SurfaceTexture!", noTimeout);
            noTimeout = waitForPreviewDone();
            assertTrue("Timeout waiting for new preview callback!", noTimeout);

            mGLView.requestRender();

            // Check the order: setting preview to null->startPreview->setPreviewTexture
            mCamera.setOneShotPreviewCallback(mPreviewCallback);
            mCamera.setPreviewTexture(null);
            mSurfaceTexture.setOnFrameAvailableListener(mSurfaceTextureCallback);
            mCamera.startPreview();
            mCamera.setPreviewTexture(mSurfaceTexture);
            noTimeout = waitForPreviewDone();
            assertTrue(noTimeout);
            terminateMessageLooper();
        }
    };

    /** Test Camera.setPreviewTexture in conjunction with just the SurfaceTexture onFrameAvailable callback */
    @UiThreadTest
    public void testSetPreviewTextureTextureCallback() throws Exception {
        runForAllCameras(testSetPreviewTextureTextureCallbackByCamera);
    }

    private RunPerCamera testSetPreviewTextureTextureCallbackByCamera = new RunPerCamera() {
        public void run(int cameraId) throws Exception {
            boolean noTimeout;
            // Check that SurfaceTexture callbacks work with no standard
            // preview callback
            mSurfaceTextureCallbackResult = false;
            mSurfaceTextureDone.close();
            initializeMessageLooper(cameraId);
            mSurfaceTextureBurstCallback.setBurstCount(1);
            mSurfaceTexture.setOnFrameAvailableListener(mSurfaceTextureBurstCallback);
            mCamera.setPreviewTexture(mSurfaceTexture);
            mRenderer.setCameraSizing(mCamera.getParameters().getPreviewSize());
            mCamera.startPreview();

            noTimeout = waitForSurfaceTextureDone();
            mGLView.requestRender();
            assertTrue(noTimeout);

            terminateMessageLooper();
            assertTrue(mSurfaceTextureCallbackResult);

            // Check that SurfaceTexture callbacks also work with
            // startPreview->setPreviewTexture
            mSurfaceTextureCallbackResult = false;
            mSurfaceTextureDone.close();
            initializeMessageLooper(cameraId);
            mSurfaceTextureBurstCallback.setBurstCount(1);
            mSurfaceTexture.setOnFrameAvailableListener(mSurfaceTextureBurstCallback);
            mRenderer.setCameraSizing(mCamera.getParameters().getPreviewSize());
            mCamera.startPreview();
            mCamera.setPreviewTexture(mSurfaceTexture);

            noTimeout = waitForSurfaceTextureDone();
            assertTrue(noTimeout);

            terminateMessageLooper();
            assertTrue(mSurfaceTextureCallbackResult);

            // Check that SurfaceTexture callbacks also work with
            // null->startPreview->setPreviewTexture
            mSurfaceTextureCallbackResult = false;
            mSurfaceTextureDone.close();
            initializeMessageLooper(cameraId);
            mSurfaceTextureBurstCallback.setBurstCount(1);
            mSurfaceTexture.setOnFrameAvailableListener(mSurfaceTextureBurstCallback);
            mRenderer.setCameraSizing(mCamera.getParameters().getPreviewSize());
            mCamera.setPreviewTexture(null);
            mCamera.startPreview();
            mCamera.setPreviewTexture(mSurfaceTexture);

            noTimeout = waitForSurfaceTextureDone();
            assertTrue(noTimeout);

            terminateMessageLooper();
            assertTrue(mSurfaceTextureCallbackResult);
        }
    };

    /** Test all preview sizes and framerates along with SurfaceTexture-provided metadata (texture
     * transforms and timestamps).
     * TODO: This should be made stricter once SurfaceTexture timestamps are generated by the drivers.
     */
    @UiThreadTest
    @TimeoutReq(minutes = 20)
    public void testCameraToSurfaceTextureMetadata() throws Exception {
        runForAllCameras(testCameraToSurfaceTextureMetadataByCamera);
    }

    private RunPerCamera testCameraToSurfaceTextureMetadataByCamera = new RunPerCamera() {
        public void run(int cameraId) throws Exception {
            // Number of frames to test over
            int kLoopCount = 100;
            // Number of frames that can be out of bounds before calling this a failure
            int kMaxOutOfBoundsFrames = kLoopCount / 25; // 4% of frames
            // Ignore timestamp issues before this frame
            int kFirstTestedFrame = 10;
            // Slop in timestamp testing, needed because timestamps are not
            // currently being set by driver-level code so are subject to
            // user-space timing variability
            float kTestSlopMargin = 20; // ms

            boolean noTimeout;
            initializeMessageLooper(cameraId);
            Parameters parameters = mCamera.getParameters();

            mSurfaceTexture.setOnFrameAvailableListener(mSurfaceTextureBurstCallback);
            mCamera.setPreviewTexture(mSurfaceTexture);

            for (Size size: parameters.getSupportedPreviewSizes()) {
                for (int[] fps: parameters.getSupportedPreviewFpsRange()) {
                    if (LOGV) {
                        Log.v(TAG, "Testing camera #" + cameraId +
                              ", preview size:" + size.width + "x" + size.height +
                              ", frame rate range: [" +
                              (fps[Parameters.PREVIEW_FPS_MIN_INDEX] / 1000.) + "," +
                              (fps[Parameters.PREVIEW_FPS_MAX_INDEX] / 1000.) + "]");
                    }
                    parameters.setPreviewSize(size.width, size.height);
                    parameters.setPreviewFpsRange(fps[Parameters.PREVIEW_FPS_MIN_INDEX],
                                                  fps[Parameters.PREVIEW_FPS_MAX_INDEX]);
                    mCamera.setParameters(parameters);

                    assertEquals(size, mCamera.getParameters().getPreviewSize());

                    int[] actualFps = new int[2];
                    mCamera.getParameters().getPreviewFpsRange(actualFps);
                    assertEquals(fps[Parameters.PREVIEW_FPS_MIN_INDEX],
                                 actualFps[Parameters.PREVIEW_FPS_MIN_INDEX]);
                    assertEquals(fps[Parameters.PREVIEW_FPS_MAX_INDEX],
                                 actualFps[Parameters.PREVIEW_FPS_MAX_INDEX]);

                    mSurfaceTextureBurstCallback.
                            setBurstCount(kLoopCount + kFirstTestedFrame);
                    mSurfaceTextureCallbackResult = false;
                    mSurfaceTextureDone.close();

                    mRenderer.setCameraSizing(mCamera.getParameters().getPreviewSize());
                    if (LOGV) Log.v(TAG, "Starting preview");
                    mCamera.startPreview();
                    if (LOGVV) Log.v(TAG, "Preview started");

                    long[] timestamps = new long[kLoopCount];
                    for (int i = 0; i < kLoopCount + kFirstTestedFrame; i++) {
                        noTimeout = waitForSurfaceTextureDone();
                        assertTrue("Timeout waiting for frame " + i +
                                   " (burst callback thinks " +
                                   (kLoopCount - mSurfaceTextureBurstCallback.getBurstCount()) +
                                   ")! (Size " + size.width + "x" + size.height + ", fps [" +
                                   (fps[Parameters.PREVIEW_FPS_MIN_INDEX] / 1000.) + ", " +
                                   (fps[Parameters.PREVIEW_FPS_MAX_INDEX] / 1000.) + "])",
                                   noTimeout);

                        if (LOGVV) Log.v(TAG, "Frame #" + i + " completed");
                        // Draw the frame (and update the SurfaceTexture)
                        mGLView.requestRender();
                        // Wait until frame is drawn, so that the SurfaceTexture has new
                        // metadata
                        noTimeout = mRenderer.waitForDrawDone();
                        assertTrue(noTimeout);

                        // Store timestamps for later
                        if (i >= kFirstTestedFrame) {
                            timestamps[i - kFirstTestedFrame] =
                                    mSurfaceTexture.getTimestamp();
                        }
                        // Verify that the surfaceTexture transform has at least one non-zero
                        // entry
                        float[] transform = new float[16];
                        mSurfaceTexture.getTransformMatrix(transform);
                        boolean nonZero = false;
                        for (int k = 0; k < 16; k++) {
                            if (transform[k] != 0.f) {
                                nonZero = true;
                                break;
                            }
                        }
                        assertTrue(nonZero);
                    }
                    assertTrue(mSurfaceTextureCallbackResult);

                    float expectedMaxFrameDurationMs = 1000.f * 1000.f /
                            fps[Parameters.PREVIEW_FPS_MIN_INDEX];
                    float slopMaxFrameDurationMs = expectedMaxFrameDurationMs +
                            kTestSlopMargin;
                    float expectedMinFrameDurationMs = 1000.f * 1000.f /
                            fps[Parameters.PREVIEW_FPS_MAX_INDEX];
                    float slopMinFrameDurationMs = expectedMinFrameDurationMs  -
                            kTestSlopMargin;

                    int outOfBoundsCount = 0;
                    for (int i = 1; i < kLoopCount; i++) {
                        float frameDurationMs =
                                (timestamps[i] - timestamps[i-1]) / 1000000.f;
                        if (LOGVV) {
                            Log.v(TAG, "Frame " + i + " duration: " + frameDurationMs +
                                  " ms, expecting [" + expectedMinFrameDurationMs + "," +
                                    expectedMaxFrameDurationMs + "], slop range [" +
                                    slopMinFrameDurationMs + "," + slopMaxFrameDurationMs + "].");
                        }
                        if ( frameDurationMs > slopMaxFrameDurationMs ||
                                frameDurationMs < slopMinFrameDurationMs ) {
                            if (LOGVV) {
                                Log.v(TAG, "  Out of bounds!!");
                            }
                            outOfBoundsCount++;
                        }
                    }
                    assertTrue(
                            "Too many frame intervals out of frame rate bounds: "
                            + outOfBoundsCount +
                            ", limit " + kMaxOutOfBoundsFrames,
                            outOfBoundsCount <= kMaxOutOfBoundsFrames);
                }
            }
            terminateMessageLooper();
        } // void run(int cameraId)
    };

    /** Basic OpenGL ES 2.0 renderer to draw SurfaceTexture-sourced frames to the screen */
    private class Renderer implements GLSurfaceView.Renderer {
        public Renderer() {
            mTriangleVertices =
                    ByteBuffer.allocateDirect(mTriangleVerticesData.length * FLOAT_SIZE_BYTES).
                    order(ByteOrder.nativeOrder()).asFloatBuffer();
            mTriangleVertices.put(mTriangleVerticesData).position(0);

            Matrix.setIdentityM(mSTMatrix, 0);
            Matrix.setIdentityM(mMMatrix, 0);

            mTextureID = 0;
        }

        public void setCameraSizing(Camera.Size previewSize) {
            mCameraRatio = (float)previewSize.width/previewSize.height;
        }

        public boolean waitForDrawDone() {
            if (!mDrawDone.block(WAIT_FOR_COMMAND_TO_COMPLETE) ) {
                // timeout could be expected or unexpected. The caller will decide.
                Log.e(TAG, "waitForDrawDone: timeout");
                return false;
            }
            mDrawDone.close();
            return true;
        }

        private final ConditionVariable mDrawDone = new ConditionVariable();

        public void onDrawFrame(GL10 glUnused) {
            if (LOGVV) Log.v(TAG, "onDrawFrame()");
            synchronized(mSurfaceTextureSyncLock) {
                if (CameraGLTest.this.mSurfaceTexture != null) {
                    CameraGLTest.this.mSurfaceTexture.updateTexImage();
                    CameraGLTest.this.mSurfaceTexture.getTransformMatrix(mSTMatrix);
                    mDrawDone.open();
                }
            }

            // Ignore the passed-in GL10 interface, and use the GLES20
            // class's static methods instead.
            GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
            GLES20.glUseProgram(mProgram);
            checkGlError("glUseProgram");

            GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
            GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureID);

            mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
            GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false,
                                         TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
            checkGlError("glVertexAttribPointer maPosition");
            GLES20.glEnableVertexAttribArray(maPositionHandle);
            checkGlError("glEnableVertexAttribArray maPositionHandle");

            mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
            GLES20.glVertexAttribPointer(maTextureHandle, 2, GLES20.GL_FLOAT, false,
                                         TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
            checkGlError("glVertexAttribPointer maTextureHandle");
            GLES20.glEnableVertexAttribArray(maTextureHandle);
            checkGlError("glEnableVertexAttribArray maTextureHandle");

            Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0);
            Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);

            GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
            GLES20.glUniformMatrix4fv(muSTMatrixHandle, 1, false, mSTMatrix, 0);
            GLES20.glUniform1f(muCRatioHandle, mCameraRatio);

            GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
            checkGlError("glDrawArrays");
        }

        public void onSurfaceChanged(GL10 glUnused, int width, int height) {
            if (LOGV) Log.v(TAG, "onSurfaceChanged()");
            // Ignore the passed-in GL10 interface, and use the GLES20
            // class's static methods instead.
            GLES20.glViewport(0, 0, width, height);
            mRatio = (float) width / height;
            Matrix.frustumM(mProjMatrix, 0, -mRatio, mRatio, -1, 1, 3, 7);
        }

        public void onSurfaceCreated(GL10 glUnused, EGLConfig config) {
            if (LOGV) Log.v(TAG, "onSurfaceCreated()");
            // Ignore the passed-in GL10 interface, and use the GLES20
            // class's static methods instead.

            /* Set up shaders and handles to their variables */
            mProgram = createProgram(mVertexShader, mFragmentShader);
            if (mProgram == 0) {
                return;
            }
            maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
            checkGlError("glGetAttribLocation aPosition");
            if (maPositionHandle == -1) {
                throw new RuntimeException("Could not get attrib location for aPosition");
            }
            maTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTextureCoord");
            checkGlError("glGetAttribLocation aTextureCoord");
            if (maTextureHandle == -1) {
                throw new RuntimeException("Could not get attrib location for aTextureCoord");
            }

            muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
            checkGlError("glGetUniformLocation uMVPMatrix");
            if (muMVPMatrixHandle == -1) {
                throw new RuntimeException("Could not get attrib location for uMVPMatrix");
            }

            muSTMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uSTMatrix");
            checkGlError("glGetUniformLocation uSTMatrix");
            if (muMVPMatrixHandle == -1) {
                throw new RuntimeException("Could not get attrib location for uSTMatrix");
            }

            muCRatioHandle = GLES20.glGetUniformLocation(mProgram, "uCRatio");
            checkGlError("glGetUniformLocation uCRatio");
            if (muMVPMatrixHandle == -1) {
                throw new RuntimeException("Could not get attrib location for uCRatio");
            }

            /*
             * Create our texture. This has to be done each time the
             * surface is created.
             */

            int[] textures = new int[1];
            GLES20.glGenTextures(1, textures, 0);

            mTextureID = textures[0];
            GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureID);
            checkGlError("glBindTexture mTextureID");

            // Can't do mipmapping with camera source
            GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER,
                                   GLES20.GL_NEAREST);
            GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER,
                                   GLES20.GL_LINEAR);
            // Clamp to edge is the only option
            GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S,
                                   GLES20.GL_CLAMP_TO_EDGE);
            GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T,
                                   GLES20.GL_CLAMP_TO_EDGE);
            checkGlError("glTexParameteri mTextureID");

            Matrix.setLookAtM(mVMatrix, 0, 0, 0, 4f, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
        }

        public int getTextureID() {
            return mTextureID;
        }

        private int loadShader(int shaderType, String source) {
            int shader = GLES20.glCreateShader(shaderType);
            if (shader != 0) {
                GLES20.glShaderSource(shader, source);
                GLES20.glCompileShader(shader);
                int[] compiled = new int[1];
                GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
                if (compiled[0] == 0) {
                    Log.e(TAG, "Could not compile shader " + shaderType + ":");
                    Log.e(TAG, GLES20.glGetShaderInfoLog(shader));
                    GLES20.glDeleteShader(shader);
                    shader = 0;
                }
            }
            return shader;
        }

        private int createProgram(String vertexSource, String fragmentSource) {
            int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
            if (vertexShader == 0) {
                return 0;
            }
            int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
            if (pixelShader == 0) {
                return 0;
            }

            int program = GLES20.glCreateProgram();
            if (program != 0) {
                GLES20.glAttachShader(program, vertexShader);
                checkGlError("glAttachShader");
                GLES20.glAttachShader(program, pixelShader);
                checkGlError("glAttachShader");
                GLES20.glLinkProgram(program);
                int[] linkStatus = new int[1];
                GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
                if (linkStatus[0] != GLES20.GL_TRUE) {
                    Log.e(TAG, "Could not link program: ");
                    Log.e(TAG, GLES20.glGetProgramInfoLog(program));
                    GLES20.glDeleteProgram(program);
                    program = 0;
                }
            }
            return program;
        }

        private void checkGlError(String op) {
            int error;
            while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
                Log.e(TAG, op + ": glError " + error);
                throw new RuntimeException(op + ": glError " + error);
            }
        }

        private static final int FLOAT_SIZE_BYTES = 4;
        private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES;
        private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0;
        private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3;
        private final float[] mTriangleVerticesData = {
            // X, Y, Z, U, V
            -1.0f, -1.0f, 0, 0.f, 0.f,
            1.0f, -1.0f, 0, 1.f, 0.f,
            -1.0f,  1.0f, 0, 0.f, 1.f,
            1.0f,   1.0f, 0, 1.f, 1.f,
        };

        private FloatBuffer mTriangleVertices;

        private final String mVertexShader =
                "uniform mat4 uMVPMatrix;\n" +
                "uniform mat4 uSTMatrix;\n" +
                "uniform float uCRatio;\n" +
                "attribute vec4 aPosition;\n" +
                "attribute vec4 aTextureCoord;\n" +
                "varying vec2 vTextureCoord;\n" +
                "void main() {\n" +
                "  gl_Position = vec4(uCRatio,1,1,1) * uMVPMatrix * aPosition;\n" +
                "  vTextureCoord = (uSTMatrix * aTextureCoord).xy;\n" +
                "}\n";

        private final String mFragmentShader =
                "#extension GL_OES_EGL_image_external : require\n" +
                "precision mediump float;\n" +
                "varying vec2 vTextureCoord;\n" +
                "uniform samplerExternalOES sTexture;\n" +
                "void main() {\n" +
                "  gl_FragColor = texture2D(sTexture, vTextureCoord);\n" +
                "}\n";

        private float[] mMVPMatrix = new float[16];
        private float[] mProjMatrix = new float[16];
        private float[] mMMatrix = new float[16];
        private float[] mVMatrix = new float[16];
        private float[] mSTMatrix = new float[16];

        private int mProgram;
        private int mTextureID;
        private int muMVPMatrixHandle;
        private int muSTMatrixHandle;
        private int muCRatioHandle;
        private int maPositionHandle;
        private int maTextureHandle;

        private float mRatio = 1.0f;
        private float mCameraRatio = 1.0f;

        private Context mContext;
        private static final String TAG = "CameraGLTest.Renderer";

        // Magic key
        private static final int GL_TEXTURE_EXTERNAL_OES = 0x8D65;
    }

}
