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