CameraStressTest.java revision a784b3dea15dd0dfedfe25552b87fbb92a5eea52
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.mediaframeworktest.stress; 18 19import com.android.mediaframeworktest.MediaFrameworkTest; 20 21import java.io.BufferedWriter; 22import java.io.File; 23import java.io.FilenameFilter; 24import java.io.FileWriter; 25import java.io.FileNotFoundException; 26import java.io.FileOutputStream; 27import java.io.IOException; 28import java.io.Writer; 29import java.util.concurrent.Semaphore; 30import java.util.concurrent.TimeUnit; 31 32import android.hardware.Camera; 33import android.hardware.Camera.PictureCallback; 34import android.hardware.Camera.ShutterCallback; 35import android.os.Environment; 36import android.os.Handler; 37import android.os.Looper; 38import android.test.ActivityInstrumentationTestCase2; 39import android.test.suitebuilder.annotation.LargeTest; 40import android.util.Log; 41import android.view.SurfaceHolder; 42import com.android.mediaframeworktest.CameraStressTestRunner; 43 44import junit.framework.Assert; 45 46/** 47 * Junit / Instrumentation test case for the camera zoom api 48 * 49 * adb shell am instrument 50 * -e class com.android.mediaframeworktest.stress.CameraStressTest 51 * -w com.android.mediaframeworktest/.CameraStressTestRunner 52 */ 53public class CameraStressTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> { 54 private String TAG = "CameraStressTest"; 55 private Camera mCamera; 56 57 private static final int NUMBER_OF_ZOOM_LOOPS = 100; 58 private static final long WAIT_GENERIC = 3 * 1000; // 3 seconds 59 private static final long WAIT_TIMEOUT = 10 * 1000; // 10 seconds 60 private static final long WAIT_ZOOM_ANIMATION = 5 * 1000; // 5 seconds 61 private static final String CAMERA_STRESS_OUTPUT = 62 "/sdcard/cameraStressOutput.txt"; 63 private final CameraErrorCallback mCameraErrorCallback = new CameraErrorCallback(); 64 65 private Thread mLooperThread; 66 private Handler mHandler; 67 68 public CameraStressTest() { 69 super("com.android.mediaframeworktest", MediaFrameworkTest.class); 70 } 71 72 protected void setUp() throws Exception { 73 final Semaphore sem = new Semaphore(0); 74 mLooperThread = new Thread() { 75 @Override 76 public void run() { 77 Log.v(TAG, "starting looper"); 78 Looper.prepare(); 79 mHandler = new Handler(); 80 sem.release(); 81 Looper.loop(); 82 Log.v(TAG, "quit looper"); 83 } 84 }; 85 mLooperThread.start(); 86 if (!sem.tryAcquire(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)) { 87 fail("Failed to start the looper."); 88 } 89 getActivity(); 90 super.setUp(); 91 } 92 93 @Override 94 protected void tearDown() throws Exception { 95 if (mHandler != null) { 96 mHandler.getLooper().quit(); 97 mHandler = null; 98 } 99 if (mLooperThread != null) { 100 mLooperThread.join(WAIT_TIMEOUT); 101 if (mLooperThread.isAlive()) { 102 fail("Failed to stop the looper."); 103 } 104 mLooperThread = null; 105 } 106 107 super.tearDown(); 108 } 109 110 private void runOnLooper(final Runnable command) throws InterruptedException { 111 final Semaphore sem = new Semaphore(0); 112 mHandler.post(new Runnable() { 113 @Override 114 public void run() { 115 try { 116 command.run(); 117 } finally { 118 sem.release(); 119 } 120 } 121 }); 122 if (!sem.tryAcquire(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)) { 123 fail("Failed to run the command on the looper."); 124 } 125 } 126 127 private final class CameraErrorCallback implements android.hardware.Camera.ErrorCallback { 128 public void onError(int error, android.hardware.Camera camera) { 129 if (error == android.hardware.Camera.CAMERA_ERROR_SERVER_DIED) { 130 assertTrue("Camera test mediaserver died", false); 131 } 132 } 133 } 134 135 private ShutterCallback shutterCallback = new ShutterCallback() { 136 @Override 137 public void onShutter() { 138 Log.v(TAG, "Shutter"); 139 } 140 }; 141 142 private PictureCallback rawCallback = new PictureCallback() { 143 @Override 144 public void onPictureTaken(byte[] data, Camera camera) { 145 Log.v(TAG, "Raw picture taken"); 146 } 147 }; 148 149 private PictureCallback jpegCallback = new PictureCallback() { 150 @Override 151 public void onPictureTaken(byte[] data, Camera camera) { 152 FileOutputStream fos = null; 153 154 try { 155 Log.v(TAG, "JPEG picture taken"); 156 fos = new FileOutputStream(String.format("%s/zoom-test-%d.jpg", 157 Environment.getExternalStorageDirectory(), System.currentTimeMillis())); 158 fos.write(data); 159 } 160 catch (FileNotFoundException e) { 161 Log.v(TAG, "File not found: " + e.toString()); 162 } 163 catch (IOException e) { 164 Log.v(TAG, "Error accessing file: " + e.toString()); 165 } 166 finally { 167 try { 168 if (fos != null) { 169 fos.close(); 170 } 171 } 172 catch (IOException e) { 173 Log.v(TAG, "Error closing file: " + e.toString()); 174 } 175 } 176 } 177 }; 178 179 // Helper method for cleaning up pics taken during testStressCameraZoom 180 private void cleanupZoomImages() { 181 try { 182 File sdcard = Environment.getExternalStorageDirectory(); 183 File[] zoomImages = null; 184 185 FilenameFilter filter = new FilenameFilter() { 186 public boolean accept(File dir, String name) { 187 return name.startsWith("zoom-test-"); 188 } 189 }; 190 191 zoomImages = sdcard.listFiles(filter); 192 193 for (File f : zoomImages) { 194 f.delete(); 195 } 196 } 197 catch (SecurityException e) { 198 Log.v(TAG, "Security manager access violation: " + e.toString()); 199 } 200 } 201 202 // Test case for stressing the camera zoom in/out feature 203 @LargeTest 204 public void testStressCameraZoom() throws Exception { 205 SurfaceHolder mSurfaceHolder; 206 mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder(); 207 File stressOutFile = new File(CAMERA_STRESS_OUTPUT); 208 Writer output = new BufferedWriter(new FileWriter(stressOutFile, true)); 209 output.write("Camera zoom stress:\n"); 210 output.write("Total number of loops: " + NUMBER_OF_ZOOM_LOOPS + "\n"); 211 212 try { 213 Log.v(TAG, "Start preview"); 214 output.write("No of loop: "); 215 216 mCamera = Camera.open(); 217 Camera.Parameters params = mCamera.getParameters(); 218 mCamera.release(); 219 220 if (!params.isSmoothZoomSupported() && !params.isZoomSupported()) { 221 Log.v(TAG, "Device camera does not support zoom"); 222 assertTrue("Camera zoom stress test", false); 223 } 224 else { 225 Log.v(TAG, "Device camera does support zoom"); 226 227 int nextZoomLevel = 0; 228 229 for (int i = 0; i < NUMBER_OF_ZOOM_LOOPS; i++) { 230 runOnLooper(new Runnable() { 231 @Override 232 public void run() { 233 mCamera = Camera.open(); 234 } 235 }); 236 237 mCamera.setErrorCallback(mCameraErrorCallback); 238 mCamera.setPreviewDisplay(mSurfaceHolder); 239 mCamera.startPreview(); 240 Thread.sleep(WAIT_GENERIC); 241 242 params = mCamera.getParameters(); 243 int currentZoomLevel = params.getZoom(); 244 245 if (nextZoomLevel >= params.getMaxZoom()) { 246 nextZoomLevel = 0; 247 } 248 ++nextZoomLevel; 249 250 if (params.isSmoothZoomSupported()) { 251 mCamera.startSmoothZoom(nextZoomLevel); 252 } 253 else { 254 params.setZoom(nextZoomLevel); 255 mCamera.setParameters(params); 256 } 257 Log.v(TAG, "Zooming from " + currentZoomLevel + " to " + nextZoomLevel); 258 259 // sleep allows for zoom animation to finish 260 Thread.sleep(WAIT_ZOOM_ANIMATION); 261 262 // take picture 263 mCamera.takePicture(shutterCallback, rawCallback, jpegCallback); 264 Thread.sleep(WAIT_GENERIC); 265 mCamera.stopPreview(); 266 mCamera.release(); 267 output.write(" ," + i); 268 } 269 } 270 271 cleanupZoomImages(); 272 } 273 catch (Exception e) { 274 assertTrue("Camera zoom stress test Exception", false); 275 Log.v(TAG, e.toString()); 276 } 277 output.write("\n\n"); 278 output.close(); 279 } 280} 281