1 /* 2 * Copyright (C) 2013 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 17 package com.android.mediaframeworktest.functional.camera; 18 19 import android.hardware.Camera; 20 import android.hardware.Camera.PictureCallback; 21 import android.hardware.Camera.ShutterCallback; 22 import android.os.Environment; 23 import android.os.Handler; 24 import android.os.Looper; 25 import android.test.ActivityInstrumentationTestCase2; 26 import android.test.suitebuilder.annotation.LargeTest; 27 import android.util.FloatMath; 28 import android.util.Log; 29 import android.view.SurfaceHolder; 30 31 import java.util.concurrent.Semaphore; 32 import java.util.concurrent.TimeUnit; 33 import java.util.List; 34 35 import com.android.mediaframeworktest.MediaFrameworkTest; 36 import com.android.mediaframeworktest.CameraStressTestRunner; 37 import com.android.mediaframeworktest.CameraTestHelper; 38 import junit.framework.Assert; 39 40 /** 41 * Junit / Instrumentation test case for camera API pairwise testing 42 * Settings tested against: flash mode, exposure compensation, white balance, 43 * scene mode, picture size, and geotagging 44 * 45 * adb shell am instrument 46 * - e class com.android.mediaframeworktest.stress.CameraPairwiseTest 47 * - w com.android.mediaframeworktest/.CameraStressTestRunner 48 */ 49 public class CameraPairwiseTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> { 50 private CameraTestHelper mCameraTestHelper; 51 private Handler mHandler; 52 private Thread mLooperThread; 53 private String TAG = "CameraPairwiseTest"; 54 55 private static final long WAIT_TIMEOUT = 10 * 1000; // 10 seconds 56 57 // coordinates of the Getty Museuem in Los Angeles 58 private static final double MOCK_LATITUDE = 34.076621; 59 private static final double MOCK_LONGITUDE = -118.473215; 60 61 // camera setting enums 62 public enum Flash { ON, OFF, AUTO }; 63 public enum Exposure { MIN, MAX, NONE }; 64 public enum WhiteBalance { DAYLIGHT, FLUORESCENT, CLOUDY, INCANDESCENT, AUTO }; 65 public enum SceneMode { SUNSET, ACTION, PARTY, NIGHT, AUTO }; 66 public enum PictureSize { SMALL, MEDIUM, LARGE }; 67 public enum Geotagging { ON, OFF }; 68 69 public CameraPairwiseTest() { 70 super("com.android.mediaframeworktest", MediaFrameworkTest.class); 71 } 72 73 protected void setUp() throws Exception { 74 final Semaphore sem = new Semaphore(0); 75 mLooperThread = new Thread() { 76 @Override 77 public void run() { 78 Log.v(TAG, "starting looper"); 79 Looper.prepare(); 80 mHandler = new Handler(); 81 sem.release(); 82 Looper.loop(); 83 Log.v(TAG, "quit looper"); 84 } 85 }; 86 mLooperThread.start(); 87 if (!sem.tryAcquire(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)) { 88 fail("Failed to start the looper."); 89 } 90 getActivity(); 91 super.setUp(); 92 93 mCameraTestHelper = new CameraTestHelper(); 94 } 95 96 @Override 97 protected void tearDown() throws Exception { 98 if (mHandler != null) { 99 mHandler.getLooper().quit(); 100 mHandler = null; 101 } 102 if (mLooperThread != null) { 103 mLooperThread.join(WAIT_TIMEOUT); 104 if (mLooperThread.isAlive()) { 105 fail("Failed to stop the looper."); 106 } 107 mLooperThread = null; 108 } 109 super.tearDown(); 110 } 111 112 private void runOnLooper(final Runnable command) throws InterruptedException { 113 final Semaphore sem = new Semaphore(0); 114 mHandler.post(new Runnable() { 115 @Override 116 public void run() { 117 try { 118 command.run(); 119 } finally { 120 sem.release(); 121 } 122 } 123 }); 124 if (!sem.tryAcquire(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)) { 125 fail("Failed to run the command on the looper."); 126 } 127 } 128 129 /** 130 * Flash: Auto / Exposure: None / WB: Daylight 131 * Scene: Sunset / Pic: Medium / Geo: off 132 */ 133 @LargeTest 134 public void testCameraPairwiseScenario01() throws Exception { 135 genericPairwiseTestCase(Flash.AUTO, Exposure.NONE, WhiteBalance.DAYLIGHT, SceneMode.SUNSET, 136 PictureSize.MEDIUM, Geotagging.OFF); 137 } 138 139 /** 140 * Flash: On / Exposure: Min / WB: Fluorescent 141 * Scene: Auto / Pic: Large / Geo: on 142 */ 143 @LargeTest 144 public void testCameraPairwiseScenario02() throws Exception { 145 genericPairwiseTestCase(Flash.ON, Exposure.MIN, WhiteBalance.FLUORESCENT, SceneMode.AUTO, 146 PictureSize.LARGE, Geotagging.ON); 147 } 148 149 /** 150 * Flash: Off / Exposure: Max / WB: Auto 151 * Scene: Night / Pic: Small / Geo: on 152 */ 153 @LargeTest 154 public void testCameraPairwiseScenario03() throws Exception { 155 genericPairwiseTestCase(Flash.OFF, Exposure.MAX, WhiteBalance.AUTO, SceneMode.NIGHT, 156 PictureSize.SMALL, Geotagging.ON); 157 } 158 159 /** 160 * Flash: Off / Exposure: Max / WB: Cloudy 161 * Scene: Auto / Pic: Med / Geo: off 162 */ 163 @LargeTest 164 public void testCameraPairwiseScenario04() throws Exception { 165 genericPairwiseTestCase(Flash.OFF, Exposure.MAX, WhiteBalance.CLOUDY, SceneMode.AUTO, 166 PictureSize.MEDIUM, Geotagging.OFF); 167 } 168 169 /** 170 * Flash: Auto / Exposure: Max / WB: Incandescent 171 * Scene: Auto / Pic: Large / Geo: off 172 */ 173 @LargeTest 174 public void testCameraPairwiseScenario05() throws Exception { 175 genericPairwiseTestCase(Flash.AUTO, Exposure.MAX, WhiteBalance.INCANDESCENT, 176 SceneMode.AUTO, PictureSize.LARGE, Geotagging.OFF); 177 } 178 179 /** 180 * Flash: On / Exposure: None / WB: Cloudy 181 * Scene: Auto / Pic: Small / Geo: on 182 */ 183 @LargeTest 184 public void testCameraPairwiseScenario06() throws Exception { 185 genericPairwiseTestCase(Flash.ON, Exposure.NONE, WhiteBalance.CLOUDY, SceneMode.AUTO, 186 PictureSize.SMALL, Geotagging.ON); 187 } 188 189 /** 190 * Flash: Auto / Exposure: Min / WB: Auto 191 * Scene: Action / Pic: Small / Geo: on 192 */ 193 @LargeTest 194 public void testCameraPairwiseScenario07() throws Exception { 195 genericPairwiseTestCase(Flash.AUTO, Exposure.MIN, WhiteBalance.AUTO, SceneMode.ACTION, 196 PictureSize.SMALL, Geotagging.ON); 197 } 198 199 /** 200 * Flash: On / Exposure: Min / WB: Auto 201 * Scene: Action / Pic: Medium / Geo: off 202 */ 203 @LargeTest 204 public void testCameraPairwiseScenario08() throws Exception { 205 genericPairwiseTestCase(Flash.ON, Exposure.MIN, WhiteBalance.AUTO, SceneMode.ACTION, 206 PictureSize.MEDIUM, Geotagging.OFF); 207 } 208 209 /** 210 * Flash: Off / Exposure: Min / WB: Auto 211 * Scene: Night / Pic: Large / Geo: off 212 */ 213 @LargeTest 214 public void testCameraPairwiseScenario09() throws Exception { 215 genericPairwiseTestCase(Flash.OFF, Exposure.MIN, WhiteBalance.AUTO, SceneMode.NIGHT, 216 PictureSize.LARGE, Geotagging.OFF); 217 } 218 219 /** 220 * Flash: Off / Exposure: Min / WB: Daylight 221 * Scene: Sunset / Pic: Small / Geo: off 222 */ 223 @LargeTest 224 public void testCameraPairwiseScenario10() throws Exception { 225 genericPairwiseTestCase(Flash.OFF, Exposure.MIN, WhiteBalance.DAYLIGHT, SceneMode.SUNSET, 226 PictureSize.SMALL, Geotagging.OFF); 227 } 228 229 /** 230 * Flash: On / Exposure: Max / WB: Daylight 231 * Scene: Sunset / Pic: Large / Geo: on 232 */ 233 @LargeTest 234 public void testCameraPairwiseScenario11() throws Exception { 235 genericPairwiseTestCase(Flash.ON, Exposure.MAX, WhiteBalance.DAYLIGHT, SceneMode.SUNSET, 236 PictureSize.LARGE, Geotagging.ON); 237 } 238 239 /** 240 * Flash: Auto / Exposure: Min / WB: Cloudy 241 * Scene: Auto / Pic: Large / Geo: off 242 */ 243 @LargeTest 244 public void testCameraPairwiseScenario12() throws Exception { 245 genericPairwiseTestCase(Flash.AUTO, Exposure.MIN, WhiteBalance.CLOUDY, SceneMode.AUTO, 246 PictureSize.LARGE, Geotagging.OFF); 247 } 248 249 /** 250 * Flash: Off / Exposure: None / WB: Auto 251 * Scene: Party / Pic: Medium / Geo: on 252 */ 253 @LargeTest 254 public void testCameraPairwiseScenario13() throws Exception { 255 genericPairwiseTestCase(Flash.OFF, Exposure.NONE, WhiteBalance.AUTO, SceneMode.PARTY, 256 PictureSize.MEDIUM, Geotagging.ON); 257 } 258 259 /** 260 * Flash: Auto / Exposure: None / WB: Auto 261 * Scene: Night / Pic: Small / Geo: off 262 */ 263 @LargeTest 264 public void testCameraPairwiseScenario14() throws Exception { 265 genericPairwiseTestCase(Flash.AUTO, Exposure.NONE, WhiteBalance.AUTO, SceneMode.NIGHT, 266 PictureSize.SMALL, Geotagging.OFF); 267 } 268 269 /** 270 * Flash: On / Exposure: None / WB: Incandescent 271 * Scene: Auto / Pic: Medium / Geo: on 272 */ 273 @LargeTest 274 public void testCameraPairwiseScenario15() throws Exception { 275 genericPairwiseTestCase(Flash.ON, Exposure.NONE, WhiteBalance.INCANDESCENT, SceneMode.AUTO, 276 PictureSize.MEDIUM, Geotagging.ON); 277 } 278 279 /** 280 * Flash: Auto / Exposure: Min / WB: Auto 281 * Scene: Party / Pic: Small / Geo: off 282 */ 283 @LargeTest 284 public void testCameraPairwiseScenario16() throws Exception { 285 genericPairwiseTestCase(Flash.AUTO, Exposure.MIN, WhiteBalance.AUTO, SceneMode.PARTY, 286 PictureSize.SMALL, Geotagging.OFF); 287 } 288 289 /** 290 * Flash: Off / Exposure: Min / WB: Incandescent 291 * Scene: Auto / Pic: Small / Geo: off 292 */ 293 @LargeTest 294 public void testCameraPairwiseScenario17() throws Exception { 295 genericPairwiseTestCase(Flash.OFF, Exposure.MIN, WhiteBalance.INCANDESCENT, SceneMode.AUTO, 296 PictureSize.SMALL, Geotagging.OFF); 297 } 298 299 /** 300 * Flash: On / Exposure: None / WB: Auto 301 * Scene: Party / Pic: Large / Geo: off 302 */ 303 @LargeTest 304 public void testCameraPairwiseScenario18() throws Exception { 305 genericPairwiseTestCase(Flash.ON, Exposure.NONE, WhiteBalance.AUTO, SceneMode.PARTY, 306 PictureSize.LARGE, Geotagging.OFF); 307 } 308 309 /** 310 * Flash Off / Exposure: None / WB: Auto 311 * Scene: Action / Pic: Large / Geo: off 312 */ 313 @LargeTest 314 public void testCameraPairwiseScenario19() throws Exception { 315 genericPairwiseTestCase(Flash.OFF, Exposure.NONE, WhiteBalance.AUTO, SceneMode.ACTION, 316 PictureSize.LARGE, Geotagging.OFF); 317 } 318 319 /** 320 * Flash: Off / Exposure: Max / WB: Fluorescent 321 * Scene: Auto / Pic: Medium / Geo: Off 322 */ 323 @LargeTest 324 public void testCameraPairwiseScenario20() throws Exception { 325 genericPairwiseTestCase(Flash.OFF, Exposure.MAX, WhiteBalance.FLUORESCENT, SceneMode.AUTO, 326 PictureSize.MEDIUM, Geotagging.OFF); 327 } 328 329 /** 330 * Flash: Off / Exposure: Min / WB: Auto 331 * Scene: Auto / Pic: Medium / Geo: off 332 */ 333 public void testCameraPairwiseScenario21() throws Exception { 334 genericPairwiseTestCase(Flash.OFF, Exposure.MIN, WhiteBalance.AUTO, SceneMode.AUTO, 335 PictureSize.MEDIUM, Geotagging.OFF); 336 } 337 338 /** 339 * Flash: On / Exposure: Max / WB: Auto 340 * Scene: Action / Pic: Small / Geo: off 341 */ 342 public void testCameraPairwiseScenario22() throws Exception { 343 genericPairwiseTestCase(Flash.ON, Exposure.MAX, WhiteBalance.AUTO, SceneMode.ACTION, 344 PictureSize.SMALL, Geotagging.OFF); 345 } 346 347 /** 348 * Flash: On / Exposure: Max / WB: Auto 349 * Scene: Night / Pic: Medium / Geo: on 350 */ 351 public void testCameraPairwiseScenario23() throws Exception { 352 genericPairwiseTestCase(Flash.ON, Exposure.MAX, WhiteBalance.AUTO, SceneMode.NIGHT, 353 PictureSize.MEDIUM, Geotagging.ON); 354 } 355 356 /** 357 * Flash: Auto / Exposure: None / WB: Fluorescent 358 * Scene: Auto / Pic: Small / Geo: on 359 */ 360 public void testCameraPairwiseScenario24() throws Exception { 361 genericPairwiseTestCase(Flash.AUTO, Exposure.NONE, WhiteBalance.FLUORESCENT, 362 SceneMode.AUTO, PictureSize.SMALL, Geotagging.ON); 363 } 364 365 /** 366 * Flash: Auto / Exposure: Max / WB: Daylight 367 * Scene: Auto / Pic: Medium / Geo: off 368 */ 369 public void testCameraPairwiseScenario25() throws Exception { 370 genericPairwiseTestCase(Flash.AUTO, Exposure.MAX, WhiteBalance.DAYLIGHT, SceneMode.AUTO, 371 PictureSize.MEDIUM, Geotagging.OFF); 372 } 373 374 /** 375 * Flash: Auto / Exposure: Max / WB: Auto 376 * Scene: Party / Pic: Medium / Geo: on 377 */ 378 public void testCameraPairwiseScenario26() throws Exception { 379 genericPairwiseTestCase(Flash.AUTO, Exposure.MAX, WhiteBalance.AUTO, SceneMode.PARTY, 380 PictureSize.MEDIUM, Geotagging.ON); 381 } 382 383 /** 384 * Generic pairwise test method 385 */ 386 private void genericPairwiseTestCase(Flash flash, Exposure exposure, WhiteBalance whitebalance, 387 SceneMode scenemode, PictureSize picturesize, Geotagging geotagging) throws Exception { 388 try { 389 SurfaceHolder surfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder(); 390 Camera.Parameters params = mCameraTestHelper.getCameraParameters(); 391 392 runOnLooper(new Runnable() { 393 @Override 394 public void run() { 395 mCameraTestHelper.setupCameraTest(); 396 } 397 }); 398 399 // Configure flash setting 400 switch (flash) { 401 case ON: 402 params.setFlashMode(Camera.Parameters.FLASH_MODE_ON); 403 break; 404 case OFF: 405 params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); 406 break; 407 case AUTO: 408 params.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO); 409 break; 410 } 411 412 // Configure exposure setting 413 switch (exposure) { 414 case MIN: 415 params.setExposureCompensation(params.getMinExposureCompensation()); 416 break; 417 case MAX: 418 params.setExposureCompensation(params.getMaxExposureCompensation()); 419 break; 420 case NONE: 421 params.setExposureCompensation(0); 422 break; 423 } 424 425 // Configure white balance setting 426 switch (whitebalance) { 427 case DAYLIGHT: 428 params.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_DAYLIGHT); 429 break; 430 case FLUORESCENT: 431 params.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_FLUORESCENT); 432 break; 433 case INCANDESCENT: 434 params.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_INCANDESCENT); 435 break; 436 case CLOUDY: 437 params.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT); 438 break; 439 case AUTO: 440 params.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_AUTO); 441 break; 442 } 443 444 // Configure scene mode setting 445 switch (scenemode) { 446 case SUNSET: 447 params.setSceneMode(Camera.Parameters.SCENE_MODE_SUNSET); 448 break; 449 case ACTION: 450 params.setSceneMode(Camera.Parameters.SCENE_MODE_ACTION); 451 break; 452 case PARTY: 453 params.setSceneMode(Camera.Parameters.SCENE_MODE_PARTY); 454 break; 455 case NIGHT: 456 params.setSceneMode(Camera.Parameters.SCENE_MODE_NIGHT); 457 break; 458 case AUTO: 459 params.setSceneMode(Camera.Parameters.SCENE_MODE_AUTO); 460 break; 461 } 462 463 // Configure picture size setting 464 List<Camera.Size> supportedPictureSizes = params.getSupportedPictureSizes(); 465 int mid = (int) Math.floor(supportedPictureSizes.size() / 2); 466 int low = supportedPictureSizes.size() - 1; 467 switch (picturesize) { 468 case SMALL: 469 params.setPictureSize(supportedPictureSizes.get(low).width, 470 supportedPictureSizes.get(low).height); 471 break; 472 case MEDIUM: 473 params.setPictureSize(supportedPictureSizes.get(mid).width, 474 supportedPictureSizes.get(mid).height); 475 break; 476 case LARGE: 477 params.setPictureSize(supportedPictureSizes.get(0).width, 478 supportedPictureSizes.get(mid).height); 479 break; 480 } 481 482 // Configure geotagging setting 483 switch (geotagging) { 484 case ON: 485 params.setGpsLatitude(MOCK_LATITUDE); 486 params.setGpsLongitude(MOCK_LONGITUDE); 487 break; 488 case OFF: 489 break; 490 } 491 492 mCameraTestHelper.setParameters(params); 493 mCameraTestHelper.startCameraPreview(surfaceHolder); 494 mCameraTestHelper.capturePhoto(); 495 mCameraTestHelper.cleanupTestImages(); 496 } catch (Exception e) { 497 Log.e(TAG, e.toString()); 498 fail("Test case failed"); 499 } 500 } 501 } 502