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

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

am a5408a8c: am 34a4e519: am 6e6d8df5: Merge "Adding camera zoom test to...

am a5408a8c: am 34a4e519: am 6e6d8df5: Merge "Adding camera zoom test to mediaframework stress suite." into ics-mr1

* commit 'a5408a8c':
  Adding camera zoom test to mediaframework stress suite.
parents 6756f74d a5408a8c
Loading
Loading
Loading
Loading
+13 −7
Original line number Original line Diff line number Diff line
@@ -35,6 +35,12 @@
            </intent-filter>
            </intent-filter>
        </activity>
        </activity>
    </application>
    </application>

    <instrumentation android:name=".CameraStressTestRunner"
        android:targetPackage="com.android.mediaframeworktest"
        android:label="Camera stress tests InstrumentationRunner">
    </instrumentation>

    <instrumentation android:name=".MediaFrameworkTestRunner"
    <instrumentation android:name=".MediaFrameworkTestRunner"
         android:targetPackage="com.android.mediaframeworktest"
         android:targetPackage="com.android.mediaframeworktest"
         android:label="MediaFramework tests InstrumentationRunner">
         android:label="MediaFramework tests InstrumentationRunner">
+38 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2012 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.test.InstrumentationTestRunner;
import android.test.InstrumentationTestSuite;
import com.android.mediaframeworktest.stress.CameraStressTest;

import junit.framework.TestSuite;

public class CameraStressTestRunner extends InstrumentationTestRunner {

    @Override
    public TestSuite getAllTests() {
        TestSuite suite = new InstrumentationTestSuite(this);
        suite.addTestSuite(CameraStressTest.class);
        return suite;
    }

    @Override
    public ClassLoader getLoader() {
        return CameraStressTestRunner.class.getClassLoader();
    }
}
+280 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2012 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.stress;

import com.android.mediaframeworktest.MediaFrameworkTest;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FilenameFilter;
import java.io.FileWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.Writer;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
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.Log;
import android.view.SurfaceHolder;
import com.android.mediaframeworktest.CameraStressTestRunner;

import junit.framework.Assert;

/**
 * Junit / Instrumentation test case for the camera zoom api
 *
 * adb shell am instrument
 *  -e class com.android.mediaframeworktest.stress.CameraStressTest
 *  -w com.android.mediaframeworktest/.CameraStressTestRunner
 */
public class CameraStressTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
    private String TAG = "CameraStressTest";
    private Camera mCamera;

    private static final int NUMBER_OF_ZOOM_LOOPS = 100;
    private static final long WAIT_GENERIC = 3 * 1000; // 3 seconds
    private static final long WAIT_TIMEOUT = 10 * 1000; // 10 seconds
    private static final long WAIT_ZOOM_ANIMATION = 5 * 1000; // 5 seconds
    private static final String CAMERA_STRESS_OUTPUT =
            "/sdcard/cameraStressOutput.txt";
    private final CameraErrorCallback mCameraErrorCallback = new CameraErrorCallback();

    private Thread mLooperThread;
    private Handler mHandler;

    public CameraStressTest() {
        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();
    }

    @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.");
        }
    }

    private final class CameraErrorCallback implements android.hardware.Camera.ErrorCallback {
        public void onError(int error, android.hardware.Camera camera) {
            if (error == android.hardware.Camera.CAMERA_ERROR_SERVER_DIED) {
                assertTrue("Camera test mediaserver died", false);
            }
        }
    }

    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/zoom-test-%d.jpg",
                        Environment.getExternalStorageDirectory(), System.currentTimeMillis()));
                fos.write(data);
            }
            catch (FileNotFoundException e) {
                Log.v(TAG, "File not found: " + e.toString());
            }
            catch (IOException e) {
                Log.v(TAG, "Error accessing file: " + e.toString());
            }
            finally {
                try {
                    if (fos != null) {
                        fos.close();
                    }
                }
                catch (IOException e) {
                    Log.v(TAG, "Error closing file: " + e.toString();
                }
            }
        }
    };

    // Helper method for cleaning up pics taken during testStressCameraZoom
    private void cleanupZoomImages() {
        try {
            File sdcard = Environment.getExternalStorageDirectory();
            File[] zoomImages = null;

            FilenameFilter filter = new FilenameFilter() {
                public boolean accept(File dir, String name) {
                    return name.startsWith("zoom-test-");
                }
            };

            zoomImages = sdcard.listFiles(filter);

            for (File f : zoomImages) {
                f.delete();
            }
        }
        catch (SecurityException e) {
            Log.v(TAG, "Security manager access violation: " + e.toString());
        }
    }

    // Test case for stressing the camera zoom in/out feature
    @LargeTest
    public void testStressCameraZoom() throws Exception {
        SurfaceHolder mSurfaceHolder;
        mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
        File stressOutFile = new File(CAMERA_STRESS_OUTPUT);
        Writer output = new BufferedWriter(new FileWriter(stressOutFile, true));
        output.write("Camera zoom stress:\n");
        output.write("Total number of loops: " +  NUMBER_OF_ZOOM_LOOPS + "\n");

        try {
            Log.v(TAG, "Start preview");
            output.write("No of loop: ");

            mCamera = Camera.open();
            Camera.Parameters params = mCamera.getParameters();
            mCamera.release();

            if (!params.isSmoothZoomSupported() && !params.isZoomSupported()) {
                Log.v(TAG, "Device camera does not support zoom");
                assertTrue("Camera zoom stress test", false);
            }
            else {
                Log.v(TAG, "Device camera does support zoom");

                int nextZoomLevel = 0;

                for (int i = 0; i < NUMBER_OF_ZOOM_LOOPS; i++) {
                    runOnLooper(new Runnable() {
                        @Override
                        public void run() {
                            mCamera = Camera.open();
                        }
                    });

                    mCamera.setErrorCallback(mCameraErrorCallback);
                    mCamera.setPreviewDisplay(mSurfaceHolder);
                    mCamera.startPreview();
                    Thread.sleep(WAIT_GENERIC);

                    params = mCamera.getParameters();
                    int currentZoomLevel = params.getZoom();

                    if (nextZoomLevel >= params.getMaxZoom()) {
                        nextZoomLevel = 0;
                    }
                    ++nextZoomLevel;

                    if (params.isSmoothZoomSupported()) {
                        mCamera.startSmoothZoom(nextZoomLevel);
                    }
                    else {
                        params.setZoom(nextZoomLevel);
                        mCamera.setParameters(params);
                    }
                    Log.v(TAG, "Zooming from " + currentZoomLevel + " to " + nextZoomLevel);

                    // sleep allows for zoom animation to finish
                    Thread.sleep(WAIT_ZOOM_ANIMATION);

                    // take picture
                    mCamera.takePicture(shutterCallback, rawCallback, jpegCallback);
                    Thread.sleep(WAIT_GENERIC);
                    mCamera.stopPreview();
                    mCamera.release();
                    output.write(" ," + i);
                }
            }

            cleanupZoomImages();
        }
        catch (Exception e) {
            assertTrue("Camera zoom stress test Exception", false);
            Log.v(TAG, e.toString());
        }
        output.write("\n\n");
        output.close();
    }
}