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
This commit is contained in:
committed by
Android (Google) Code Review
commit
b318f7b900
@@ -19,6 +19,8 @@ package com.android.mediaframeworktest;
|
|||||||
import android.test.InstrumentationTestRunner;
|
import android.test.InstrumentationTestRunner;
|
||||||
import android.test.InstrumentationTestSuite;
|
import android.test.InstrumentationTestSuite;
|
||||||
import com.android.mediaframeworktest.stress.CameraStressTest;
|
import com.android.mediaframeworktest.stress.CameraStressTest;
|
||||||
|
import com.android.mediaframeworktest.functional.camera.CameraFunctionalTest;
|
||||||
|
import com.android.mediaframeworktest.functional.camera.CameraPairwiseTest;
|
||||||
|
|
||||||
import junit.framework.TestSuite;
|
import junit.framework.TestSuite;
|
||||||
|
|
||||||
@@ -28,6 +30,8 @@ public class CameraStressTestRunner extends InstrumentationTestRunner {
|
|||||||
public TestSuite getAllTests() {
|
public TestSuite getAllTests() {
|
||||||
TestSuite suite = new InstrumentationTestSuite(this);
|
TestSuite suite = new InstrumentationTestSuite(this);
|
||||||
suite.addTestSuite(CameraStressTest.class);
|
suite.addTestSuite(CameraStressTest.class);
|
||||||
|
suite.addTestSuite(CameraFunctionalTest.class);
|
||||||
|
suite.addTestSuite(CameraPairwiseTest.class);
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,165 @@
|
|||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,255 @@
|
|||||||
|
/*
|
||||||
|
* 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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,501 @@
|
|||||||
|
/*
|
||||||
|
* 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 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.FloatMath;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.SurfaceHolder;
|
||||||
|
|
||||||
|
import java.util.concurrent.Semaphore;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.android.mediaframeworktest.MediaFrameworkTest;
|
||||||
|
import com.android.mediaframeworktest.CameraStressTestRunner;
|
||||||
|
import com.android.mediaframeworktest.CameraTestHelper;
|
||||||
|
import junit.framework.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Junit / Instrumentation test case for camera API pairwise testing
|
||||||
|
* Settings tested against: flash mode, exposure compensation, white balance,
|
||||||
|
* scene mode, picture size, and geotagging
|
||||||
|
*
|
||||||
|
* adb shell am instrument
|
||||||
|
* - e class com.android.mediaframeworktest.stress.CameraPairwiseTest
|
||||||
|
* - w com.android.mediaframeworktest/.CameraStressTestRunner
|
||||||
|
*/
|
||||||
|
public class CameraPairwiseTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
|
||||||
|
private CameraTestHelper mCameraTestHelper;
|
||||||
|
private Handler mHandler;
|
||||||
|
private Thread mLooperThread;
|
||||||
|
private String TAG = "CameraPairwiseTest";
|
||||||
|
|
||||||
|
private static final long WAIT_TIMEOUT = 10 * 1000; // 10 seconds
|
||||||
|
|
||||||
|
// coordinates of the Getty Museuem in Los Angeles
|
||||||
|
private static final double MOCK_LATITUDE = 34.076621;
|
||||||
|
private static final double MOCK_LONGITUDE = -118.473215;
|
||||||
|
|
||||||
|
// camera setting enums
|
||||||
|
public enum Flash { ON, OFF, AUTO };
|
||||||
|
public enum Exposure { MIN, MAX, NONE };
|
||||||
|
public enum WhiteBalance { DAYLIGHT, FLUORESCENT, CLOUDY, INCANDESCENT, AUTO };
|
||||||
|
public enum SceneMode { SUNSET, ACTION, PARTY, NIGHT, AUTO };
|
||||||
|
public enum PictureSize { SMALL, MEDIUM, LARGE };
|
||||||
|
public enum Geotagging { ON, OFF };
|
||||||
|
|
||||||
|
public CameraPairwiseTest() {
|
||||||
|
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.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flash: Auto / Exposure: None / WB: Daylight
|
||||||
|
* Scene: Sunset / Pic: Medium / Geo: off
|
||||||
|
*/
|
||||||
|
@LargeTest
|
||||||
|
public void testCameraPairwiseScenario01() throws Exception {
|
||||||
|
genericPairwiseTestCase(Flash.AUTO, Exposure.NONE, WhiteBalance.DAYLIGHT, SceneMode.SUNSET,
|
||||||
|
PictureSize.MEDIUM, Geotagging.OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flash: On / Exposure: Min / WB: Fluorescent
|
||||||
|
* Scene: Auto / Pic: Large / Geo: on
|
||||||
|
*/
|
||||||
|
@LargeTest
|
||||||
|
public void testCameraPairwiseScenario02() throws Exception {
|
||||||
|
genericPairwiseTestCase(Flash.ON, Exposure.MIN, WhiteBalance.FLUORESCENT, SceneMode.AUTO,
|
||||||
|
PictureSize.LARGE, Geotagging.ON);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flash: Off / Exposure: Max / WB: Auto
|
||||||
|
* Scene: Night / Pic: Small / Geo: on
|
||||||
|
*/
|
||||||
|
@LargeTest
|
||||||
|
public void testCameraPairwiseScenario03() throws Exception {
|
||||||
|
genericPairwiseTestCase(Flash.OFF, Exposure.MAX, WhiteBalance.AUTO, SceneMode.NIGHT,
|
||||||
|
PictureSize.SMALL, Geotagging.ON);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flash: Off / Exposure: Max / WB: Cloudy
|
||||||
|
* Scene: Auto / Pic: Med / Geo: off
|
||||||
|
*/
|
||||||
|
@LargeTest
|
||||||
|
public void testCameraPairwiseScenario04() throws Exception {
|
||||||
|
genericPairwiseTestCase(Flash.OFF, Exposure.MAX, WhiteBalance.CLOUDY, SceneMode.AUTO,
|
||||||
|
PictureSize.MEDIUM, Geotagging.OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flash: Auto / Exposure: Max / WB: Incandescent
|
||||||
|
* Scene: Auto / Pic: Large / Geo: off
|
||||||
|
*/
|
||||||
|
@LargeTest
|
||||||
|
public void testCameraPairwiseScenario05() throws Exception {
|
||||||
|
genericPairwiseTestCase(Flash.AUTO, Exposure.MAX, WhiteBalance.INCANDESCENT,
|
||||||
|
SceneMode.AUTO, PictureSize.LARGE, Geotagging.OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flash: On / Exposure: None / WB: Cloudy
|
||||||
|
* Scene: Auto / Pic: Small / Geo: on
|
||||||
|
*/
|
||||||
|
@LargeTest
|
||||||
|
public void testCameraPairwiseScenario06() throws Exception {
|
||||||
|
genericPairwiseTestCase(Flash.ON, Exposure.NONE, WhiteBalance.CLOUDY, SceneMode.AUTO,
|
||||||
|
PictureSize.SMALL, Geotagging.ON);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flash: Auto / Exposure: Min / WB: Auto
|
||||||
|
* Scene: Action / Pic: Small / Geo: on
|
||||||
|
*/
|
||||||
|
@LargeTest
|
||||||
|
public void testCameraPairwiseScenario07() throws Exception {
|
||||||
|
genericPairwiseTestCase(Flash.AUTO, Exposure.MIN, WhiteBalance.AUTO, SceneMode.ACTION,
|
||||||
|
PictureSize.SMALL, Geotagging.ON);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flash: On / Exposure: Min / WB: Auto
|
||||||
|
* Scene: Action / Pic: Medium / Geo: off
|
||||||
|
*/
|
||||||
|
@LargeTest
|
||||||
|
public void testCameraPairwiseScenario08() throws Exception {
|
||||||
|
genericPairwiseTestCase(Flash.ON, Exposure.MIN, WhiteBalance.AUTO, SceneMode.ACTION,
|
||||||
|
PictureSize.MEDIUM, Geotagging.OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flash: Off / Exposure: Min / WB: Auto
|
||||||
|
* Scene: Night / Pic: Large / Geo: off
|
||||||
|
*/
|
||||||
|
@LargeTest
|
||||||
|
public void testCameraPairwiseScenario09() throws Exception {
|
||||||
|
genericPairwiseTestCase(Flash.OFF, Exposure.MIN, WhiteBalance.AUTO, SceneMode.NIGHT,
|
||||||
|
PictureSize.LARGE, Geotagging.OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flash: Off / Exposure: Min / WB: Daylight
|
||||||
|
* Scene: Sunset / Pic: Small / Geo: off
|
||||||
|
*/
|
||||||
|
@LargeTest
|
||||||
|
public void testCameraPairwiseScenario10() throws Exception {
|
||||||
|
genericPairwiseTestCase(Flash.OFF, Exposure.MIN, WhiteBalance.DAYLIGHT, SceneMode.SUNSET,
|
||||||
|
PictureSize.SMALL, Geotagging.OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flash: On / Exposure: Max / WB: Daylight
|
||||||
|
* Scene: Sunset / Pic: Large / Geo: on
|
||||||
|
*/
|
||||||
|
@LargeTest
|
||||||
|
public void testCameraPairwiseScenario11() throws Exception {
|
||||||
|
genericPairwiseTestCase(Flash.ON, Exposure.MAX, WhiteBalance.DAYLIGHT, SceneMode.SUNSET,
|
||||||
|
PictureSize.LARGE, Geotagging.ON);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flash: Auto / Exposure: Min / WB: Cloudy
|
||||||
|
* Scene: Auto / Pic: Large / Geo: off
|
||||||
|
*/
|
||||||
|
@LargeTest
|
||||||
|
public void testCameraPairwiseScenario12() throws Exception {
|
||||||
|
genericPairwiseTestCase(Flash.AUTO, Exposure.MIN, WhiteBalance.CLOUDY, SceneMode.AUTO,
|
||||||
|
PictureSize.LARGE, Geotagging.OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flash: Off / Exposure: None / WB: Auto
|
||||||
|
* Scene: Party / Pic: Medium / Geo: on
|
||||||
|
*/
|
||||||
|
@LargeTest
|
||||||
|
public void testCameraPairwiseScenario13() throws Exception {
|
||||||
|
genericPairwiseTestCase(Flash.OFF, Exposure.NONE, WhiteBalance.AUTO, SceneMode.PARTY,
|
||||||
|
PictureSize.MEDIUM, Geotagging.ON);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flash: Auto / Exposure: None / WB: Auto
|
||||||
|
* Scene: Night / Pic: Small / Geo: off
|
||||||
|
*/
|
||||||
|
@LargeTest
|
||||||
|
public void testCameraPairwiseScenario14() throws Exception {
|
||||||
|
genericPairwiseTestCase(Flash.AUTO, Exposure.NONE, WhiteBalance.AUTO, SceneMode.NIGHT,
|
||||||
|
PictureSize.SMALL, Geotagging.OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flash: On / Exposure: None / WB: Incandescent
|
||||||
|
* Scene: Auto / Pic: Medium / Geo: on
|
||||||
|
*/
|
||||||
|
@LargeTest
|
||||||
|
public void testCameraPairwiseScenario15() throws Exception {
|
||||||
|
genericPairwiseTestCase(Flash.ON, Exposure.NONE, WhiteBalance.INCANDESCENT, SceneMode.AUTO,
|
||||||
|
PictureSize.MEDIUM, Geotagging.ON);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flash: Auto / Exposure: Min / WB: Auto
|
||||||
|
* Scene: Party / Pic: Small / Geo: off
|
||||||
|
*/
|
||||||
|
@LargeTest
|
||||||
|
public void testCameraPairwiseScenario16() throws Exception {
|
||||||
|
genericPairwiseTestCase(Flash.AUTO, Exposure.MIN, WhiteBalance.AUTO, SceneMode.PARTY,
|
||||||
|
PictureSize.SMALL, Geotagging.OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flash: Off / Exposure: Min / WB: Incandescent
|
||||||
|
* Scene: Auto / Pic: Small / Geo: off
|
||||||
|
*/
|
||||||
|
@LargeTest
|
||||||
|
public void testCameraPairwiseScenario17() throws Exception {
|
||||||
|
genericPairwiseTestCase(Flash.OFF, Exposure.MIN, WhiteBalance.INCANDESCENT, SceneMode.AUTO,
|
||||||
|
PictureSize.SMALL, Geotagging.OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flash: On / Exposure: None / WB: Auto
|
||||||
|
* Scene: Party / Pic: Large / Geo: off
|
||||||
|
*/
|
||||||
|
@LargeTest
|
||||||
|
public void testCameraPairwiseScenario18() throws Exception {
|
||||||
|
genericPairwiseTestCase(Flash.ON, Exposure.NONE, WhiteBalance.AUTO, SceneMode.PARTY,
|
||||||
|
PictureSize.LARGE, Geotagging.OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flash Off / Exposure: None / WB: Auto
|
||||||
|
* Scene: Action / Pic: Large / Geo: off
|
||||||
|
*/
|
||||||
|
@LargeTest
|
||||||
|
public void testCameraPairwiseScenario19() throws Exception {
|
||||||
|
genericPairwiseTestCase(Flash.OFF, Exposure.NONE, WhiteBalance.AUTO, SceneMode.ACTION,
|
||||||
|
PictureSize.LARGE, Geotagging.OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flash: Off / Exposure: Max / WB: Fluorescent
|
||||||
|
* Scene: Auto / Pic: Medium / Geo: Off
|
||||||
|
*/
|
||||||
|
@LargeTest
|
||||||
|
public void testCameraPairwiseScenario20() throws Exception {
|
||||||
|
genericPairwiseTestCase(Flash.OFF, Exposure.MAX, WhiteBalance.FLUORESCENT, SceneMode.AUTO,
|
||||||
|
PictureSize.MEDIUM, Geotagging.OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flash: Off / Exposure: Min / WB: Auto
|
||||||
|
* Scene: Auto / Pic: Medium / Geo: off
|
||||||
|
*/
|
||||||
|
public void testCameraPairwiseScenario21() throws Exception {
|
||||||
|
genericPairwiseTestCase(Flash.OFF, Exposure.MIN, WhiteBalance.AUTO, SceneMode.AUTO,
|
||||||
|
PictureSize.MEDIUM, Geotagging.OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flash: On / Exposure: Max / WB: Auto
|
||||||
|
* Scene: Action / Pic: Small / Geo: off
|
||||||
|
*/
|
||||||
|
public void testCameraPairwiseScenario22() throws Exception {
|
||||||
|
genericPairwiseTestCase(Flash.ON, Exposure.MAX, WhiteBalance.AUTO, SceneMode.ACTION,
|
||||||
|
PictureSize.SMALL, Geotagging.OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flash: On / Exposure: Max / WB: Auto
|
||||||
|
* Scene: Night / Pic: Medium / Geo: on
|
||||||
|
*/
|
||||||
|
public void testCameraPairwiseScenario23() throws Exception {
|
||||||
|
genericPairwiseTestCase(Flash.ON, Exposure.MAX, WhiteBalance.AUTO, SceneMode.NIGHT,
|
||||||
|
PictureSize.MEDIUM, Geotagging.ON);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flash: Auto / Exposure: None / WB: Fluorescent
|
||||||
|
* Scene: Auto / Pic: Small / Geo: on
|
||||||
|
*/
|
||||||
|
public void testCameraPairwiseScenario24() throws Exception {
|
||||||
|
genericPairwiseTestCase(Flash.AUTO, Exposure.NONE, WhiteBalance.FLUORESCENT,
|
||||||
|
SceneMode.AUTO, PictureSize.SMALL, Geotagging.ON);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flash: Auto / Exposure: Max / WB: Daylight
|
||||||
|
* Scene: Auto / Pic: Medium / Geo: off
|
||||||
|
*/
|
||||||
|
public void testCameraPairwiseScenario25() throws Exception {
|
||||||
|
genericPairwiseTestCase(Flash.AUTO, Exposure.MAX, WhiteBalance.DAYLIGHT, SceneMode.AUTO,
|
||||||
|
PictureSize.MEDIUM, Geotagging.OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flash: Auto / Exposure: Max / WB: Auto
|
||||||
|
* Scene: Party / Pic: Medium / Geo: on
|
||||||
|
*/
|
||||||
|
public void testCameraPairwiseScenario26() throws Exception {
|
||||||
|
genericPairwiseTestCase(Flash.AUTO, Exposure.MAX, WhiteBalance.AUTO, SceneMode.PARTY,
|
||||||
|
PictureSize.MEDIUM, Geotagging.ON);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic pairwise test method
|
||||||
|
*/
|
||||||
|
private void genericPairwiseTestCase(Flash flash, Exposure exposure, WhiteBalance whitebalance,
|
||||||
|
SceneMode scenemode, PictureSize picturesize, Geotagging geotagging) throws Exception {
|
||||||
|
try {
|
||||||
|
SurfaceHolder surfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
|
||||||
|
Camera.Parameters params = mCameraTestHelper.getCameraParameters();
|
||||||
|
|
||||||
|
runOnLooper(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mCameraTestHelper.setupCameraTest();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Configure flash setting
|
||||||
|
switch (flash) {
|
||||||
|
case ON:
|
||||||
|
params.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
|
||||||
|
break;
|
||||||
|
case OFF:
|
||||||
|
params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
|
||||||
|
break;
|
||||||
|
case AUTO:
|
||||||
|
params.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure exposure setting
|
||||||
|
switch (exposure) {
|
||||||
|
case MIN:
|
||||||
|
params.setExposureCompensation(params.getMinExposureCompensation());
|
||||||
|
break;
|
||||||
|
case MAX:
|
||||||
|
params.setExposureCompensation(params.getMaxExposureCompensation());
|
||||||
|
break;
|
||||||
|
case NONE:
|
||||||
|
params.setExposureCompensation(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure white balance setting
|
||||||
|
switch (whitebalance) {
|
||||||
|
case DAYLIGHT:
|
||||||
|
params.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_DAYLIGHT);
|
||||||
|
break;
|
||||||
|
case FLUORESCENT:
|
||||||
|
params.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_FLUORESCENT);
|
||||||
|
break;
|
||||||
|
case INCANDESCENT:
|
||||||
|
params.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_INCANDESCENT);
|
||||||
|
break;
|
||||||
|
case CLOUDY:
|
||||||
|
params.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT);
|
||||||
|
break;
|
||||||
|
case AUTO:
|
||||||
|
params.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_AUTO);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure scene mode setting
|
||||||
|
switch (scenemode) {
|
||||||
|
case SUNSET:
|
||||||
|
params.setSceneMode(Camera.Parameters.SCENE_MODE_SUNSET);
|
||||||
|
break;
|
||||||
|
case ACTION:
|
||||||
|
params.setSceneMode(Camera.Parameters.SCENE_MODE_ACTION);
|
||||||
|
break;
|
||||||
|
case PARTY:
|
||||||
|
params.setSceneMode(Camera.Parameters.SCENE_MODE_PARTY);
|
||||||
|
break;
|
||||||
|
case NIGHT:
|
||||||
|
params.setSceneMode(Camera.Parameters.SCENE_MODE_NIGHT);
|
||||||
|
break;
|
||||||
|
case AUTO:
|
||||||
|
params.setSceneMode(Camera.Parameters.SCENE_MODE_AUTO);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure picture size setting
|
||||||
|
List<Camera.Size> supportedPictureSizes = params.getSupportedPictureSizes();
|
||||||
|
int mid = (int) Math.floor(supportedPictureSizes.size() / 2);
|
||||||
|
int low = supportedPictureSizes.size() - 1;
|
||||||
|
switch (picturesize) {
|
||||||
|
case SMALL:
|
||||||
|
params.setPictureSize(supportedPictureSizes.get(low).width,
|
||||||
|
supportedPictureSizes.get(low).height);
|
||||||
|
break;
|
||||||
|
case MEDIUM:
|
||||||
|
params.setPictureSize(supportedPictureSizes.get(mid).width,
|
||||||
|
supportedPictureSizes.get(mid).height);
|
||||||
|
break;
|
||||||
|
case LARGE:
|
||||||
|
params.setPictureSize(supportedPictureSizes.get(0).width,
|
||||||
|
supportedPictureSizes.get(mid).height);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure geotagging setting
|
||||||
|
switch (geotagging) {
|
||||||
|
case ON:
|
||||||
|
params.setGpsLatitude(MOCK_LATITUDE);
|
||||||
|
params.setGpsLongitude(MOCK_LONGITUDE);
|
||||||
|
break;
|
||||||
|
case OFF:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
mCameraTestHelper.setParameters(params);
|
||||||
|
mCameraTestHelper.startCameraPreview(surfaceHolder);
|
||||||
|
mCameraTestHelper.capturePhoto();
|
||||||
|
mCameraTestHelper.cleanupTestImages();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, e.toString());
|
||||||
|
fail("Test case failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,13 +17,11 @@
|
|||||||
package com.android.mediaframeworktest.stress;
|
package com.android.mediaframeworktest.stress;
|
||||||
|
|
||||||
import com.android.mediaframeworktest.MediaFrameworkTest;
|
import com.android.mediaframeworktest.MediaFrameworkTest;
|
||||||
|
import com.android.mediaframeworktest.CameraTestHelper;
|
||||||
|
|
||||||
import java.io.BufferedWriter;
|
import java.io.BufferedWriter;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FilenameFilter;
|
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.util.concurrent.Semaphore;
|
import java.util.concurrent.Semaphore;
|
||||||
@@ -31,8 +29,7 @@ import java.util.concurrent.TimeUnit;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import android.hardware.Camera;
|
import android.hardware.Camera;
|
||||||
import android.hardware.Camera.PictureCallback;
|
import android.hardware.Camera.Parameters;
|
||||||
import android.hardware.Camera.ShutterCallback;
|
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
@@ -45,32 +42,28 @@ import com.android.mediaframeworktest.CameraStressTestRunner;
|
|||||||
import junit.framework.Assert;
|
import junit.framework.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Junit / Instrumentation test case for the camera zoom and scene mode APIs
|
* Junit / Instrumentation test case for the following camera APIs:
|
||||||
|
* - camera zoom
|
||||||
|
* - scene mode
|
||||||
*
|
*
|
||||||
* adb shell am instrument
|
* adb shell am instrument
|
||||||
* -e class com.android.mediaframeworktest.stress.CameraStressTest
|
* -e class com.android.mediaframeworktest.stress.CameraStressTest
|
||||||
* -w com.android.mediaframeworktest/.CameraStressTestRunner
|
* -w com.android.mediaframeworktest/.CameraStressTestRunner
|
||||||
*/
|
*/
|
||||||
public class CameraStressTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
|
public class CameraStressTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
|
||||||
private String TAG = "CameraStressTest";
|
|
||||||
private Camera mCamera;
|
|
||||||
|
|
||||||
private static final int CAMERA_ID = 0;
|
|
||||||
private static final int NUMBER_OF_ZOOM_LOOPS = 100;
|
|
||||||
private static final int NUMBER_OF_SCENE_MODE_LOOPS = 10;
|
private static final int NUMBER_OF_SCENE_MODE_LOOPS = 10;
|
||||||
private static final long WAIT_GENERIC = 3 * 1000; // 3 seconds
|
private static final int NUMBER_OF_ZOOM_LOOPS = 100;
|
||||||
private static final long WAIT_TIMEOUT = 10 * 1000; // 10 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_IMAGES_DIRECTORY = "cameraStressImages";
|
|
||||||
private static final String CAMERA_STRESS_IMAGES_PREFIX = "camera-stress-test";
|
|
||||||
private static final String CAMERA_STRESS_OUTPUT = "cameraStressOutput.txt";
|
private static final String CAMERA_STRESS_OUTPUT = "cameraStressOutput.txt";
|
||||||
private final CameraErrorCallback mCameraErrorCallback = new CameraErrorCallback();
|
|
||||||
|
|
||||||
private Thread mLooperThread;
|
private CameraTestHelper mCameraTestHelper;
|
||||||
private Handler mHandler;
|
private Handler mHandler;
|
||||||
|
private Thread mLooperThread;
|
||||||
private Writer mOutput;
|
private Writer mOutput;
|
||||||
|
|
||||||
|
private String TAG = "CameraStressTest";
|
||||||
|
|
||||||
public CameraStressTest() {
|
public CameraStressTest() {
|
||||||
super("com.android.mediaframeworktest", MediaFrameworkTest.class);
|
super("com.android.mediaframeworktest", MediaFrameworkTest.class);
|
||||||
}
|
}
|
||||||
@@ -95,19 +88,11 @@ public class CameraStressTest extends ActivityInstrumentationTestCase2<MediaFram
|
|||||||
getActivity();
|
getActivity();
|
||||||
super.setUp();
|
super.setUp();
|
||||||
|
|
||||||
File sdcard = Environment.getExternalStorageDirectory();
|
mCameraTestHelper = new CameraTestHelper();
|
||||||
|
File stressOutFile = new File(String.format("%s/%s",
|
||||||
// Create the test images directory if it doesn't exist
|
Environment.getExternalStorageDirectory(), CAMERA_STRESS_OUTPUT));
|
||||||
File stressImagesDirectory = new File(String.format("%s/%s", sdcard,
|
|
||||||
CAMERA_STRESS_IMAGES_DIRECTORY));
|
|
||||||
if (!stressImagesDirectory.exists()) {
|
|
||||||
stressImagesDirectory.mkdir();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start writing output file
|
|
||||||
File stressOutFile = new File(String.format("%s/%s",sdcard, CAMERA_STRESS_OUTPUT));
|
|
||||||
mOutput = new BufferedWriter(new FileWriter(stressOutFile, true));
|
mOutput = new BufferedWriter(new FileWriter(stressOutFile, true));
|
||||||
mOutput.write(this.getName() + ":\n");
|
mOutput.write(this.getName() + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -123,10 +108,8 @@ public class CameraStressTest extends ActivityInstrumentationTestCase2<MediaFram
|
|||||||
}
|
}
|
||||||
mLooperThread = null;
|
mLooperThread = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
mOutput.write("\n\n");
|
mOutput.write("\n\n");
|
||||||
mOutput.close();
|
mOutput.close();
|
||||||
|
|
||||||
super.tearDown();
|
super.tearDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,182 +130,14 @@ public class CameraStressTest extends ActivityInstrumentationTestCase2<MediaFram
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class CameraErrorCallback implements android.hardware.Camera.ErrorCallback {
|
/**
|
||||||
public void onError(int error, android.hardware.Camera camera) {
|
* Stress test iterating on the various scene modes (action, night, party, etc.)
|
||||||
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 cleaning up pics taken during testStressCameraZoom
|
|
||||||
private void cleanupStressTestImages() {
|
|
||||||
try {
|
|
||||||
File stressImagesDirectory = new File(String.format("%s/%s",
|
|
||||||
Environment.getExternalStorageDirectory(), CAMERA_STRESS_IMAGES_DIRECTORY));
|
|
||||||
File[] zoomImages = null;
|
|
||||||
|
|
||||||
FilenameFilter filter = new FilenameFilter() {
|
|
||||||
public boolean accept(File dir, String name) {
|
|
||||||
return name.startsWith(CAMERA_STRESS_IMAGES_PREFIX);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
zoomImages = stressImagesDirectory.listFiles(filter);
|
|
||||||
|
|
||||||
for (File f : zoomImages) {
|
|
||||||
f.delete();
|
|
||||||
}
|
|
||||||
} catch (SecurityException e) {
|
|
||||||
Log.e(TAG, "Security manager access violation: " + e.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper method for starting up the camera preview
|
|
||||||
private void startCameraPreview(SurfaceHolder surfaceHolder) {
|
|
||||||
try {
|
|
||||||
mCamera.setErrorCallback(mCameraErrorCallback);
|
|
||||||
mCamera.setPreviewDisplay(surfaceHolder);
|
|
||||||
mCamera.startPreview();
|
|
||||||
Thread.sleep(WAIT_GENERIC);
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, "Error setting preview display: " + e.toString());
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Log.e(TAG, "Error waiting for preview to come up: " + e.toString());
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, "Error starting up camera preview: " + e.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper method for taking a photo
|
|
||||||
private void capturePhoto() {
|
|
||||||
try {
|
|
||||||
mCamera.takePicture(shutterCallback, rawCallback, jpegCallback);
|
|
||||||
Thread.sleep(WAIT_GENERIC);
|
|
||||||
mCamera.stopPreview();
|
|
||||||
mCamera.release();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Log.e(TAG, "Error waiting for photo to be taken: " + e.toString());
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, "Error capturing photo: " + e.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test case for stressing the camera zoom in/out feature
|
|
||||||
@LargeTest
|
|
||||||
public void testStressCameraZoom() throws Exception {
|
|
||||||
SurfaceHolder mSurfaceHolder;
|
|
||||||
mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
|
|
||||||
mOutput.write("Total number of loops: " + NUMBER_OF_ZOOM_LOOPS + "\n");
|
|
||||||
|
|
||||||
try {
|
|
||||||
Log.v(TAG, "Start preview");
|
|
||||||
mOutput.write("No of loop: ");
|
|
||||||
|
|
||||||
mCamera = Camera.open(CAMERA_ID);
|
|
||||||
Camera.Parameters params = mCamera.getParameters();
|
|
||||||
mCamera.release();
|
|
||||||
|
|
||||||
if (!params.isSmoothZoomSupported() && !params.isZoomSupported()) {
|
|
||||||
Log.v(TAG, "Device camera does not support zoom");
|
|
||||||
fail("Camera zoom stress test failed");
|
|
||||||
} 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(CAMERA_ID);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
startCameraPreview(mSurfaceHolder);
|
|
||||||
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);
|
|
||||||
capturePhoto();
|
|
||||||
|
|
||||||
if (i == 0) {
|
|
||||||
mOutput.write(Integer.toString(i));
|
|
||||||
} else {
|
|
||||||
mOutput.write(", " + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cleanupStressTestImages();
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
fail("Camera zoom stress test Exception");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test case for stressing the camera scene mode feature
|
|
||||||
@LargeTest
|
@LargeTest
|
||||||
public void testStressCameraSceneModes() throws Exception {
|
public void testStressCameraSceneModes() throws Exception {
|
||||||
SurfaceHolder mSurfaceHolder;
|
|
||||||
mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mCamera = Camera.open(CAMERA_ID);
|
SurfaceHolder surfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
|
||||||
Camera.Parameters params = mCamera.getParameters();
|
Parameters params = mCameraTestHelper.getCameraParameters();
|
||||||
mCamera.release();
|
|
||||||
List<String> supportedSceneModes = params.getSupportedSceneModes();
|
List<String> supportedSceneModes = params.getSupportedSceneModes();
|
||||||
assertNotNull("No scene modes supported", supportedSceneModes);
|
assertNotNull("No scene modes supported", supportedSceneModes);
|
||||||
|
|
||||||
@@ -336,27 +151,85 @@ public class CameraStressTest extends ActivityInstrumentationTestCase2<MediaFram
|
|||||||
runOnLooper(new Runnable() {
|
runOnLooper(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
mCamera = Camera.open(CAMERA_ID);
|
mCameraTestHelper.setupCameraTest();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Log.v(TAG, "Setting scene mode to " + supportedSceneModes.get(i));
|
||||||
startCameraPreview(mSurfaceHolder);
|
|
||||||
Log.v(TAG, "Setting mode to " + supportedSceneModes.get(i));
|
|
||||||
params.setSceneMode(supportedSceneModes.get(i));
|
params.setSceneMode(supportedSceneModes.get(i));
|
||||||
mCamera.setParameters(params);
|
mCameraTestHelper.setParameters(params);
|
||||||
capturePhoto();
|
mCameraTestHelper.startCameraPreview(surfaceHolder);
|
||||||
|
mCameraTestHelper.capturePhoto();
|
||||||
|
|
||||||
if ((i == 0) && (j == 0)) {
|
if (i == 0 && j == 0) {
|
||||||
mOutput.write(Integer.toString(j + i * NUMBER_OF_SCENE_MODE_LOOPS));
|
mOutput.write(Integer.toString(j + i * NUMBER_OF_SCENE_MODE_LOOPS));
|
||||||
} else {
|
} else {
|
||||||
mOutput.write(", " + (j + i * NUMBER_OF_SCENE_MODE_LOOPS));
|
mOutput.write(", " + (j + i * NUMBER_OF_SCENE_MODE_LOOPS));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cleanupStressTestImages();
|
mCameraTestHelper.cleanupTestImages();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, e.toString());
|
Log.e(TAG, e.toString());
|
||||||
fail("Camera scene mode test Exception");
|
fail("Camera scene mode test Exception");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stress test iterating on the range of supported camera zoom levels
|
||||||
|
*/
|
||||||
|
@LargeTest
|
||||||
|
public void testStressCameraZoom() throws Exception {
|
||||||
|
try {
|
||||||
|
SurfaceHolder surfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
|
||||||
|
Parameters params = mCameraTestHelper.getCameraParameters();
|
||||||
|
|
||||||
|
if (!params.isSmoothZoomSupported() && !params.isZoomSupported()) {
|
||||||
|
Log.v(TAG, "Device camera does not support zoom");
|
||||||
|
fail("Camera zoom stress test failed due to unsupported feature");
|
||||||
|
} else {
|
||||||
|
Log.v(TAG, "Device camera does support zoom");
|
||||||
|
Log.v(TAG, "Start preview");
|
||||||
|
mOutput.write("Total number of loops: " + NUMBER_OF_ZOOM_LOOPS + "\n");
|
||||||
|
mOutput.write("No of loops: ");
|
||||||
|
|
||||||
|
int nextZoomLevel = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < NUMBER_OF_ZOOM_LOOPS; i++) {
|
||||||
|
runOnLooper(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mCameraTestHelper.setupCameraTest();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mCameraTestHelper.startCameraPreview(surfaceHolder);
|
||||||
|
params = mCameraTestHelper.mCamera.getParameters();
|
||||||
|
int currentZoomLevel = params.getZoom();
|
||||||
|
|
||||||
|
if (nextZoomLevel >= params.getMaxZoom()) {
|
||||||
|
nextZoomLevel = 0;
|
||||||
|
}
|
||||||
|
++nextZoomLevel;
|
||||||
|
|
||||||
|
if (params.isSmoothZoomSupported()) {
|
||||||
|
mCameraTestHelper.mCamera.startSmoothZoom(nextZoomLevel);
|
||||||
|
} else {
|
||||||
|
params.setZoom(nextZoomLevel);
|
||||||
|
mCameraTestHelper.setParameters(params);
|
||||||
|
}
|
||||||
|
mCameraTestHelper.capturePhoto();
|
||||||
|
|
||||||
|
if (i == 0) {
|
||||||
|
mOutput.write(Integer.toString(i));
|
||||||
|
} else {
|
||||||
|
mOutput.write(", " + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mCameraTestHelper.cleanupTestImages();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, e.toString());
|
||||||
|
fail("Camera zoom stress test Exception");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user