Home | History | Annotate | Download | only in functional
      1 /*
      2  * Copyright (C) 2008 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;
     18 
     19 import com.android.mediaframeworktest.MediaFrameworkTest;
     20 import com.android.mediaframeworktest.MediaNames;
     21 
     22 import java.io.*;
     23 
     24 import android.content.Context;
     25 import android.hardware.Camera;
     26 import android.hardware.Camera.PictureCallback;
     27 import android.hardware.Camera.PreviewCallback;
     28 import android.hardware.Camera.ShutterCallback;
     29 import android.test.ActivityInstrumentationTestCase;
     30 import android.util.Log;
     31 import android.view.SurfaceHolder;
     32 
     33 import android.os.ConditionVariable;
     34 import android.os.Looper;
     35 
     36 import android.test.suitebuilder.annotation.LargeTest;
     37 
     38 /**
     39  * Junit / Instrumentation test case for the camera api
     40 
     41  */
     42 public class CameraTest extends ActivityInstrumentationTestCase<MediaFrameworkTest> {
     43     private String TAG = "CameraTest";
     44 
     45     private boolean rawPreviewCallbackResult = false;
     46     private boolean shutterCallbackResult = false;
     47     private boolean rawPictureCallbackResult = false;
     48     private boolean jpegPictureCallbackResult = false;
     49 
     50     private static int WAIT_FOR_COMMAND_TO_COMPLETE = 10000;  // Milliseconds.
     51 
     52     private RawPreviewCallback mRawPreviewCallback = new RawPreviewCallback();
     53     private TestShutterCallback mShutterCallback = new TestShutterCallback();
     54     private RawPictureCallback mRawPictureCallback = new RawPictureCallback();
     55     private JpegPictureCallback mJpegPictureCallback = new JpegPictureCallback();
     56 
     57     private boolean mInitialized = false;
     58     private Looper mLooper = null;
     59     private final ConditionVariable mPreviewDone = new ConditionVariable();
     60     private final ConditionVariable mSnapshotDone = new ConditionVariable();
     61 
     62     Camera mCamera;
     63     Context mContext;
     64 
     65     public CameraTest() {
     66         super("com.android.mediaframeworktest", MediaFrameworkTest.class);
     67     }
     68 
     69     protected void setUp() throws Exception {
     70         super.setUp();
     71     }
     72 
     73     /*
     74      * Initializes the message looper so that the Camera object can
     75      * receive the callback messages.
     76      */
     77     private void initializeMessageLooper() {
     78         final ConditionVariable startDone = new ConditionVariable();
     79         Log.v(TAG, "start looper");
     80         new Thread() {
     81             @Override
     82             public void run() {
     83                 // Set up a looper to be used by camera.
     84                 Looper.prepare();
     85                 Log.v(TAG, "start loopRun");
     86                 // Save the looper so that we can terminate this thread
     87                 // after we are done with it.
     88                 mLooper = Looper.myLooper();
     89                 mCamera = Camera.open();
     90                 startDone.open();
     91                 Looper.loop();  // Blocks forever until Looper.quit() is called.
     92                 Log.v(TAG, "initializeMessageLooper: quit.");
     93             }
     94         }.start();
     95 
     96         if (!startDone.block(WAIT_FOR_COMMAND_TO_COMPLETE)) {
     97             fail("initializeMessageLooper: start timeout");
     98         }
     99     }
    100 
    101     /*
    102      * Terminates the message looper thread.
    103      */
    104     private void terminateMessageLooper() throws Exception {
    105         mLooper.quit();
    106         // Looper.quit() is asynchronous. The looper may still has some
    107         // preview callbacks in the queue after quit is called. The preview
    108         // callback still uses the camera object (setHasPreviewCallback).
    109         // After camera is released, RuntimeException will be thrown from
    110         // the method. So we need to join the looper thread here.
    111         mLooper.getThread().join();
    112         mCamera.release();
    113     }
    114 
    115     //Implement the previewCallback
    116     private final class RawPreviewCallback implements PreviewCallback {
    117         public void onPreviewFrame(byte [] rawData, Camera camera) {
    118             Log.v(TAG, "Preview callback start");
    119             int rawDataLength = 0;
    120             if (rawData != null) {
    121                 rawDataLength = rawData.length;
    122             }
    123             if (rawDataLength > 0) {
    124                 rawPreviewCallbackResult = true;
    125             } else {
    126                 rawPreviewCallbackResult = false;
    127             }
    128             mPreviewDone.open();
    129             Log.v(TAG, "Preview callback stop");
    130         }
    131     };
    132 
    133     //Implement the shutterCallback
    134     private final class TestShutterCallback implements ShutterCallback {
    135         public void onShutter() {
    136             shutterCallbackResult = true;
    137             Log.v(TAG, "onShutter called");
    138         }
    139     };
    140 
    141     //Implement the RawPictureCallback
    142     private final class RawPictureCallback implements PictureCallback {
    143         public void onPictureTaken(byte [] rawData, Camera camera) {
    144             // no support for raw data - success if we get the callback
    145             rawPictureCallbackResult = true;
    146             Log.v(TAG, "RawPictureCallback callback");
    147         }
    148     };
    149 
    150     //Implement the JpegPictureCallback
    151     private final class JpegPictureCallback implements PictureCallback {
    152         public void onPictureTaken(byte [] rawData, Camera camera) {
    153             try {
    154                 if (rawData != null) {
    155                     int rawDataLength = rawData.length;
    156                     File rawoutput = new File("/sdcard/test.bmp");
    157                     FileOutputStream outstream = new FileOutputStream(rawoutput);
    158                     outstream.write(rawData);
    159                     Log.v(TAG, "JpegPictureCallback rawDataLength = " + rawDataLength);
    160                     jpegPictureCallbackResult = true;
    161                 } else {
    162                     jpegPictureCallbackResult = false;
    163                 }
    164                 mSnapshotDone.open();
    165                 Log.v(TAG, "Jpeg Picture callback");
    166             } catch (Exception e) {
    167                 Log.v(TAG, e.toString());
    168             }
    169         }
    170     };
    171 
    172     private void waitForPreviewDone() {
    173         if (!mPreviewDone.block(WAIT_FOR_COMMAND_TO_COMPLETE)) {
    174             Log.v(TAG, "waitForPreviewDone: timeout");
    175         }
    176         mPreviewDone.close();
    177     }
    178 
    179     private void waitForSnapshotDone() {
    180         if (!mSnapshotDone.block(MediaNames.WAIT_SNAPSHOT_TIME)) {
    181             // timeout could be expected or unexpected. The caller will decide.
    182             Log.v(TAG, "waitForSnapshotDone: timeout");
    183         }
    184         mSnapshotDone.close();
    185     }
    186 
    187 
    188     private void checkTakePicture() {
    189         SurfaceHolder mSurfaceHolder;
    190         try {
    191             mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
    192             mCamera.setPreviewDisplay(mSurfaceHolder);
    193             Log.v(TAG, "Start preview");
    194             mCamera.startPreview();
    195             waitForPreviewDone();
    196             mCamera.setPreviewCallback(null);
    197             mCamera.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback);
    198             waitForSnapshotDone();
    199         } catch (Exception e) {
    200             Log.v(TAG, e.toString());
    201         }
    202     }
    203 
    204     private void checkPreviewCallback() {
    205         SurfaceHolder mSurfaceHolder;
    206         try {
    207             mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
    208             mCamera.setPreviewDisplay(mSurfaceHolder);
    209             Log.v(TAG, "start preview");
    210             mCamera.startPreview();
    211             waitForPreviewDone();
    212             mCamera.setPreviewCallback(null);
    213         } catch (Exception e) {
    214             Log.v(TAG, e.toString());
    215         }
    216     }
    217 
    218     /*
    219      * TODO(yslau): Need to setup the golden rawData and compare the
    220      * the new captured rawData with the golden one.
    221      *
    222      * Test case 1: Take a picture and verify all the callback
    223      * functions are called properly.
    224      */
    225     @LargeTest
    226     public void testTakePicture() throws Exception {
    227         initializeMessageLooper();
    228         mCamera.setPreviewCallback(mRawPreviewCallback);
    229         checkTakePicture();
    230         terminateMessageLooper();
    231         assertTrue("shutterCallbackResult", shutterCallbackResult);
    232         assertTrue("rawPictureCallbackResult", rawPictureCallbackResult);
    233         assertTrue("jpegPictureCallbackResult", jpegPictureCallbackResult);
    234     }
    235 
    236     /*
    237      * Test case 2: Set the preview and
    238      * verify the RawPreviewCallback is called
    239      */
    240     @LargeTest
    241     public void testCheckPreview() throws Exception {
    242         initializeMessageLooper();
    243         mCamera.setPreviewCallback(mRawPreviewCallback);
    244         checkPreviewCallback();
    245         terminateMessageLooper();
    246         assertTrue("RawPreviewCallbackResult", rawPreviewCallbackResult);
    247     }
    248 
    249 }
    250 
    251