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

Commit c6cedc84 authored by Jason Noguchi's avatar Jason Noguchi
Browse files

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.

Slight refactor to add camera test helper and also additional
tests for: flash, exposure, white balance, and focus mode

Bug: 9174937

Change-Id: I3d26b545dc8ff972c8173066df59a2e572a837ef
parent eed8411c
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