Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b809577f authored by Jason Noguchi's avatar Jason Noguchi Committed by Android Git Automerger
Browse files

am b318f7b9: Merge "Refactor of camera stress test to add camera test helper....

am b318f7b9: Merge "Refactor of camera stress test to add camera test helper. Also add additional functional tests for: flash, exposure, white balance, and focus mode.  Also add pairwise tests." into jb-mr2-dev

* commit 'b318f7b9':
  Refactor of camera stress test to add camera test helper. Also add additional functional tests for: flash, exposure, white balance, and focus mode.  Also add pairwise tests.
parents 51ff6f95 b318f7b9
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.mediaframeworktest;
import android.test.InstrumentationTestRunner;
import android.test.InstrumentationTestSuite;
import com.android.mediaframeworktest.stress.CameraStressTest;
import com.android.mediaframeworktest.functional.camera.CameraFunctionalTest;
import com.android.mediaframeworktest.functional.camera.CameraPairwiseTest;

import junit.framework.TestSuite;

@@ -28,6 +30,8 @@ public class CameraStressTestRunner extends InstrumentationTestRunner {
    public TestSuite getAllTests() {
        TestSuite suite = new InstrumentationTestSuite(this);
        suite.addTestSuite(CameraStressTest.class);
        suite.addTestSuite(CameraFunctionalTest.class);
        suite.addTestSuite(CameraPairwiseTest.class);
        return suite;
    }

+165 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 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 com.android.mediaframeworktest;

import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.os.Environment;
import android.util.Log;
import android.view.SurfaceHolder;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FilenameFilter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import junit.framework.Assert;

public class CameraTestHelper {

    public Camera mCamera;
    private String TAG = "CameraTestHelper";
    private static final int CAMERA_ID = 0;
    private static final long WAIT_GENERIC = 3 * 1000; // 3 seconds
    private static final long WAIT_ZOOM_ANIMATION = 5 * 1000; // 5 seconds
    protected static final String CAMERA_STRESS_IMAGES_DIRECTORY = "cameraStressImages";
    private static final String CAMERA_STRESS_IMAGES_PREFIX = "camera-stress-test";
    private final CameraErrorCallback mCameraErrorCallback = new CameraErrorCallback();

    private final class CameraErrorCallback implements android.hardware.Camera.ErrorCallback {
        public void onError(int error, android.hardware.Camera camera) {
            Assert.fail(String.format("Camera error, code: %d", error));
        }
    }

    private ShutterCallback shutterCallback = new ShutterCallback() {
        @Override
        public void onShutter() {
            Log.v(TAG, "Shutter");
        }
    };

    private PictureCallback rawCallback = new PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            Log.v(TAG, "Raw picture taken");
        }
    };

    private PictureCallback jpegCallback = new PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            FileOutputStream fos = null;

            try {
                Log.v(TAG, "JPEG picture taken");
                fos = new FileOutputStream(String.format("%s/%s/%s-%d.jpg",
                        Environment.getExternalStorageDirectory(), CAMERA_STRESS_IMAGES_DIRECTORY,
                        CAMERA_STRESS_IMAGES_PREFIX, System.currentTimeMillis()));
                fos.write(data);
            } catch (FileNotFoundException e) {
                Log.e(TAG, "File not found: " + e.toString());
            } catch (IOException e) {
                Log.e(TAG, "Error accessing file: " + e.toString());
            } finally {
                try {
                    if (fos != null) {
                        fos.close();
                    }
                } catch (IOException e) {
                    Log.e(TAG, "Error closing file: " + e.toString());
                }
            }
        }
    };

    /**
     * Helper method for prepping test
     */
    public void setupCameraTest() {
        // Create the test images directory if it doesn't exist
        File stressImagesDirectory = new File(String.format("%s/%s",
                Environment.getExternalStorageDirectory(), CAMERA_STRESS_IMAGES_DIRECTORY));
        if (!stressImagesDirectory.exists()) {
            stressImagesDirectory.mkdir();
        }

        mCamera = Camera.open(CAMERA_ID);
    }

    /**
     * Helper method for getting the available parameters of the default camera
     */
    public Parameters getCameraParameters() {
        mCamera = Camera.open(CAMERA_ID);
        Parameters params = mCamera.getParameters();
        mCamera.release();
        return params;
    }

    /**
     * Helper method for taking a photo
     */
    public void capturePhoto() throws Exception {
        mCamera.takePicture(shutterCallback, rawCallback, jpegCallback);
        Thread.sleep(WAIT_GENERIC);
        mCamera.stopPreview();
        mCamera.release();
    }

    /**
     * Helper method for cleaning up pics taken during tests
     */
    public void cleanupTestImages() {
        try {
            File stressImagesDirectory = new File(String.format("%s/%s",
                    Environment.getExternalStorageDirectory(), CAMERA_STRESS_IMAGES_DIRECTORY));
            File[] stressImages = stressImagesDirectory.listFiles();
            for (File f : stressImages) {
                f.delete();
            }
        } catch (SecurityException e) {
            Log.e(TAG, "Security manager access violation: " + e.toString());
        }
    }

    /**
     * Helper method for setting the camera parameters
     */
    public void setParameters(Parameters params) {
        try {
            mCamera.setParameters(params);
        } catch (Exception e) {
            Log.e(TAG, "Error setting camera parameters");
        }
    }

    /**
     * Helper method for starting up the camera preview
     */
    public void startCameraPreview(SurfaceHolder surfaceHolder) throws Exception {
        mCamera.setErrorCallback(mCameraErrorCallback);
        mCamera.setPreviewDisplay(surfaceHolder);
        mCamera.startPreview();
        Thread.sleep(WAIT_GENERIC);
    }
}
+255 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 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 com.android.mediaframeworktest.functional.camera;

import com.android.mediaframeworktest.MediaFrameworkTest;
import com.android.mediaframeworktest.CameraTestHelper;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.LargeTest;
import android.util.FloatMath;
import android.util.Log;
import android.view.SurfaceHolder;
import com.android.mediaframeworktest.CameraStressTestRunner;

import junit.framework.Assert;

/**
 * Junit / Instrumentation test case for the following camera APIs:
 * - flash
 * - exposure compensation
 * - white balance
 * - focus mode
 *
 * adb shell am instrument
 *  -e class com.android.mediaframeworktest.functional.camera.CameraFunctionalTest
 *  -w com.android.mediaframework/.CameraStressTestRunner
 */
public class CameraFunctionalTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
    private static final long WAIT_TIMEOUT = 10 * 1000; // 10 seconds
    private CameraTestHelper mCameraTestHelper;
    private Handler mHandler;
    private Thread mLooperThread;
    private Writer mOutput;

    private String TAG = "CameraFunctionalTest";

    public CameraFunctionalTest() {
        super("com.android.mediaframeworktest", MediaFrameworkTest.class);
    }

    protected void setUp() throws Exception {
        final Semaphore sem = new Semaphore(0);
        mLooperThread = new Thread() {
            @Override
            public void run() {
                Log.v(TAG, "starting looper");
                Looper.prepare();
                mHandler = new Handler();
                sem.release();
                Looper.loop();
                Log.v(TAG, "quit looper");
            }
        };
        mLooperThread.start();
        if (!sem.tryAcquire(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)) {
            fail("Failed to start the looper.");
        }
        getActivity();
        super.setUp();

        mCameraTestHelper = new CameraTestHelper();
    }

    @Override
    protected void tearDown() throws Exception {
        if (mHandler != null) {
            mHandler.getLooper().quit();
            mHandler = null;
        }
        if (mLooperThread != null) {
            mLooperThread.join(WAIT_TIMEOUT);
            if (mLooperThread.isAlive()) {
                fail("Failed to stop the looper.");
            }
            mLooperThread = null;
        }
        super.tearDown();
    }

    private void runOnLooper(final Runnable command) throws InterruptedException {
        final Semaphore sem = new Semaphore(0);
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                try {
                    command.run();
                } finally {
                    sem.release();
                }
            }
        });
        if (!sem.tryAcquire(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)) {
            fail("Failed to run the command on the looper.");
        }
    }

    /**
     * Functional test iterating on the range of supported exposure compensation levels
     */
    @LargeTest
    public void testFunctionalCameraExposureCompensation() throws Exception {
        try {
            SurfaceHolder surfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
            Parameters params = mCameraTestHelper.getCameraParameters();

            int min = params.getMinExposureCompensation();
            int max = params.getMaxExposureCompensation();
            assertFalse("Adjusting exposure not supported", (max == 0 && min == 0));
            float step = params.getExposureCompensationStep();
            int stepsPerEV = (int) Math.round(Math.pow((double) step, -1));

            // only get integer values for exposure compensation
            for (int i = min; i <= max; i += stepsPerEV) {
                runOnLooper(new Runnable() {
                    @Override
                    public void run() {
                        mCameraTestHelper.setupCameraTest();
                    }
                });
                Log.v(TAG, "Setting exposure compensation index to " + i);
                params.setExposureCompensation(i);
                mCameraTestHelper.setParameters(params);
                mCameraTestHelper.startCameraPreview(surfaceHolder);
                mCameraTestHelper.capturePhoto();
            }
            mCameraTestHelper.cleanupTestImages();
        } catch (Exception e) {
            Log.e(TAG, e.toString());
            fail("Camera exposure compensation test Exception");
        }
    }

    /**
     * Functional test iterating on the various flash modes (on, off, auto, torch)
     */
    @LargeTest
    public void testFunctionalCameraFlashModes() throws Exception {
        try {
            SurfaceHolder surfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
            Parameters params = mCameraTestHelper.getCameraParameters();
            List<String> supportedFlashModes = params.getSupportedFlashModes();
            assertNotNull("No flash modes supported", supportedFlashModes);

            for (int i = 0; i < supportedFlashModes.size(); i++) {
                runOnLooper(new Runnable() {
                    @Override
                    public void run() {
                        mCameraTestHelper.setupCameraTest();
                    }
                });
                Log.v(TAG, "Setting flash mode to " + supportedFlashModes.get(i));
                params.setFlashMode(supportedFlashModes.get(i));
                mCameraTestHelper.setParameters(params);
                mCameraTestHelper.startCameraPreview(surfaceHolder);
                mCameraTestHelper.capturePhoto();
            }
            mCameraTestHelper.cleanupTestImages();
        } catch (Exception e) {
            Log.e(TAG, e.toString());
            fail("Camera flash mode test Exception");
        }
    }

    /**
     * Functional test iterating on the various focus modes (auto, infinitiy, macro, etc.)
     */
    @LargeTest
    public void testFunctionalCameraFocusModes() throws Exception {
        try {
            SurfaceHolder surfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
            Parameters params = mCameraTestHelper.getCameraParameters();
            List<String> supportedFocusModes = params.getSupportedFocusModes();
            assertNotNull("No focus modes supported", supportedFocusModes);

            for (int i = 0; i < supportedFocusModes.size(); i++) {
                runOnLooper(new Runnable() {
                    @Override
                    public void run() {
                        mCameraTestHelper.setupCameraTest();
                    }
                });
                Log.v(TAG, "Setting focus mode to: " + supportedFocusModes.get(i));
                params.setFocusMode(supportedFocusModes.get(i));
                mCameraTestHelper.setParameters(params);
                mCameraTestHelper.startCameraPreview(surfaceHolder);
                mCameraTestHelper.capturePhoto();
            }
            mCameraTestHelper.cleanupTestImages();
        } catch (Exception e) {
            Log.e(TAG, e.toString());
            fail("Camera focus modes test Exception");
        }
    }

    /**
     * Functional test iterating on the various white balances (auto, daylight, cloudy, etc.)
     */
    @LargeTest
    public void testFunctionalCameraWhiteBalance() throws Exception {
        try {
            SurfaceHolder surfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
            Parameters params = mCameraTestHelper.getCameraParameters();
            List<String> supportedWhiteBalance = params.getSupportedWhiteBalance();
            assertNotNull("No white balance modes supported", supportedWhiteBalance);

            for (int i = 0; i < supportedWhiteBalance.size(); i++) {
                runOnLooper(new Runnable() {
                    @Override
                    public void run() {
                        mCameraTestHelper.setupCameraTest();
                    }
                });
                Log.v(TAG, "Setting white balance to: " + supportedWhiteBalance.get(i));
                params.setWhiteBalance(supportedWhiteBalance.get(i));
                mCameraTestHelper.setParameters(params);
                mCameraTestHelper.startCameraPreview(surfaceHolder);
                mCameraTestHelper.capturePhoto();
            }
            mCameraTestHelper.cleanupTestImages();
        } catch (Exception e) {
            Log.e(TAG, e.toString());
            fail("Camera focus modes test Exception");
        }
    }
}
+501 −0

File added.

Preview size limit exceeded, changes collapsed.

+64 −191

File changed.

Preview size limit exceeded, changes collapsed.

+6 −6

File changed.

Contains only whitespace changes.

Loading