Home | History | Annotate | Download | only in camera
      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