blob: e628b6825208bf0c8bf472f98b71b63095f4429e [file] [log] [blame]
Igor Murashkin70725502013-06-25 20:27:06 +00001/*
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
17package com.android.mediaframeworktest.integration;
18
Zhijun He7b7a1542013-09-25 16:33:35 -070019import android.graphics.ImageFormat;
Igor Murashkin70725502013-06-25 20:27:06 +000020import android.graphics.SurfaceTexture;
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -080021import android.hardware.ICameraService;
Eino-Ville Talvala2f1a2e42013-07-25 17:12:05 -070022import android.hardware.camera2.CameraMetadata;
Chien-Yu Chen7a316f6b2015-04-13 14:31:45 -070023import android.hardware.camera2.CameraCaptureSession;
Igor Murashkin68f40062013-09-10 12:15:54 -070024import android.hardware.camera2.CameraCharacteristics;
Eino-Ville Talvala2f1a2e42013-07-25 17:12:05 -070025import android.hardware.camera2.CaptureRequest;
26import android.hardware.camera2.ICameraDeviceCallbacks;
27import android.hardware.camera2.ICameraDeviceUser;
Eino-Ville Talvala70c22072013-08-27 12:09:04 -070028import android.hardware.camera2.impl.CameraMetadataNative;
Igor Murashkin72f9f0a2014-05-14 15:46:10 -070029import android.hardware.camera2.impl.CaptureResultExtras;
Yin-Chia Yehbfbbee72015-03-12 13:39:26 -070030import android.hardware.camera2.params.OutputConfiguration;
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -080031import android.hardware.camera2.utils.SubmitInfo;
Zhijun He7b7a1542013-09-25 16:33:35 -070032import android.media.Image;
33import android.media.ImageReader;
34import android.os.Handler;
35import android.os.HandlerThread;
Igor Murashkin70725502013-06-25 20:27:06 +000036import android.os.RemoteException;
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -080037import android.os.ServiceSpecificException;
Eino-Ville Talvalae841d4e2013-09-05 09:04:08 -070038import android.os.SystemClock;
Igor Murashkin70725502013-06-25 20:27:06 +000039import android.test.AndroidTestCase;
40import android.test.suitebuilder.annotation.SmallTest;
41import android.util.Log;
42import android.view.Surface;
43
Eino-Ville Talvala2f1a2e42013-07-25 17:12:05 -070044import static android.hardware.camera2.CameraDevice.TEMPLATE_PREVIEW;
Igor Murashkin70725502013-06-25 20:27:06 +000045
46import com.android.mediaframeworktest.MediaFrameworkIntegrationTestRunner;
Zhijun He693e21d2013-07-31 14:16:14 -070047
Eino-Ville Talvalae841d4e2013-09-05 09:04:08 -070048import org.mockito.ArgumentCaptor;
Paul Duffin192bb0b2017-03-09 18:49:41 +000049import org.mockito.compat.ArgumentMatcher;
Zhijun He693e21d2013-07-31 14:16:14 -070050import static org.mockito.Mockito.*;
Igor Murashkin70725502013-06-25 20:27:06 +000051
52public class CameraDeviceBinderTest extends AndroidTestCase {
53 private static String TAG = "CameraDeviceBinderTest";
Zhijun He693e21d2013-07-31 14:16:14 -070054 // Number of streaming callbacks need to check.
55 private static int NUM_CALLBACKS_CHECKED = 10;
Ruben Brunk66ef6452013-08-08 13:05:30 -070056 // Wait for capture result timeout value: 1500ms
57 private final static int WAIT_FOR_COMPLETE_TIMEOUT_MS = 1500;
Eino-Ville Talvalae841d4e2013-09-05 09:04:08 -070058 // Wait for flush timeout value: 1000ms
59 private final static int WAIT_FOR_FLUSH_TIMEOUT_MS = 1000;
60 // Wait for idle timeout value: 2000ms
61 private final static int WAIT_FOR_IDLE_TIMEOUT_MS = 2000;
62 // Wait while camera device starts working on requests
63 private final static int WAIT_FOR_WORK_MS = 300;
Zhijun He7b7a1542013-09-25 16:33:35 -070064 // Default size is VGA, which is mandatory camera supported image size by CDD.
65 private static final int DEFAULT_IMAGE_WIDTH = 640;
66 private static final int DEFAULT_IMAGE_HEIGHT = 480;
67 private static final int MAX_NUM_IMAGES = 5;
Igor Murashkin70725502013-06-25 20:27:06 +000068
Eino-Ville Talvala283ae234f2016-12-08 13:38:52 -080069 private String mCameraId;
Igor Murashkin70725502013-06-25 20:27:06 +000070 private ICameraDeviceUser mCameraUser;
71 private CameraBinderTestUtils mUtils;
Zhijun He693e21d2013-07-31 14:16:14 -070072 private ICameraDeviceCallbacks.Stub mMockCb;
73 private Surface mSurface;
Yin-Chia Yehbfbbee72015-03-12 13:39:26 -070074 private OutputConfiguration mOutputConfiguration;
Zhijun He7b7a1542013-09-25 16:33:35 -070075 private HandlerThread mHandlerThread;
76 private Handler mHandler;
77 ImageReader mImageReader;
Igor Murashkin70725502013-06-25 20:27:06 +000078
79 public CameraDeviceBinderTest() {
80 }
81
Zhijun He7b7a1542013-09-25 16:33:35 -070082 private class ImageDropperListener implements ImageReader.OnImageAvailableListener {
83
84 @Override
85 public void onImageAvailable(ImageReader reader) {
86 Image image = reader.acquireNextImage();
87 if (image != null) image.close();
88 }
89 }
90
Zhijun He693e21d2013-07-31 14:16:14 -070091 public class DummyCameraDeviceCallbacks extends ICameraDeviceCallbacks.Stub {
Igor Murashkin70725502013-06-25 20:27:06 +000092
Zhijun He438d77e2014-04-10 17:09:22 -070093 /*
94 * (non-Javadoc)
95 * @see
Eino-Ville Talvalaacc00952014-08-06 14:31:08 -070096 * android.hardware.camera2.ICameraDeviceCallbacks#onDeviceError(int,
Zhijun He438d77e2014-04-10 17:09:22 -070097 * android.hardware.camera2.CaptureResultExtras)
98 */
Eino-Ville Talvalaacc00952014-08-06 14:31:08 -070099 public void onDeviceError(int errorCode, CaptureResultExtras resultExtras)
Zhijun He438d77e2014-04-10 17:09:22 -0700100 throws RemoteException {
101 // TODO Auto-generated method stub
102
Igor Murashkin70725502013-06-25 20:27:06 +0000103 }
104
Zhijun He438d77e2014-04-10 17:09:22 -0700105 /*
106 * (non-Javadoc)
Eino-Ville Talvalaacc00952014-08-06 14:31:08 -0700107 * @see android.hardware.camera2.ICameraDeviceCallbacks#onDeviceIdle()
Zhijun He438d77e2014-04-10 17:09:22 -0700108 */
Eino-Ville Talvalaacc00952014-08-06 14:31:08 -0700109 public void onDeviceIdle() throws RemoteException {
Zhijun He438d77e2014-04-10 17:09:22 -0700110 // TODO Auto-generated method stub
111
Eino-Ville Talvalae841d4e2013-09-05 09:04:08 -0700112 }
113
Zhijun He438d77e2014-04-10 17:09:22 -0700114 /*
115 * (non-Javadoc)
116 * @see
117 * android.hardware.camera2.ICameraDeviceCallbacks#onCaptureStarted(
118 * android.hardware.camera2.CaptureResultExtras, long)
119 */
120 public void onCaptureStarted(CaptureResultExtras resultExtras, long timestamp)
121 throws RemoteException {
122 // TODO Auto-generated method stub
123
Eino-Ville Talvalae841d4e2013-09-05 09:04:08 -0700124 }
125
Zhijun He438d77e2014-04-10 17:09:22 -0700126 /*
127 * (non-Javadoc)
128 * @see
129 * android.hardware.camera2.ICameraDeviceCallbacks#onResultReceived(
130 * android.hardware.camera2.impl.CameraMetadataNative,
131 * android.hardware.camera2.CaptureResultExtras)
132 */
133 public void onResultReceived(CameraMetadataNative result, CaptureResultExtras resultExtras)
134 throws RemoteException {
135 // TODO Auto-generated method stub
136
Igor Murashkin70725502013-06-25 20:27:06 +0000137 }
Eino-Ville Talvalaad916f72015-04-11 12:09:11 -0700138
139 /*
140 * (non-Javadoc)
141 * @see android.hardware.camera2.ICameraDeviceCallbacks#onPrepared()
142 */
143 @Override
144 public void onPrepared(int streamId) throws RemoteException {
145 // TODO Auto-generated method stub
146
147 }
Chien-Yu Chen2da496f2016-04-14 13:33:00 -0700148
149 /*
150 * (non-Javadoc)
Shuzhen Wang88f1af22016-09-30 10:29:28 -0700151 * @see android.hardware.camera2.ICameraDeviceCallbacks#onRequestQueueEmpty()
152 */
153 @Override
154 public void onRequestQueueEmpty() throws RemoteException {
155 // TODO Auto-generated method stub
156
157 }
158
159 /*
160 * (non-Javadoc)
Chien-Yu Chen2da496f2016-04-14 13:33:00 -0700161 * @see android.hardware.camera2.ICameraDeviceCallbacks#onRepeatingRequestError()
162 */
163 @Override
Yin-Chia Yeh8cd12e92017-09-05 18:14:21 -0700164 public void onRepeatingRequestError(long lastFrameNumber, int repeatingRequestId) {
Chien-Yu Chen2da496f2016-04-14 13:33:00 -0700165 // TODO Auto-generated method stub
166 }
Igor Murashkin70725502013-06-25 20:27:06 +0000167 }
168
Eino-Ville Talvala70c22072013-08-27 12:09:04 -0700169 class IsMetadataNotEmpty extends ArgumentMatcher<CameraMetadataNative> {
Zhijun He20011882013-09-25 10:05:59 -0700170 @Override
Paul Duffin192bb0b2017-03-09 18:49:41 +0000171 public boolean matchesObject(Object obj) {
Eino-Ville Talvala70c22072013-08-27 12:09:04 -0700172 return !((CameraMetadataNative) obj).isEmpty();
Zhijun He693e21d2013-07-31 14:16:14 -0700173 }
Eino-Ville Talvalae841d4e2013-09-05 09:04:08 -0700174 }
Zhijun He693e21d2013-07-31 14:16:14 -0700175
176 private void createDefaultSurface() {
Zhijun He7b7a1542013-09-25 16:33:35 -0700177 mImageReader =
178 ImageReader.newInstance(DEFAULT_IMAGE_WIDTH,
179 DEFAULT_IMAGE_HEIGHT,
180 ImageFormat.YUV_420_888,
181 MAX_NUM_IMAGES);
182 mImageReader.setOnImageAvailableListener(new ImageDropperListener(), mHandler);
183 mSurface = mImageReader.getSurface();
Yin-Chia Yehbfbbee72015-03-12 13:39:26 -0700184 mOutputConfiguration = new OutputConfiguration(mSurface);
Zhijun He693e21d2013-07-31 14:16:14 -0700185 }
186
Eino-Ville Talvala70c22072013-08-27 12:09:04 -0700187 private CaptureRequest.Builder createDefaultBuilder(boolean needStream) throws Exception {
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800188 CameraMetadataNative metadata = null;
Zhijun He693e21d2013-07-31 14:16:14 -0700189 assertTrue(metadata.isEmpty());
190
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800191 metadata = mCameraUser.createDefaultRequest(TEMPLATE_PREVIEW);
Zhijun He693e21d2013-07-31 14:16:14 -0700192 assertFalse(metadata.isEmpty());
193
Chien-Yu Chen7a316f6b2015-04-13 14:31:45 -0700194 CaptureRequest.Builder request = new CaptureRequest.Builder(metadata, /*reprocess*/false,
195 CameraCaptureSession.SESSION_ID_NONE);
Zhijun He693e21d2013-07-31 14:16:14 -0700196 assertFalse(request.isEmpty());
Eino-Ville Talvala70c22072013-08-27 12:09:04 -0700197 assertFalse(metadata.isEmpty());
Zhijun He693e21d2013-07-31 14:16:14 -0700198 if (needStream) {
Yin-Chia Yehbfbbee72015-03-12 13:39:26 -0700199 int streamId = mCameraUser.createStream(mOutputConfiguration);
Zhijun He693e21d2013-07-31 14:16:14 -0700200 assertEquals(0, streamId);
201 request.addTarget(mSurface);
202 }
203 return request;
204 }
205
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800206 private SubmitInfo submitCameraRequest(CaptureRequest request, boolean streaming) throws Exception {
207 SubmitInfo requestInfo = mCameraUser.submitRequest(request, streaming);
Igor Murashkin5c207ec2014-04-01 15:50:48 -0700208 assertTrue(
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800209 "Request IDs should be non-negative (expected: >= 0, actual: " +
210 requestInfo.getRequestId() + ")",
211 requestInfo.getRequestId() >= 0);
212 return requestInfo;
Zhijun He693e21d2013-07-31 14:16:14 -0700213 }
214
Igor Murashkin70725502013-06-25 20:27:06 +0000215 @Override
216 protected void setUp() throws Exception {
217 super.setUp();
218
Zhijun He693e21d2013-07-31 14:16:14 -0700219 /**
220 * Workaround for mockito and JB-MR2 incompatibility
221 *
222 * Avoid java.lang.IllegalArgumentException: dexcache == null
223 * https://code.google.com/p/dexmaker/issues/detail?id=2
224 */
225 System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString());
Igor Murashkin70725502013-06-25 20:27:06 +0000226 mUtils = new CameraBinderTestUtils(getContext());
227
228 // This cannot be set in the constructor, since the onCreate isn't
229 // called yet
230 mCameraId = MediaFrameworkIntegrationTestRunner.mCameraId;
231
Zhijun He693e21d2013-07-31 14:16:14 -0700232 ICameraDeviceCallbacks.Stub dummyCallbacks = new DummyCameraDeviceCallbacks();
Igor Murashkin70725502013-06-25 20:27:06 +0000233
234 String clientPackageName = getContext().getPackageName();
235
Zhijun He693e21d2013-07-31 14:16:14 -0700236 mMockCb = spy(dummyCallbacks);
237
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800238 mCameraUser = mUtils.getCameraService().connectDevice(mMockCb, mCameraId,
239 clientPackageName, ICameraService.USE_CALLING_UID);
Igor Murashkin70725502013-06-25 20:27:06 +0000240 assertNotNull(String.format("Camera %s was null", mCameraId), mCameraUser);
Zhijun He7b7a1542013-09-25 16:33:35 -0700241 mHandlerThread = new HandlerThread(TAG);
242 mHandlerThread.start();
243 mHandler = new Handler(mHandlerThread.getLooper());
Zhijun He693e21d2013-07-31 14:16:14 -0700244 createDefaultSurface();
Igor Murashkin70725502013-06-25 20:27:06 +0000245
246 Log.v(TAG, String.format("Camera %s connected", mCameraId));
247 }
248
249 @Override
250 protected void tearDown() throws Exception {
251 mCameraUser.disconnect();
252 mCameraUser = null;
Zhijun He693e21d2013-07-31 14:16:14 -0700253 mSurface.release();
Zhijun He7b7a1542013-09-25 16:33:35 -0700254 mImageReader.close();
255 mHandlerThread.quitSafely();
Igor Murashkin70725502013-06-25 20:27:06 +0000256 }
257
258 @SmallTest
259 public void testCreateDefaultRequest() throws Exception {
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800260 CameraMetadataNative metadata = null;
Igor Murashkin70725502013-06-25 20:27:06 +0000261 assertTrue(metadata.isEmpty());
262
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800263 metadata = mCameraUser.createDefaultRequest(TEMPLATE_PREVIEW);
Igor Murashkin70725502013-06-25 20:27:06 +0000264 assertFalse(metadata.isEmpty());
265
Igor Murashkin70725502013-06-25 20:27:06 +0000266 }
267
268 @SmallTest
269 public void testCreateStream() throws Exception {
Yin-Chia Yehbfbbee72015-03-12 13:39:26 -0700270 int streamId = mCameraUser.createStream(mOutputConfiguration);
Igor Murashkin70725502013-06-25 20:27:06 +0000271 assertEquals(0, streamId);
272
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800273 try {
274 mCameraUser.createStream(mOutputConfiguration);
275 fail("Creating same stream twice");
276 } catch (ServiceSpecificException e) {
277 assertEquals("Creating same stream twice",
278 e.errorCode, ICameraService.ERROR_ALREADY_EXISTS);
279 }
Igor Murashkin70725502013-06-25 20:27:06 +0000280
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800281 mCameraUser.deleteStream(streamId);
Igor Murashkin70725502013-06-25 20:27:06 +0000282 }
283
284 @SmallTest
285 public void testDeleteInvalidStream() throws Exception {
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800286 int[] badStreams = { -1, 0, 1, 0xC0FFEE };
287 for (int badStream : badStreams) {
288 try {
289 mCameraUser.deleteStream(badStream);
290 fail("Allowed bad stream delete");
291 } catch (ServiceSpecificException e) {
292 assertEquals(e.errorCode, ICameraService.ERROR_ILLEGAL_ARGUMENT);
293 }
294 }
Igor Murashkin70725502013-06-25 20:27:06 +0000295 }
296
297 @SmallTest
298 public void testCreateStreamTwo() throws Exception {
299
300 // Create first stream
Yin-Chia Yehbfbbee72015-03-12 13:39:26 -0700301 int streamId = mCameraUser.createStream(mOutputConfiguration);
Igor Murashkin70725502013-06-25 20:27:06 +0000302 assertEquals(0, streamId);
303
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800304 try {
305 mCameraUser.createStream(mOutputConfiguration);
306 fail("Created same stream twice");
307 } catch (ServiceSpecificException e) {
308 assertEquals("Created same stream twice",
309 ICameraService.ERROR_ALREADY_EXISTS, e.errorCode);
310 }
Igor Murashkin70725502013-06-25 20:27:06 +0000311
Zhijun He693e21d2013-07-31 14:16:14 -0700312 // Create second stream with a different surface.
313 SurfaceTexture surfaceTexture = new SurfaceTexture(/* ignored */0);
314 surfaceTexture.setDefaultBufferSize(640, 480);
315 Surface surface2 = new Surface(surfaceTexture);
Yin-Chia Yehbfbbee72015-03-12 13:39:26 -0700316 OutputConfiguration output2 = new OutputConfiguration(surface2);
Igor Murashkin70725502013-06-25 20:27:06 +0000317
Yin-Chia Yehbfbbee72015-03-12 13:39:26 -0700318 int streamId2 = mCameraUser.createStream(output2);
Igor Murashkin70725502013-06-25 20:27:06 +0000319 assertEquals(1, streamId2);
320
321 // Clean up streams
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800322 mCameraUser.deleteStream(streamId);
323 mCameraUser.deleteStream(streamId2);
Igor Murashkin70725502013-06-25 20:27:06 +0000324 }
325
326 @SmallTest
327 public void testSubmitBadRequest() throws Exception {
328
Eino-Ville Talvala70c22072013-08-27 12:09:04 -0700329 CaptureRequest.Builder builder = createDefaultBuilder(/* needStream */false);
330 CaptureRequest request1 = builder.build();
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800331 try {
332 SubmitInfo requestInfo = mCameraUser.submitRequest(request1, /* streaming */false);
333 fail("Exception expected");
334 } catch(ServiceSpecificException e) {
335 assertEquals("Expected submitRequest to throw ServiceSpecificException with BAD_VALUE " +
336 "since we had 0 surface targets set.", ICameraService.ERROR_ILLEGAL_ARGUMENT,
337 e.errorCode);
338 }
Igor Murashkin70725502013-06-25 20:27:06 +0000339
Eino-Ville Talvala70c22072013-08-27 12:09:04 -0700340 builder.addTarget(mSurface);
341 CaptureRequest request2 = builder.build();
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800342 try {
343 SubmitInfo requestInfo = mCameraUser.submitRequest(request2, /* streaming */false);
344 fail("Exception expected");
345 } catch(ServiceSpecificException e) {
346 assertEquals("Expected submitRequest to throw ILLEGAL_ARGUMENT " +
347 "ServiceSpecificException since the target wasn't registered with createStream.",
348 ICameraService.ERROR_ILLEGAL_ARGUMENT, e.errorCode);
349 }
Igor Murashkin70725502013-06-25 20:27:06 +0000350 }
351
352 @SmallTest
353 public void testSubmitGoodRequest() throws Exception {
354
Eino-Ville Talvala70c22072013-08-27 12:09:04 -0700355 CaptureRequest.Builder builder = createDefaultBuilder(/* needStream */true);
356 CaptureRequest request = builder.build();
Igor Murashkin70725502013-06-25 20:27:06 +0000357
358 // Submit valid request twice.
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800359 SubmitInfo requestInfo1 = submitCameraRequest(request, /* streaming */false);
360 SubmitInfo requestInfo2 = submitCameraRequest(request, /* streaming */false);
361 assertNotSame("Request IDs should be unique for multiple requests",
362 requestInfo1.getRequestId(), requestInfo2.getRequestId());
Igor Murashkin70725502013-06-25 20:27:06 +0000363
Igor Murashkin70725502013-06-25 20:27:06 +0000364 }
365
366 @SmallTest
367 public void testSubmitStreamingRequest() throws Exception {
368
Eino-Ville Talvala70c22072013-08-27 12:09:04 -0700369 CaptureRequest.Builder builder = createDefaultBuilder(/* needStream */true);
370
371 CaptureRequest request = builder.build();
Igor Murashkin70725502013-06-25 20:27:06 +0000372
373 // Submit valid request once (non-streaming), and another time
374 // (streaming)
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800375 SubmitInfo requestInfo1 = submitCameraRequest(request, /* streaming */false);
Igor Murashkin70725502013-06-25 20:27:06 +0000376
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800377 SubmitInfo requestInfoStreaming = submitCameraRequest(request, /* streaming */true);
378 assertNotSame("Request IDs should be unique for multiple requests",
379 requestInfo1.getRequestId(),
380 requestInfoStreaming.getRequestId());
Igor Murashkin70725502013-06-25 20:27:06 +0000381
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800382 try {
383 long lastFrameNumber = mCameraUser.cancelRequest(-1);
384 fail("Expected exception");
385 } catch (ServiceSpecificException e) {
386 assertEquals("Invalid request IDs should not be cancellable",
387 ICameraService.ERROR_ILLEGAL_ARGUMENT, e.errorCode);
388 }
Igor Murashkin70725502013-06-25 20:27:06 +0000389
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800390 try {
391 long lastFrameNumber = mCameraUser.cancelRequest(requestInfo1.getRequestId());
392 fail("Expected exception");
393 } catch (ServiceSpecificException e) {
394 assertEquals("Non-streaming request IDs should not be cancellable",
395 ICameraService.ERROR_ILLEGAL_ARGUMENT, e.errorCode);
396 }
Igor Murashkin70725502013-06-25 20:27:06 +0000397
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800398 long lastFrameNumber = mCameraUser.cancelRequest(requestInfoStreaming.getRequestId());
Igor Murashkin70725502013-06-25 20:27:06 +0000399 }
Igor Murashkind7bf1772013-07-12 18:01:31 -0700400
401 @SmallTest
402 public void testCameraInfo() throws RemoteException {
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800403 CameraMetadataNative info = mCameraUser.getCameraInfo();
Igor Murashkind7bf1772013-07-12 18:01:31 -0700404
405 assertFalse(info.isEmpty());
Igor Murashkin68f40062013-09-10 12:15:54 -0700406 assertNotNull(info.get(CameraCharacteristics.SCALER_AVAILABLE_FORMATS));
Igor Murashkind7bf1772013-07-12 18:01:31 -0700407 }
408
Zhijun He7f4d3142013-07-23 07:54:38 -0700409 @SmallTest
Zhijun He20011882013-09-25 10:05:59 -0700410 public void testCameraCharacteristics() throws RemoteException {
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800411 CameraMetadataNative info = mUtils.getCameraService().getCameraCharacteristics(mCameraId);
Zhijun He20011882013-09-25 10:05:59 -0700412
413 assertFalse(info.isEmpty());
414 assertNotNull(info.get(CameraCharacteristics.SCALER_AVAILABLE_FORMATS));
415 }
416
417 @SmallTest
Zhijun He7f4d3142013-07-23 07:54:38 -0700418 public void testWaitUntilIdle() throws Exception {
Eino-Ville Talvala70c22072013-08-27 12:09:04 -0700419 CaptureRequest.Builder builder = createDefaultBuilder(/* needStream */true);
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800420 SubmitInfo requestInfoStreaming = submitCameraRequest(builder.build(), /* streaming */true);
Zhijun He7f4d3142013-07-23 07:54:38 -0700421
422 // Test Bad case first: waitUntilIdle when there is active repeating request
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800423 try {
424 mCameraUser.waitUntilIdle();
425 } catch (ServiceSpecificException e) {
426 assertEquals("waitUntilIdle is invalid operation when there is active repeating request",
427 ICameraService.ERROR_INVALID_OPERATION, e.errorCode);
428 }
Zhijun He7f4d3142013-07-23 07:54:38 -0700429
430 // Test good case, waitUntilIdle when there is no active repeating request
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800431 long lastFrameNumber = mCameraUser.cancelRequest(requestInfoStreaming.getRequestId());
432 mCameraUser.waitUntilIdle();
Zhijun He7f4d3142013-07-23 07:54:38 -0700433 }
434
Zhijun He693e21d2013-07-31 14:16:14 -0700435 @SmallTest
436 public void testCaptureResultCallbacks() throws Exception {
437 IsMetadataNotEmpty matcher = new IsMetadataNotEmpty();
Eino-Ville Talvala70c22072013-08-27 12:09:04 -0700438 CaptureRequest request = createDefaultBuilder(/* needStream */true).build();
Zhijun He693e21d2013-07-31 14:16:14 -0700439
440 // Test both single request and streaming request.
Zhijun He693e21d2013-07-31 14:16:14 -0700441 verify(mMockCb, timeout(WAIT_FOR_COMPLETE_TIMEOUT_MS).times(1)).onResultReceived(
Zhijun He438d77e2014-04-10 17:09:22 -0700442 argThat(matcher),
443 any(CaptureResultExtras.class));
Zhijun He693e21d2013-07-31 14:16:14 -0700444
Zhijun He693e21d2013-07-31 14:16:14 -0700445 verify(mMockCb, timeout(WAIT_FOR_COMPLETE_TIMEOUT_MS).atLeast(NUM_CALLBACKS_CHECKED))
446 .onResultReceived(
Zhijun He438d77e2014-04-10 17:09:22 -0700447 argThat(matcher),
448 any(CaptureResultExtras.class));
Zhijun He693e21d2013-07-31 14:16:14 -0700449 }
Eino-Ville Talvala8ebd52b2013-08-13 12:09:44 -0700450
451 @SmallTest
Eino-Ville Talvalae841d4e2013-09-05 09:04:08 -0700452 public void testCaptureStartedCallbacks() throws Exception {
453 CaptureRequest request = createDefaultBuilder(/* needStream */true).build();
454
455 ArgumentCaptor<Long> timestamps = ArgumentCaptor.forClass(Long.class);
456
457 // Test both single request and streaming request.
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800458 SubmitInfo requestInfo1 = submitCameraRequest(request, /* streaming */false);
Eino-Ville Talvalae841d4e2013-09-05 09:04:08 -0700459 verify(mMockCb, timeout(WAIT_FOR_COMPLETE_TIMEOUT_MS).times(1)).onCaptureStarted(
Zhijun He438d77e2014-04-10 17:09:22 -0700460 any(CaptureResultExtras.class),
Eino-Ville Talvalae841d4e2013-09-05 09:04:08 -0700461 anyLong());
462
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800463 SubmitInfo streamingInfo = submitCameraRequest(request, /* streaming */true);
Eino-Ville Talvalae841d4e2013-09-05 09:04:08 -0700464 verify(mMockCb, timeout(WAIT_FOR_COMPLETE_TIMEOUT_MS).atLeast(NUM_CALLBACKS_CHECKED))
465 .onCaptureStarted(
Zhijun He438d77e2014-04-10 17:09:22 -0700466 any(CaptureResultExtras.class),
Eino-Ville Talvalae841d4e2013-09-05 09:04:08 -0700467 timestamps.capture());
468
469 long timestamp = 0; // All timestamps should be larger than 0.
470 for (Long nextTimestamp : timestamps.getAllValues()) {
471 Log.v(TAG, "next t: " + nextTimestamp + " current t: " + timestamp);
472 assertTrue("Captures are out of order", timestamp < nextTimestamp);
473 timestamp = nextTimestamp;
474 }
475 }
476
477 @SmallTest
478 public void testIdleCallback() throws Exception {
479 int status;
480 CaptureRequest request = createDefaultBuilder(/* needStream */true).build();
481
482 // Try streaming
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800483 SubmitInfo streamingInfo = submitCameraRequest(request, /* streaming */true);
Eino-Ville Talvalae841d4e2013-09-05 09:04:08 -0700484
485 // Wait a bit to fill up the queue
486 SystemClock.sleep(WAIT_FOR_WORK_MS);
487
488 // Cancel and make sure we eventually quiesce
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800489 long lastFrameNumber = mCameraUser.cancelRequest(streamingInfo.getRequestId());
Eino-Ville Talvalae841d4e2013-09-05 09:04:08 -0700490
Eino-Ville Talvalaacc00952014-08-06 14:31:08 -0700491 verify(mMockCb, timeout(WAIT_FOR_IDLE_TIMEOUT_MS).times(1)).onDeviceIdle();
Eino-Ville Talvalae841d4e2013-09-05 09:04:08 -0700492
493 // Submit a few capture requests
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800494 SubmitInfo requestInfo1 = submitCameraRequest(request, /* streaming */false);
495 SubmitInfo requestInfo2 = submitCameraRequest(request, /* streaming */false);
496 SubmitInfo requestInfo3 = submitCameraRequest(request, /* streaming */false);
497 SubmitInfo requestInfo4 = submitCameraRequest(request, /* streaming */false);
498 SubmitInfo requestInfo5 = submitCameraRequest(request, /* streaming */false);
Eino-Ville Talvalae841d4e2013-09-05 09:04:08 -0700499
500 // And wait for more idle
Eino-Ville Talvalaacc00952014-08-06 14:31:08 -0700501 verify(mMockCb, timeout(WAIT_FOR_IDLE_TIMEOUT_MS).times(2)).onDeviceIdle();
Eino-Ville Talvalae841d4e2013-09-05 09:04:08 -0700502
503 }
504
505 @SmallTest
Eino-Ville Talvala8ebd52b2013-08-13 12:09:44 -0700506 public void testFlush() throws Exception {
507 int status;
508
509 // Initial flush should work
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800510 long lastFrameNumber = mCameraUser.flush();
Eino-Ville Talvala8ebd52b2013-08-13 12:09:44 -0700511
512 // Then set up a stream
Eino-Ville Talvala70c22072013-08-27 12:09:04 -0700513 CaptureRequest request = createDefaultBuilder(/* needStream */true).build();
Eino-Ville Talvala8ebd52b2013-08-13 12:09:44 -0700514
515 // Flush should still be a no-op, really
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800516 lastFrameNumber = mCameraUser.flush();
Eino-Ville Talvala8ebd52b2013-08-13 12:09:44 -0700517
518 // Submit a few capture requests
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800519 SubmitInfo requestInfo1 = submitCameraRequest(request, /* streaming */false);
520 SubmitInfo requestInfo2 = submitCameraRequest(request, /* streaming */false);
521 SubmitInfo requestInfo3 = submitCameraRequest(request, /* streaming */false);
522 SubmitInfo requestInfo4 = submitCameraRequest(request, /* streaming */false);
523 SubmitInfo requestInfo5 = submitCameraRequest(request, /* streaming */false);
Eino-Ville Talvala8ebd52b2013-08-13 12:09:44 -0700524
Eino-Ville Talvalae841d4e2013-09-05 09:04:08 -0700525 // Then flush and wait for idle
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800526 lastFrameNumber = mCameraUser.flush();
Eino-Ville Talvala8ebd52b2013-08-13 12:09:44 -0700527
Eino-Ville Talvalaacc00952014-08-06 14:31:08 -0700528 verify(mMockCb, timeout(WAIT_FOR_FLUSH_TIMEOUT_MS).times(1)).onDeviceIdle();
Eino-Ville Talvalae841d4e2013-09-05 09:04:08 -0700529
530 // Now a streaming request
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800531 SubmitInfo streamingInfo = submitCameraRequest(request, /* streaming */true);
Eino-Ville Talvalae841d4e2013-09-05 09:04:08 -0700532
533 // Wait a bit to fill up the queue
534 SystemClock.sleep(WAIT_FOR_WORK_MS);
535
536 // Then flush and wait for the idle callback
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800537 lastFrameNumber = mCameraUser.flush();
Eino-Ville Talvalae841d4e2013-09-05 09:04:08 -0700538
Eino-Ville Talvalaacc00952014-08-06 14:31:08 -0700539 verify(mMockCb, timeout(WAIT_FOR_FLUSH_TIMEOUT_MS).times(2)).onDeviceIdle();
Eino-Ville Talvalae841d4e2013-09-05 09:04:08 -0700540
Eino-Ville Talvala8ebd52b2013-08-13 12:09:44 -0700541 // TODO: When errors are hooked up, count that errors + successful
542 // requests equal to 5.
543 }
Igor Murashkin70725502013-06-25 20:27:06 +0000544}