blob: d8c975f44c6a56b97bf5d95090f35c4d06293911 [file] [log] [blame]
Igor Murashkin4491d682013-05-31 16:43:48 -07001/*
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
Igor Murashkin4491d682013-05-31 16:43:48 -070019import android.hardware.CameraInfo;
20import android.hardware.ICamera;
21import android.hardware.ICameraClient;
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -080022import android.hardware.ICameraService;
Igor Murashkin4491d682013-05-31 16:43:48 -070023import android.hardware.ICameraServiceListener;
Eino-Ville Talvala2f1a2e42013-07-25 17:12:05 -070024import android.hardware.camera2.ICameraDeviceCallbacks;
25import android.hardware.camera2.ICameraDeviceUser;
Eino-Ville Talvala70c22072013-08-27 12:09:04 -070026import android.hardware.camera2.impl.CameraMetadataNative;
Igor Murashkin72f9f0a2014-05-14 15:46:10 -070027import android.hardware.camera2.impl.CaptureResultExtras;
Shuzhen Wang0960fb42018-01-10 20:35:11 -080028import android.hardware.camera2.impl.PhysicalCaptureResultInfo;
Igor Murashkin4491d682013-05-31 16:43:48 -070029import android.os.Binder;
30import android.os.IBinder;
31import android.os.RemoteException;
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -080032import android.os.ServiceSpecificException;
Igor Murashkin4491d682013-05-31 16:43:48 -070033import android.test.AndroidTestCase;
34import android.test.suitebuilder.annotation.SmallTest;
35import android.util.Log;
36
37/**
Igor Murashkin70725502013-06-25 20:27:06 +000038 * <p>
Igor Murashkin4491d682013-05-31 16:43:48 -070039 * Junit / Instrumentation test case for the camera2 api
Igor Murashkin70725502013-06-25 20:27:06 +000040 * </p>
41 * <p>
42 * To run only tests in this class:
43 * </p>
Igor Murashkin4491d682013-05-31 16:43:48 -070044 *
Igor Murashkin70725502013-06-25 20:27:06 +000045 * <pre>
Igor Murashkin4491d682013-05-31 16:43:48 -070046 * adb shell am instrument \
Igor Murashkin70725502013-06-25 20:27:06 +000047 * -e class com.android.mediaframeworktest.integration.CameraBinderTest \
48 * -w com.android.mediaframeworktest/.MediaFrameworkIntegrationTestRunner
49 * </pre>
Igor Murashkin4491d682013-05-31 16:43:48 -070050 */
51public class CameraBinderTest extends AndroidTestCase {
Igor Murashkin4961bc82014-06-17 12:04:07 -070052 private static final int MAX_PARAMETERS_LENGTH = 100;
53
Igor Murashkin70725502013-06-25 20:27:06 +000054 static String TAG = "CameraBinderTest";
Igor Murashkin4491d682013-05-31 16:43:48 -070055
Igor Murashkin4961bc82014-06-17 12:04:07 -070056 // From ICameraService.h
57 private static final int API_VERSION_1 = 1;
58 private static final int API_VERSION_2 = 2;
59
Eino-Ville Talvala57176122015-08-14 13:11:16 -070060 private static final int CAMERA_TYPE_BACKWARD_COMPATIBLE = 0;
61 private static final int CAMERA_TYPE_ALL = 1;
62
Igor Murashkin70725502013-06-25 20:27:06 +000063 protected CameraBinderTestUtils mUtils;
Igor Murashkin4491d682013-05-31 16:43:48 -070064
65 public CameraBinderTest() {
66 }
67
Igor Murashkin70725502013-06-25 20:27:06 +000068 @Override
Igor Murashkin4491d682013-05-31 16:43:48 -070069 protected void setUp() throws Exception {
70 super.setUp();
71
Igor Murashkin70725502013-06-25 20:27:06 +000072 mUtils = new CameraBinderTestUtils(getContext());
Igor Murashkin4491d682013-05-31 16:43:48 -070073 }
74
75 @SmallTest
76 public void testNumberOfCameras() throws Exception {
Igor Murashkin70725502013-06-25 20:27:06 +000077
Eino-Ville Talvala57176122015-08-14 13:11:16 -070078 int numCameras = mUtils.getCameraService().getNumberOfCameras(CAMERA_TYPE_ALL);
Igor Murashkin70725502013-06-25 20:27:06 +000079 assertTrue("At least this many cameras: " + mUtils.getGuessedNumCameras(),
80 numCameras >= mUtils.getGuessedNumCameras());
Igor Murashkin4491d682013-05-31 16:43:48 -070081 Log.v(TAG, "Number of cameras " + numCameras);
82 }
83
84 @SmallTest
85 public void testCameraInfo() throws Exception {
Igor Murashkin70725502013-06-25 20:27:06 +000086 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
Igor Murashkin4491d682013-05-31 16:43:48 -070087
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -080088 CameraInfo info = mUtils.getCameraService().getCameraInfo(cameraId);
Igor Murashkin4491d682013-05-31 16:43:48 -070089 assertTrue("Facing was not set for camera " + cameraId, info.info.facing != -1);
90 assertTrue("Orientation was not set for camera " + cameraId,
91 info.info.orientation != -1);
92
93 Log.v(TAG, "Camera " + cameraId + " info: facing " + info.info.facing
94 + ", orientation " + info.info.orientation);
95 }
96 }
97
Igor Murashkin4961bc82014-06-17 12:04:07 -070098 @SmallTest
99 public void testGetLegacyParameters() throws Exception {
100 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
101
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800102 String parameters = mUtils.getCameraService().getLegacyParameters(cameraId);
103 assertNotNull(parameters);
Igor Murashkin4961bc82014-06-17 12:04:07 -0700104 assertTrue("Parameters should have at least one character in it",
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800105 parameters.length() > 0);
Igor Murashkin4961bc82014-06-17 12:04:07 -0700106
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800107 int end = parameters.length();
Igor Murashkin4961bc82014-06-17 12:04:07 -0700108 if (end > MAX_PARAMETERS_LENGTH) {
109 end = MAX_PARAMETERS_LENGTH;
110 }
111
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800112 Log.v(TAG, "Camera " + cameraId + " parameters: " + parameters.substring(0, end));
Igor Murashkin4961bc82014-06-17 12:04:07 -0700113 }
114 }
115
116 /** The camera2 api is only supported on HAL3.2+ devices */
117 @SmallTest
118 public void testSupportsCamera2Api() throws Exception {
119 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
Eino-Ville Talvala283ae234f2016-12-08 13:38:52 -0800120 boolean supports = mUtils.getCameraService().supportsCameraApi(
121 String.valueOf(cameraId), API_VERSION_2);
Igor Murashkin4961bc82014-06-17 12:04:07 -0700122
Igor Murashkin4961bc82014-06-17 12:04:07 -0700123 Log.v(TAG, "Camera " + cameraId + " supports api2: " + supports);
124 }
125 }
126
127 /** The camera1 api is supported on *all* devices regardless of HAL version */
128 @SmallTest
129 public void testSupportsCamera1Api() throws Exception {
130 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
131
Eino-Ville Talvala283ae234f2016-12-08 13:38:52 -0800132 boolean supports = mUtils.getCameraService().supportsCameraApi(
133 String.valueOf(cameraId), API_VERSION_1);
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800134 assertTrue(
135 "Camera service returned false when queried if it supports camera1 api " +
136 " for camera ID " + cameraId, supports);
Igor Murashkin4961bc82014-06-17 12:04:07 -0700137 }
138 }
139
Igor Murashkin4491d682013-05-31 16:43:48 -0700140 static abstract class DummyBase extends Binder implements android.os.IInterface {
141 @Override
142 public IBinder asBinder() {
143 return this;
144 }
145 }
146
147 static class DummyCameraClient extends DummyBase implements ICameraClient {
148 }
149
150 @SmallTest
151 public void testConnect() throws Exception {
Igor Murashkin70725502013-06-25 20:27:06 +0000152 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
Igor Murashkin4491d682013-05-31 16:43:48 -0700153
154 ICameraClient dummyCallbacks = new DummyCameraClient();
155
156 String clientPackageName = getContext().getPackageName();
157
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800158 ICamera cameraUser = mUtils.getCameraService()
Ruben Brunk66ef6452013-08-08 13:05:30 -0700159 .connect(dummyCallbacks, cameraId, clientPackageName,
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800160 ICameraService.USE_CALLING_UID,
161 ICameraService.USE_CALLING_PID);
Igor Murashkin4491d682013-05-31 16:43:48 -0700162 assertNotNull(String.format("Camera %s was null", cameraId), cameraUser);
163
164 Log.v(TAG, String.format("Camera %s connected", cameraId));
165
166 cameraUser.disconnect();
167 }
168 }
169
Zhijun He4c913802014-06-16 16:42:35 -0700170 @SmallTest
171 public void testConnectLegacy() throws Exception {
172 final int CAMERA_HAL_API_VERSION_1_0 = 0x100;
173 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
174 ICamera cameraUser = null;
175 ICameraClient dummyCallbacks = new DummyCameraClient();
176
177 String clientPackageName = getContext().getPackageName();
178
Zhijun He4c913802014-06-16 16:42:35 -0700179 try {
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800180 cameraUser = mUtils.getCameraService()
Zhijun He4c913802014-06-16 16:42:35 -0700181 .connectLegacy(dummyCallbacks, cameraId, CAMERA_HAL_API_VERSION_1_0,
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800182 clientPackageName,
183 ICameraService.USE_CALLING_UID);
Zhijun He4c913802014-06-16 16:42:35 -0700184 assertNotNull(String.format("Camera %s was null", cameraId), cameraUser);
185
186 Log.v(TAG, String.format("Camera %s connected as HAL1 legacy device", cameraId));
187 } catch (RuntimeException e) {
188 // Not all camera device support openLegacy.
189 Log.i(TAG, "Unable to open camera as HAL1 legacy camera device " + e);
190 } finally {
191 if (cameraUser != null) {
192 cameraUser.disconnect();
193 }
194 }
195 }
196 }
197
Zhijun He693e21d2013-07-31 14:16:14 -0700198 static class DummyCameraDeviceCallbacks extends ICameraDeviceCallbacks.Stub {
Igor Murashkin70725502013-06-25 20:27:06 +0000199
Zhijun He438d77e2014-04-10 17:09:22 -0700200 /*
201 * (non-Javadoc)
202 * @see
203 * android.hardware.camera2.ICameraDeviceCallbacks#onCameraError(int,
204 * android.hardware.camera2.CaptureResultExtras)
205 */
Igor Murashkin4961bc82014-06-17 12:04:07 -0700206 @Override
Eino-Ville Talvalaacc00952014-08-06 14:31:08 -0700207 public void onDeviceError(int errorCode, CaptureResultExtras resultExtras)
Eino-Ville Talvalae841d4e2013-09-05 09:04:08 -0700208 throws RemoteException {
Zhijun He438d77e2014-04-10 17:09:22 -0700209 // TODO Auto-generated method stub
210
211 }
212
213 /*
214 * (non-Javadoc)
215 * @see
216 * android.hardware.camera2.ICameraDeviceCallbacks#onCaptureStarted(
217 * android.hardware.camera2.CaptureResultExtras, long)
218 */
Igor Murashkin4961bc82014-06-17 12:04:07 -0700219 @Override
Zhijun He438d77e2014-04-10 17:09:22 -0700220 public void onCaptureStarted(CaptureResultExtras resultExtras, long timestamp)
221 throws RemoteException {
222 // TODO Auto-generated method stub
223
224 }
225
226 /*
227 * (non-Javadoc)
228 * @see
229 * android.hardware.camera2.ICameraDeviceCallbacks#onResultReceived(
230 * android.hardware.camera2.impl.CameraMetadataNative,
231 * android.hardware.camera2.CaptureResultExtras)
232 */
Igor Murashkin4961bc82014-06-17 12:04:07 -0700233 @Override
Shuzhen Wang0960fb42018-01-10 20:35:11 -0800234 public void onResultReceived(CameraMetadataNative result, CaptureResultExtras resultExtras,
235 PhysicalCaptureResultInfo physicalResults[]) throws RemoteException {
Zhijun He438d77e2014-04-10 17:09:22 -0700236 // TODO Auto-generated method stub
237
238 }
239
240 /*
241 * (non-Javadoc)
242 * @see android.hardware.camera2.ICameraDeviceCallbacks#onCameraIdle()
243 */
Igor Murashkin4961bc82014-06-17 12:04:07 -0700244 @Override
Eino-Ville Talvalaacc00952014-08-06 14:31:08 -0700245 public void onDeviceIdle() throws RemoteException {
Zhijun He438d77e2014-04-10 17:09:22 -0700246 // TODO Auto-generated method stub
247
Igor Murashkin70725502013-06-25 20:27:06 +0000248 }
Eino-Ville Talvalaad916f72015-04-11 12:09:11 -0700249
250 /*
251 * (non-Javadoc)
252 * @see android.hardware.camera2.ICameraDeviceCallbacks#onPrepared()
253 */
254 @Override
255 public void onPrepared(int streamId) throws RemoteException {
256 // TODO Auto-generated method stub
257
258 }
Chien-Yu Chen2da496f2016-04-14 13:33:00 -0700259
260 /*
261 * (non-Javadoc)
Shuzhen Wang88f1af22016-09-30 10:29:28 -0700262 * @see android.hardware.camera2.ICameraDeviceCallbacks#onRequestQueueEmpty()
263 */
264 @Override
265 public void onRequestQueueEmpty() throws RemoteException {
266 // TODO Auto-generated method stub
267
268 }
269
270 /*
271 * (non-Javadoc)
Chien-Yu Chen2da496f2016-04-14 13:33:00 -0700272 * @see android.hardware.camera2.ICameraDeviceCallbacks#onRepeatingRequestError()
273 */
274 @Override
Yin-Chia Yeh8cd12e92017-09-05 18:14:21 -0700275 public void onRepeatingRequestError(long lastFrameNumber, int repeatingRequestId) {
Chien-Yu Chen2da496f2016-04-14 13:33:00 -0700276 // TODO Auto-generated method stub
277 }
Igor Murashkin70725502013-06-25 20:27:06 +0000278 }
279
280 @SmallTest
281 public void testConnectDevice() throws Exception {
282 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
283
284 ICameraDeviceCallbacks dummyCallbacks = new DummyCameraDeviceCallbacks();
285
286 String clientPackageName = getContext().getPackageName();
287
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800288 ICameraDeviceUser cameraUser =
289 mUtils.getCameraService().connectDevice(
Eino-Ville Talvala283ae234f2016-12-08 13:38:52 -0800290 dummyCallbacks, String.valueOf(cameraId),
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800291 clientPackageName,
292 ICameraService.USE_CALLING_UID);
Igor Murashkin4491d682013-05-31 16:43:48 -0700293 assertNotNull(String.format("Camera %s was null", cameraId), cameraUser);
294
295 Log.v(TAG, String.format("Camera %s connected", cameraId));
296
297 cameraUser.disconnect();
298 }
299 }
300
Zhijun He693e21d2013-07-31 14:16:14 -0700301 static class DummyCameraServiceListener extends ICameraServiceListener.Stub {
Igor Murashkin4491d682013-05-31 16:43:48 -0700302 @Override
Eino-Ville Talvala283ae234f2016-12-08 13:38:52 -0800303 public void onStatusChanged(int status, String cameraId)
Igor Murashkin4491d682013-05-31 16:43:48 -0700304 throws RemoteException {
Eino-Ville Talvala283ae234f2016-12-08 13:38:52 -0800305 Log.v(TAG, String.format("Camera %s has status changed to 0x%x", cameraId, status));
Igor Murashkin4491d682013-05-31 16:43:48 -0700306 }
Chien-Yu Chenafa91392015-02-11 11:23:28 -0800307 public void onTorchStatusChanged(int status, String cameraId)
308 throws RemoteException {
309 Log.v(TAG, String.format("Camera %s has torch status changed to 0x%x",
310 cameraId, status));
311 }
Igor Murashkin4491d682013-05-31 16:43:48 -0700312 }
313
314 /**
Igor Murashkin70725502013-06-25 20:27:06 +0000315 * <pre>
Igor Murashkin4491d682013-05-31 16:43:48 -0700316 * adb shell am instrument \
Igor Murashkin70725502013-06-25 20:27:06 +0000317 * -e class 'com.android.mediaframeworktest.integration.CameraBinderTest#testAddRemoveListeners' \
318 * -w com.android.mediaframeworktest/.MediaFrameworkIntegrationTestRunner
319 * </pre>
Igor Murashkin4491d682013-05-31 16:43:48 -0700320 */
321 @SmallTest
322 public void testAddRemoveListeners() throws Exception {
Igor Murashkin70725502013-06-25 20:27:06 +0000323 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
Igor Murashkin4491d682013-05-31 16:43:48 -0700324
325 ICameraServiceListener listener = new DummyCameraServiceListener();
326
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800327 try {
328 mUtils.getCameraService().removeListener(listener);
329 fail("Listener was removed before added");
330 } catch (ServiceSpecificException e) {
331 assertEquals("Listener was removed before added",
332 e.errorCode, ICameraService.ERROR_ILLEGAL_ARGUMENT);
333 }
Igor Murashkin4491d682013-05-31 16:43:48 -0700334
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800335 mUtils.getCameraService().addListener(listener);
Igor Murashkin4491d682013-05-31 16:43:48 -0700336
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800337 try {
338 mUtils.getCameraService().addListener(listener);
339 fail("Listener was wrongly added again");
340 } catch (ServiceSpecificException e) {
341 assertEquals("Listener was wrongly added again",
342 e.errorCode, ICameraService.ERROR_ALREADY_EXISTS);
343 }
344
345 mUtils.getCameraService().removeListener(listener);
346
347 try {
348 mUtils.getCameraService().removeListener(listener);
349 fail("Listener was wrongly removed twice");
350 } catch (ServiceSpecificException e) {
351 assertEquals("Listener was wrongly removed twice",
352 e.errorCode, ICameraService.ERROR_ILLEGAL_ARGUMENT);
353 }
Igor Murashkin4491d682013-05-31 16:43:48 -0700354 }
355 }
356}