CameraTest.java revision f75e370e127b7c7bb6b6d5cebaa07abec36794b2
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 17package com.android.mediaframeworktest.functional; 18 19import com.android.mediaframeworktest.MediaFrameworkTest; 20import com.android.mediaframeworktest.MediaNames; 21 22import android.content.Context; 23import android.hardware.Camera; 24import android.hardware.Camera.PictureCallback; 25import android.hardware.Camera.PreviewCallback; 26import android.hardware.Camera.ShutterCallback; 27import android.os.ConditionVariable; 28import android.os.Environment; 29import android.os.Looper; 30import android.test.ActivityInstrumentationTestCase; 31import android.test.suitebuilder.annotation.LargeTest; 32import android.util.Log; 33import android.view.SurfaceHolder; 34 35import java.io.*; 36 37/** 38 * Junit / Instrumentation test case for the camera api 39 40 */ 41public class CameraTest extends ActivityInstrumentationTestCase<MediaFrameworkTest> { 42 private String TAG = "CameraTest"; 43 44 private boolean rawPreviewCallbackResult = false; 45 private boolean shutterCallbackResult = false; 46 private boolean rawPictureCallbackResult = false; 47 private boolean jpegPictureCallbackResult = false; 48 49 private static int WAIT_FOR_COMMAND_TO_COMPLETE = 10000; // Milliseconds. 50 51 private RawPreviewCallback mRawPreviewCallback = new RawPreviewCallback(); 52 private TestShutterCallback mShutterCallback = new TestShutterCallback(); 53 private RawPictureCallback mRawPictureCallback = new RawPictureCallback(); 54 private JpegPictureCallback mJpegPictureCallback = new JpegPictureCallback(); 55 56 private boolean mInitialized = false; 57 private Looper mLooper = null; 58 private final ConditionVariable mPreviewDone = new ConditionVariable(); 59 private final ConditionVariable mSnapshotDone = new ConditionVariable(); 60 61 Camera mCamera; 62 Context mContext; 63 64 public CameraTest() { 65 super("com.android.mediaframeworktest", MediaFrameworkTest.class); 66 } 67 68 protected void setUp() throws Exception { 69 super.setUp(); 70 } 71 72 /* 73 * Initializes the message looper so that the Camera object can 74 * receive the callback messages. 75 */ 76 private void initializeMessageLooper() { 77 final ConditionVariable startDone = new ConditionVariable(); 78 Log.v(TAG, "start looper"); 79 new Thread() { 80 @Override 81 public void run() { 82 // Set up a looper to be used by camera. 83 Looper.prepare(); 84 Log.v(TAG, "start loopRun"); 85 // Save the looper so that we can terminate this thread 86 // after we are done with it. 87 mLooper = Looper.myLooper(); 88 mCamera = Camera.open(); 89 startDone.open(); 90 Looper.loop(); // Blocks forever until Looper.quit() is called. 91 Log.v(TAG, "initializeMessageLooper: quit."); 92 } 93 }.start(); 94 95 if (!startDone.block(WAIT_FOR_COMMAND_TO_COMPLETE)) { 96 fail("initializeMessageLooper: start timeout"); 97 } 98 } 99 100 /* 101 * Terminates the message looper thread. 102 */ 103 private void terminateMessageLooper() throws Exception { 104 mLooper.quit(); 105 // Looper.quit() is asynchronous. The looper may still has some 106 // preview callbacks in the queue after quit is called. The preview 107 // callback still uses the camera object (setHasPreviewCallback). 108 // After camera is released, RuntimeException will be thrown from 109 // the method. So we need to join the looper thread here. 110 mLooper.getThread().join(); 111 mCamera.release(); 112 } 113 114 //Implement the previewCallback 115 private final class RawPreviewCallback implements PreviewCallback { 116 public void onPreviewFrame(byte [] rawData, Camera camera) { 117 Log.v(TAG, "Preview callback start"); 118 int rawDataLength = 0; 119 if (rawData != null) { 120 rawDataLength = rawData.length; 121 } 122 if (rawDataLength > 0) { 123 rawPreviewCallbackResult = true; 124 } else { 125 rawPreviewCallbackResult = false; 126 } 127 mPreviewDone.open(); 128 Log.v(TAG, "Preview callback stop"); 129 } 130 }; 131 132 //Implement the shutterCallback 133 private final class TestShutterCallback implements ShutterCallback { 134 public void onShutter() { 135 shutterCallbackResult = true; 136 Log.v(TAG, "onShutter called"); 137 } 138 }; 139 140 //Implement the RawPictureCallback 141 private final class RawPictureCallback implements PictureCallback { 142 public void onPictureTaken(byte [] rawData, Camera camera) { 143 // no support for raw data - success if we get the callback 144 rawPictureCallbackResult = true; 145 Log.v(TAG, "RawPictureCallback callback"); 146 } 147 }; 148 149 //Implement the JpegPictureCallback 150 private final class JpegPictureCallback implements PictureCallback { 151 public void onPictureTaken(byte [] rawData, Camera camera) { 152 try { 153 if (rawData != null) { 154 int rawDataLength = rawData.length; 155 File rawoutput = new File( 156 Environment.getExternalStorageDirectory().toString(), "/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