blob: 2f864d7fa906f6565277c72d4102e517ab10bcdb [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import android.content.Context;
23import android.hardware.Camera;
24import android.hardware.Camera.PictureCallback;
25import android.hardware.Camera.PreviewCallback;
26import android.hardware.Camera.ShutterCallback;
Ray Chenf75e3702010-04-30 14:11:52 -070027import android.os.ConditionVariable;
28import android.os.Environment;
29import android.os.Looper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.test.ActivityInstrumentationTestCase;
Ray Chenf75e3702010-04-30 14:11:52 -070031import android.test.suitebuilder.annotation.LargeTest;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.util.Log;
33import android.view.SurfaceHolder;
34
Ray Chenf75e3702010-04-30 14:11:52 -070035import java.io.*;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036
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.
Yu Shan Emily Laue35b3e02012-04-26 17:10:29 -070050 private static final int CAMERA_ID = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051
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;
Wu-cheng Li59411b32010-03-25 17:27:29 +080059 private final ConditionVariable mPreviewDone = new ConditionVariable();
60 private final ConditionVariable mSnapshotDone = new ConditionVariable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061
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() {
Wu-cheng Li59411b32010-03-25 17:27:29 +080078 final ConditionVariable startDone = new ConditionVariable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079 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.
Wu-cheng Li59411b32010-03-25 17:27:29 +080088 mLooper = Looper.myLooper();
Yu Shan Emily Laue35b3e02012-04-26 17:10:29 -070089 mCamera = Camera.open(CAMERA_ID);
Wu-cheng Li59411b32010-03-25 17:27:29 +080090 startDone.open();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091 Looper.loop(); // Blocks forever until Looper.quit() is called.
92 Log.v(TAG, "initializeMessageLooper: quit.");
93 }
94 }.start();
Wu-cheng Li59411b32010-03-25 17:27:29 +080095
96 if (!startDone.block(WAIT_FOR_COMMAND_TO_COMPLETE)) {
97 fail("initializeMessageLooper: start timeout");
98 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099 }
100
101 /*
102 * Terminates the message looper thread.
103 */
Wu-cheng Li59411b32010-03-25 17:27:29 +0800104 private void terminateMessageLooper() throws Exception {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105 mLooper.quit();
Wu-cheng Li59411b32010-03-25 17:27:29 +0800106 // 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();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112 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 }
Wu-cheng Li59411b32010-03-25 17:27:29 +0800128 mPreviewDone.open();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129 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) {
Wu-cheng Li59411b32010-03-25 17:27:29 +0800144 // no support for raw data - success if we get the callback
145 rawPictureCallbackResult = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146 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;
Ray Chenf75e3702010-04-30 14:11:52 -0700156 File rawoutput = new File(
157 Environment.getExternalStorageDirectory().toString(), "/test.bmp");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800158 FileOutputStream outstream = new FileOutputStream(rawoutput);
159 outstream.write(rawData);
160 Log.v(TAG, "JpegPictureCallback rawDataLength = " + rawDataLength);
161 jpegPictureCallbackResult = true;
162 } else {
163 jpegPictureCallbackResult = false;
164 }
Wu-cheng Li59411b32010-03-25 17:27:29 +0800165 mSnapshotDone.open();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800166 Log.v(TAG, "Jpeg Picture callback");
167 } catch (Exception e) {
168 Log.v(TAG, e.toString());
169 }
170 }
171 };
172
Wu-cheng Li59411b32010-03-25 17:27:29 +0800173 private void waitForPreviewDone() {
174 if (!mPreviewDone.block(WAIT_FOR_COMMAND_TO_COMPLETE)) {
175 Log.v(TAG, "waitForPreviewDone: timeout");
176 }
177 mPreviewDone.close();
178 }
179
180 private void waitForSnapshotDone() {
181 if (!mSnapshotDone.block(MediaNames.WAIT_SNAPSHOT_TIME)) {
182 // timeout could be expected or unexpected. The caller will decide.
183 Log.v(TAG, "waitForSnapshotDone: timeout");
184 }
185 mSnapshotDone.close();
186 }
187
188
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800189 private void checkTakePicture() {
190 SurfaceHolder mSurfaceHolder;
191 try {
192 mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
193 mCamera.setPreviewDisplay(mSurfaceHolder);
194 Log.v(TAG, "Start preview");
195 mCamera.startPreview();
Wu-cheng Li59411b32010-03-25 17:27:29 +0800196 waitForPreviewDone();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800197 mCamera.setPreviewCallback(null);
198 mCamera.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback);
Wu-cheng Li59411b32010-03-25 17:27:29 +0800199 waitForSnapshotDone();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800200 } catch (Exception e) {
201 Log.v(TAG, e.toString());
202 }
203 }
204
205 private void checkPreviewCallback() {
206 SurfaceHolder mSurfaceHolder;
207 try {
208 mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
209 mCamera.setPreviewDisplay(mSurfaceHolder);
210 Log.v(TAG, "start preview");
Wu-cheng Li59411b32010-03-25 17:27:29 +0800211 mCamera.startPreview();
212 waitForPreviewDone();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800213 mCamera.setPreviewCallback(null);
214 } catch (Exception e) {
215 Log.v(TAG, e.toString());
216 }
217 }
218
219 /*
220 * TODO(yslau): Need to setup the golden rawData and compare the
221 * the new captured rawData with the golden one.
222 *
223 * Test case 1: Take a picture and verify all the callback
224 * functions are called properly.
225 */
226 @LargeTest
227 public void testTakePicture() throws Exception {
Wu-cheng Li59411b32010-03-25 17:27:29 +0800228 initializeMessageLooper();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800229 mCamera.setPreviewCallback(mRawPreviewCallback);
230 checkTakePicture();
231 terminateMessageLooper();
232 assertTrue("shutterCallbackResult", shutterCallbackResult);
233 assertTrue("rawPictureCallbackResult", rawPictureCallbackResult);
234 assertTrue("jpegPictureCallbackResult", jpegPictureCallbackResult);
235 }
236
237 /*
238 * Test case 2: Set the preview and
239 * verify the RawPreviewCallback is called
240 */
241 @LargeTest
242 public void testCheckPreview() throws Exception {
Wu-cheng Li59411b32010-03-25 17:27:29 +0800243 initializeMessageLooper();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800244 mCamera.setPreviewCallback(mRawPreviewCallback);
245 checkPreviewCallback();
246 terminateMessageLooper();
247 assertTrue("RawPreviewCallbackResult", rawPreviewCallbackResult);
248 }
249
250}
251