blob: cf5882f92b00af8116c4974cd9c82e8f7d11c854 [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;
Igor Murashkin4491d682013-05-31 16:43:48 -070028import android.os.Binder;
29import android.os.IBinder;
30import android.os.RemoteException;
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -080031import android.os.ServiceSpecificException;
Igor Murashkin4491d682013-05-31 16:43:48 -070032import android.test.AndroidTestCase;
33import android.test.suitebuilder.annotation.SmallTest;
34import android.util.Log;
35
36/**
Igor Murashkin70725502013-06-25 20:27:06 +000037 * <p>
Igor Murashkin4491d682013-05-31 16:43:48 -070038 * Junit / Instrumentation test case for the camera2 api
Igor Murashkin70725502013-06-25 20:27:06 +000039 * </p>
40 * <p>
41 * To run only tests in this class:
42 * </p>
Igor Murashkin4491d682013-05-31 16:43:48 -070043 *
Igor Murashkin70725502013-06-25 20:27:06 +000044 * <pre>
Igor Murashkin4491d682013-05-31 16:43:48 -070045 * adb shell am instrument \
Igor Murashkin70725502013-06-25 20:27:06 +000046 * -e class com.android.mediaframeworktest.integration.CameraBinderTest \
47 * -w com.android.mediaframeworktest/.MediaFrameworkIntegrationTestRunner
48 * </pre>
Igor Murashkin4491d682013-05-31 16:43:48 -070049 */
50public class CameraBinderTest extends AndroidTestCase {
Igor Murashkin4961bc82014-06-17 12:04:07 -070051 private static final int MAX_PARAMETERS_LENGTH = 100;
52
Igor Murashkin70725502013-06-25 20:27:06 +000053 static String TAG = "CameraBinderTest";
Igor Murashkin4491d682013-05-31 16:43:48 -070054
Igor Murashkin4961bc82014-06-17 12:04:07 -070055 // From ICameraService.h
56 private static final int API_VERSION_1 = 1;
57 private static final int API_VERSION_2 = 2;
58
Eino-Ville Talvala57176122015-08-14 13:11:16 -070059 private static final int CAMERA_TYPE_BACKWARD_COMPATIBLE = 0;
60 private static final int CAMERA_TYPE_ALL = 1;
61
Igor Murashkin70725502013-06-25 20:27:06 +000062 protected CameraBinderTestUtils mUtils;
Igor Murashkin4491d682013-05-31 16:43:48 -070063
64 public CameraBinderTest() {
65 }
66
Igor Murashkin70725502013-06-25 20:27:06 +000067 @Override
Igor Murashkin4491d682013-05-31 16:43:48 -070068 protected void setUp() throws Exception {
69 super.setUp();
70
Igor Murashkin70725502013-06-25 20:27:06 +000071 mUtils = new CameraBinderTestUtils(getContext());
Igor Murashkin4491d682013-05-31 16:43:48 -070072 }
73
74 @SmallTest
75 public void testNumberOfCameras() throws Exception {
Igor Murashkin70725502013-06-25 20:27:06 +000076
Eino-Ville Talvala57176122015-08-14 13:11:16 -070077 int numCameras = mUtils.getCameraService().getNumberOfCameras(CAMERA_TYPE_ALL);
Igor Murashkin70725502013-06-25 20:27:06 +000078 assertTrue("At least this many cameras: " + mUtils.getGuessedNumCameras(),
79 numCameras >= mUtils.getGuessedNumCameras());
Igor Murashkin4491d682013-05-31 16:43:48 -070080 Log.v(TAG, "Number of cameras " + numCameras);
81 }
82
83 @SmallTest
84 public void testCameraInfo() throws Exception {
Igor Murashkin70725502013-06-25 20:27:06 +000085 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
Igor Murashkin4491d682013-05-31 16:43:48 -070086
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -080087 CameraInfo info = mUtils.getCameraService().getCameraInfo(cameraId);
Igor Murashkin4491d682013-05-31 16:43:48 -070088 assertTrue("Facing was not set for camera " + cameraId, info.info.facing != -1);
89 assertTrue("Orientation was not set for camera " + cameraId,
90 info.info.orientation != -1);
91
92 Log.v(TAG, "Camera " + cameraId + " info: facing " + info.info.facing
93 + ", orientation " + info.info.orientation);
94 }
95 }
96
Igor Murashkin4961bc82014-06-17 12:04:07 -070097 @SmallTest
98 public void testGetLegacyParameters() throws Exception {
99 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
100
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800101 String parameters = mUtils.getCameraService().getLegacyParameters(cameraId);
102 assertNotNull(parameters);
Igor Murashkin4961bc82014-06-17 12:04:07 -0700103 assertTrue("Parameters should have at least one character in it",
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800104 parameters.length() > 0);
Igor Murashkin4961bc82014-06-17 12:04:07 -0700105
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800106 int end = parameters.length();
Igor Murashkin4961bc82014-06-17 12:04:07 -0700107 if (end > MAX_PARAMETERS_LENGTH) {
108 end = MAX_PARAMETERS_LENGTH;
109 }
110
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800111 Log.v(TAG, "Camera " + cameraId + " parameters: " + parameters.substring(0, end));
Igor Murashkin4961bc82014-06-17 12:04:07 -0700112 }
113 }
114
115 /** The camera2 api is only supported on HAL3.2+ devices */
116 @SmallTest
117 public void testSupportsCamera2Api() throws Exception {
118 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
Eino-Ville Talvala283ae234f2016-12-08 13:38:52 -0800119 boolean supports = mUtils.getCameraService().supportsCameraApi(
120 String.valueOf(cameraId), API_VERSION_2);
Igor Murashkin4961bc82014-06-17 12:04:07 -0700121
Igor Murashkin4961bc82014-06-17 12:04:07 -0700122 Log.v(TAG, "Camera " + cameraId + " supports api2: " + supports);
123 }
124 }
125
126 /** The camera1 api is supported on *all* devices regardless of HAL version */
127 @SmallTest
128 public void testSupportsCamera1Api() throws Exception {
129 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
130
Eino-Ville Talvala283ae234f2016-12-08 13:38:52 -0800131 boolean supports = mUtils.getCameraService().supportsCameraApi(
132 String.valueOf(cameraId), API_VERSION_1);
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800133 assertTrue(
134 "Camera service returned false when queried if it supports camera1 api " +
135 " for camera ID " + cameraId, supports);
Igor Murashkin4961bc82014-06-17 12:04:07 -0700136 }
137 }
138
Igor Murashkin4491d682013-05-31 16:43:48 -0700139 static abstract class DummyBase extends Binder implements android.os.IInterface {
140 @Override
141 public IBinder asBinder() {
142 return this;
143 }
144 }
145
146 static class DummyCameraClient extends DummyBase implements ICameraClient {
147 }
148
149 @SmallTest
150 public void testConnect() throws Exception {
Igor Murashkin70725502013-06-25 20:27:06 +0000151 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
Igor Murashkin4491d682013-05-31 16:43:48 -0700152
153 ICameraClient dummyCallbacks = new DummyCameraClient();
154
155 String clientPackageName = getContext().getPackageName();
156
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800157 ICamera cameraUser = mUtils.getCameraService()
Ruben Brunk66ef6452013-08-08 13:05:30 -0700158 .connect(dummyCallbacks, cameraId, clientPackageName,
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800159 ICameraService.USE_CALLING_UID,
160 ICameraService.USE_CALLING_PID);
Igor Murashkin4491d682013-05-31 16:43:48 -0700161 assertNotNull(String.format("Camera %s was null", cameraId), cameraUser);
162
163 Log.v(TAG, String.format("Camera %s connected", cameraId));
164
165 cameraUser.disconnect();
166 }
167 }
168
Zhijun He4c913802014-06-16 16:42:35 -0700169 @SmallTest
170 public void testConnectLegacy() throws Exception {
171 final int CAMERA_HAL_API_VERSION_1_0 = 0x100;
172 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
173 ICamera cameraUser = null;
174 ICameraClient dummyCallbacks = new DummyCameraClient();
175
176 String clientPackageName = getContext().getPackageName();
177
Zhijun He4c913802014-06-16 16:42:35 -0700178 try {
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800179 cameraUser = mUtils.getCameraService()
Zhijun He4c913802014-06-16 16:42:35 -0700180 .connectLegacy(dummyCallbacks, cameraId, CAMERA_HAL_API_VERSION_1_0,
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800181 clientPackageName,
182 ICameraService.USE_CALLING_UID);
Zhijun He4c913802014-06-16 16:42:35 -0700183 assertNotNull(String.format("Camera %s was null", cameraId), cameraUser);
184
185 Log.v(TAG, String.format("Camera %s connected as HAL1 legacy device", cameraId));
186 } catch (RuntimeException e) {
187 // Not all camera device support openLegacy.
188 Log.i(TAG, "Unable to open camera as HAL1 legacy camera device " + e);
189 } finally {
190 if (cameraUser != null) {
191 cameraUser.disconnect();
192 }
193 }
194 }
195 }
196
Zhijun He693e21d2013-07-31 14:16:14 -0700197 static class DummyCameraDeviceCallbacks extends ICameraDeviceCallbacks.Stub {
Igor Murashkin70725502013-06-25 20:27:06 +0000198
Zhijun He438d77e2014-04-10 17:09:22 -0700199 /*
200 * (non-Javadoc)
201 * @see
202 * android.hardware.camera2.ICameraDeviceCallbacks#onCameraError(int,
203 * android.hardware.camera2.CaptureResultExtras)
204 */
Igor Murashkin4961bc82014-06-17 12:04:07 -0700205 @Override
Eino-Ville Talvalaacc00952014-08-06 14:31:08 -0700206 public void onDeviceError(int errorCode, CaptureResultExtras resultExtras)
Eino-Ville Talvalae841d4e2013-09-05 09:04:08 -0700207 throws RemoteException {
Zhijun He438d77e2014-04-10 17:09:22 -0700208 // TODO Auto-generated method stub
209
210 }
211
212 /*
213 * (non-Javadoc)
214 * @see
215 * android.hardware.camera2.ICameraDeviceCallbacks#onCaptureStarted(
216 * android.hardware.camera2.CaptureResultExtras, long)
217 */
Igor Murashkin4961bc82014-06-17 12:04:07 -0700218 @Override
Zhijun He438d77e2014-04-10 17:09:22 -0700219 public void onCaptureStarted(CaptureResultExtras resultExtras, long timestamp)
220 throws RemoteException {
221 // TODO Auto-generated method stub
222
223 }
224
225 /*
226 * (non-Javadoc)
227 * @see
228 * android.hardware.camera2.ICameraDeviceCallbacks#onResultReceived(
229 * android.hardware.camera2.impl.CameraMetadataNative,
230 * android.hardware.camera2.CaptureResultExtras)
231 */
Igor Murashkin4961bc82014-06-17 12:04:07 -0700232 @Override
Zhijun He438d77e2014-04-10 17:09:22 -0700233 public void onResultReceived(CameraMetadataNative result, CaptureResultExtras resultExtras)
234 throws RemoteException {
235 // TODO Auto-generated method stub
236
237 }
238
239 /*
240 * (non-Javadoc)
241 * @see android.hardware.camera2.ICameraDeviceCallbacks#onCameraIdle()
242 */
Igor Murashkin4961bc82014-06-17 12:04:07 -0700243 @Override
Eino-Ville Talvalaacc00952014-08-06 14:31:08 -0700244 public void onDeviceIdle() throws RemoteException {
Zhijun He438d77e2014-04-10 17:09:22 -0700245 // TODO Auto-generated method stub
246
Igor Murashkin70725502013-06-25 20:27:06 +0000247 }
Eino-Ville Talvalaad916f72015-04-11 12:09:11 -0700248
249 /*
250 * (non-Javadoc)
251 * @see android.hardware.camera2.ICameraDeviceCallbacks#onPrepared()
252 */
253 @Override
254 public void onPrepared(int streamId) throws RemoteException {
255 // TODO Auto-generated method stub
256
257 }
Chien-Yu Chen2da496f2016-04-14 13:33:00 -0700258
259 /*
260 * (non-Javadoc)
Shuzhen Wang88f1af22016-09-30 10:29:28 -0700261 * @see android.hardware.camera2.ICameraDeviceCallbacks#onRequestQueueEmpty()
262 */
263 @Override
264 public void onRequestQueueEmpty() throws RemoteException {
265 // TODO Auto-generated method stub
266
267 }
268
269 /*
270 * (non-Javadoc)
Chien-Yu Chen2da496f2016-04-14 13:33:00 -0700271 * @see android.hardware.camera2.ICameraDeviceCallbacks#onRepeatingRequestError()
272 */
273 @Override
Yin-Chia Yeh8cd12e92017-09-05 18:14:21 -0700274 public void onRepeatingRequestError(long lastFrameNumber, int repeatingRequestId) {
Chien-Yu Chen2da496f2016-04-14 13:33:00 -0700275 // TODO Auto-generated method stub
276 }
Igor Murashkin70725502013-06-25 20:27:06 +0000277 }
278
279 @SmallTest
280 public void testConnectDevice() throws Exception {
281 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
282
283 ICameraDeviceCallbacks dummyCallbacks = new DummyCameraDeviceCallbacks();
284
285 String clientPackageName = getContext().getPackageName();
286
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800287 ICameraDeviceUser cameraUser =
288 mUtils.getCameraService().connectDevice(
Eino-Ville Talvala283ae234f2016-12-08 13:38:52 -0800289 dummyCallbacks, String.valueOf(cameraId),
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800290 clientPackageName,
291 ICameraService.USE_CALLING_UID);
Igor Murashkin4491d682013-05-31 16:43:48 -0700292 assertNotNull(String.format("Camera %s was null", cameraId), cameraUser);
293
294 Log.v(TAG, String.format("Camera %s connected", cameraId));
295
296 cameraUser.disconnect();
297 }
298 }
299
Zhijun He693e21d2013-07-31 14:16:14 -0700300 static class DummyCameraServiceListener extends ICameraServiceListener.Stub {
Igor Murashkin4491d682013-05-31 16:43:48 -0700301 @Override
Eino-Ville Talvala283ae234f2016-12-08 13:38:52 -0800302 public void onStatusChanged(int status, String cameraId)
Igor Murashkin4491d682013-05-31 16:43:48 -0700303 throws RemoteException {
Eino-Ville Talvala283ae234f2016-12-08 13:38:52 -0800304 Log.v(TAG, String.format("Camera %s has status changed to 0x%x", cameraId, status));
Igor Murashkin4491d682013-05-31 16:43:48 -0700305 }
Chien-Yu Chenafa91392015-02-11 11:23:28 -0800306 public void onTorchStatusChanged(int status, String cameraId)
307 throws RemoteException {
308 Log.v(TAG, String.format("Camera %s has torch status changed to 0x%x",
309 cameraId, status));
310 }
Igor Murashkin4491d682013-05-31 16:43:48 -0700311 }
312
313 /**
Igor Murashkin70725502013-06-25 20:27:06 +0000314 * <pre>
Igor Murashkin4491d682013-05-31 16:43:48 -0700315 * adb shell am instrument \
Igor Murashkin70725502013-06-25 20:27:06 +0000316 * -e class 'com.android.mediaframeworktest.integration.CameraBinderTest#testAddRemoveListeners' \
317 * -w com.android.mediaframeworktest/.MediaFrameworkIntegrationTestRunner
318 * </pre>
Igor Murashkin4491d682013-05-31 16:43:48 -0700319 */
320 @SmallTest
321 public void testAddRemoveListeners() throws Exception {
Igor Murashkin70725502013-06-25 20:27:06 +0000322 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
Igor Murashkin4491d682013-05-31 16:43:48 -0700323
324 ICameraServiceListener listener = new DummyCameraServiceListener();
325
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800326 try {
327 mUtils.getCameraService().removeListener(listener);
328 fail("Listener was removed before added");
329 } catch (ServiceSpecificException e) {
330 assertEquals("Listener was removed before added",
331 e.errorCode, ICameraService.ERROR_ILLEGAL_ARGUMENT);
332 }
Igor Murashkin4491d682013-05-31 16:43:48 -0700333
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800334 mUtils.getCameraService().addListener(listener);
Igor Murashkin4491d682013-05-31 16:43:48 -0700335
Eino-Ville Talvala5d2d7782015-12-17 16:50:50 -0800336 try {
337 mUtils.getCameraService().addListener(listener);
338 fail("Listener was wrongly added again");
339 } catch (ServiceSpecificException e) {
340 assertEquals("Listener was wrongly added again",
341 e.errorCode, ICameraService.ERROR_ALREADY_EXISTS);
342 }
343
344 mUtils.getCameraService().removeListener(listener);
345
346 try {
347 mUtils.getCameraService().removeListener(listener);
348 fail("Listener was wrongly removed twice");
349 } catch (ServiceSpecificException e) {
350 assertEquals("Listener was wrongly removed twice",
351 e.errorCode, ICameraService.ERROR_ILLEGAL_ARGUMENT);
352 }
Igor Murashkin4491d682013-05-31 16:43:48 -0700353 }
354 }
355}