blob: 7f23ba576fbbc89eabf73b99a9e9b9ea7ddc9c13 [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
Igor Murashkin4491d682013-05-31 16:43:48 -070039 *
40 * To run only tests in this class:
41 *
42 * adb shell am instrument \
43 * -e class com.android.mediaframeworktest.functional.CameraTest \
44 * -w com.android.mediaframeworktest/.MediaFrameworkTestRunner
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045 */
46public class CameraTest extends ActivityInstrumentationTestCase<MediaFrameworkTest> {
47 private String TAG = "CameraTest";
48
49 private boolean rawPreviewCallbackResult = false;
50 private boolean shutterCallbackResult = false;
51 private boolean rawPictureCallbackResult = false;
52 private boolean jpegPictureCallbackResult = false;
53
54 private static int WAIT_FOR_COMMAND_TO_COMPLETE = 10000; // Milliseconds.
Yu Shan Emily Laue35b3e02012-04-26 17:10:29 -070055 private static final int CAMERA_ID = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056
57 private RawPreviewCallback mRawPreviewCallback = new RawPreviewCallback();
58 private TestShutterCallback mShutterCallback = new TestShutterCallback();
59 private RawPictureCallback mRawPictureCallback = new RawPictureCallback();
60 private JpegPictureCallback mJpegPictureCallback = new JpegPictureCallback();
61
62 private boolean mInitialized = false;
63 private Looper mLooper = null;
Wu-cheng Li59411b32010-03-25 17:27:29 +080064 private final ConditionVariable mPreviewDone = new ConditionVariable();
65 private final ConditionVariable mSnapshotDone = new ConditionVariable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066
67 Camera mCamera;
68 Context mContext;
69
70 public CameraTest() {
71 super("com.android.mediaframeworktest", MediaFrameworkTest.class);
72 }
73
74 protected void setUp() throws Exception {
75 super.setUp();
76 }
77
78 /*
79 * Initializes the message looper so that the Camera object can
80 * receive the callback messages.
81 */
82 private void initializeMessageLooper() {
Wu-cheng Li59411b32010-03-25 17:27:29 +080083 final ConditionVariable startDone = new ConditionVariable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084 Log.v(TAG, "start looper");
85 new Thread() {
86 @Override
87 public void run() {
88 // Set up a looper to be used by camera.
89 Looper.prepare();
90 Log.v(TAG, "start loopRun");
91 // Save the looper so that we can terminate this thread
92 // after we are done with it.
Wu-cheng Li59411b32010-03-25 17:27:29 +080093 mLooper = Looper.myLooper();
Yu Shan Emily Laue35b3e02012-04-26 17:10:29 -070094 mCamera = Camera.open(CAMERA_ID);
Wu-cheng Li59411b32010-03-25 17:27:29 +080095 startDone.open();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096 Looper.loop(); // Blocks forever until Looper.quit() is called.
97 Log.v(TAG, "initializeMessageLooper: quit.");
98 }
99 }.start();
Wu-cheng Li59411b32010-03-25 17:27:29 +0800100
101 if (!startDone.block(WAIT_FOR_COMMAND_TO_COMPLETE)) {
102 fail("initializeMessageLooper: start timeout");
103 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104 }
105
106 /*
107 * Terminates the message looper thread.
108 */
Wu-cheng Li59411b32010-03-25 17:27:29 +0800109 private void terminateMessageLooper() throws Exception {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110 mLooper.quit();
Wu-cheng Li59411b32010-03-25 17:27:29 +0800111 // Looper.quit() is asynchronous. The looper may still has some
112 // preview callbacks in the queue after quit is called. The preview
113 // callback still uses the camera object (setHasPreviewCallback).
114 // After camera is released, RuntimeException will be thrown from
115 // the method. So we need to join the looper thread here.
116 mLooper.getThread().join();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117 mCamera.release();
118 }
119
120 //Implement the previewCallback
121 private final class RawPreviewCallback implements PreviewCallback {
122 public void onPreviewFrame(byte [] rawData, Camera camera) {
123 Log.v(TAG, "Preview callback start");
124 int rawDataLength = 0;
125 if (rawData != null) {
126 rawDataLength = rawData.length;
127 }
128 if (rawDataLength > 0) {
129 rawPreviewCallbackResult = true;
130 } else {
131 rawPreviewCallbackResult = false;
132 }
Wu-cheng Li59411b32010-03-25 17:27:29 +0800133 mPreviewDone.open();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134 Log.v(TAG, "Preview callback stop");
135 }
136 };
137
138 //Implement the shutterCallback
139 private final class TestShutterCallback implements ShutterCallback {
140 public void onShutter() {
141 shutterCallbackResult = true;
142 Log.v(TAG, "onShutter called");
143 }
144 };
145
146 //Implement the RawPictureCallback
147 private final class RawPictureCallback implements PictureCallback {
148 public void onPictureTaken(byte [] rawData, Camera camera) {
Wu-cheng Li59411b32010-03-25 17:27:29 +0800149 // no support for raw data - success if we get the callback
150 rawPictureCallbackResult = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151 Log.v(TAG, "RawPictureCallback callback");
152 }
153 };
154
155 //Implement the JpegPictureCallback
156 private final class JpegPictureCallback implements PictureCallback {
157 public void onPictureTaken(byte [] rawData, Camera camera) {
158 try {
159 if (rawData != null) {
160 int rawDataLength = rawData.length;
Ray Chenf75e3702010-04-30 14:11:52 -0700161 File rawoutput = new File(
162 Environment.getExternalStorageDirectory().toString(), "/test.bmp");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 FileOutputStream outstream = new FileOutputStream(rawoutput);
164 outstream.write(rawData);
165 Log.v(TAG, "JpegPictureCallback rawDataLength = " + rawDataLength);
166 jpegPictureCallbackResult = true;
167 } else {
168 jpegPictureCallbackResult = false;
169 }
Wu-cheng Li59411b32010-03-25 17:27:29 +0800170 mSnapshotDone.open();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 Log.v(TAG, "Jpeg Picture callback");
172 } catch (Exception e) {
173 Log.v(TAG, e.toString());
174 }
175 }
176 };
177
Wu-cheng Li59411b32010-03-25 17:27:29 +0800178 private void waitForPreviewDone() {
179 if (!mPreviewDone.block(WAIT_FOR_COMMAND_TO_COMPLETE)) {
180 Log.v(TAG, "waitForPreviewDone: timeout");
181 }
182 mPreviewDone.close();
183 }
184
185 private void waitForSnapshotDone() {
186 if (!mSnapshotDone.block(MediaNames.WAIT_SNAPSHOT_TIME)) {
187 // timeout could be expected or unexpected. The caller will decide.
188 Log.v(TAG, "waitForSnapshotDone: timeout");
189 }
190 mSnapshotDone.close();
191 }
192
193
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800194 private void checkTakePicture() {
195 SurfaceHolder mSurfaceHolder;
196 try {
197 mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
198 mCamera.setPreviewDisplay(mSurfaceHolder);
199 Log.v(TAG, "Start preview");
200 mCamera.startPreview();
Wu-cheng Li59411b32010-03-25 17:27:29 +0800201 waitForPreviewDone();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202 mCamera.setPreviewCallback(null);
203 mCamera.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback);
Wu-cheng Li59411b32010-03-25 17:27:29 +0800204 waitForSnapshotDone();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800205 } catch (Exception e) {
206 Log.v(TAG, e.toString());
207 }
208 }
209
210 private void checkPreviewCallback() {
211 SurfaceHolder mSurfaceHolder;
212 try {
213 mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
214 mCamera.setPreviewDisplay(mSurfaceHolder);
215 Log.v(TAG, "start preview");
Wu-cheng Li59411b32010-03-25 17:27:29 +0800216 mCamera.startPreview();
217 waitForPreviewDone();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800218 mCamera.setPreviewCallback(null);
219 } catch (Exception e) {
220 Log.v(TAG, e.toString());
221 }
222 }
223
224 /*
225 * TODO(yslau): Need to setup the golden rawData and compare the
226 * the new captured rawData with the golden one.
227 *
228 * Test case 1: Take a picture and verify all the callback
229 * functions are called properly.
230 */
231 @LargeTest
232 public void testTakePicture() throws Exception {
Wu-cheng Li59411b32010-03-25 17:27:29 +0800233 initializeMessageLooper();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800234 mCamera.setPreviewCallback(mRawPreviewCallback);
235 checkTakePicture();
236 terminateMessageLooper();
237 assertTrue("shutterCallbackResult", shutterCallbackResult);
238 assertTrue("rawPictureCallbackResult", rawPictureCallbackResult);
239 assertTrue("jpegPictureCallbackResult", jpegPictureCallbackResult);
240 }
241
242 /*
243 * Test case 2: Set the preview and
244 * verify the RawPreviewCallback is called
245 */
246 @LargeTest
247 public void testCheckPreview() throws Exception {
Wu-cheng Li59411b32010-03-25 17:27:29 +0800248 initializeMessageLooper();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800249 mCamera.setPreviewCallback(mRawPreviewCallback);
250 checkPreviewCallback();
251 terminateMessageLooper();
252 assertTrue("RawPreviewCallbackResult", rawPreviewCallbackResult);
253 }
254
255}
256