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