1/* 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 19import android.hardware.CameraInfo; 20import android.hardware.ICamera; 21import android.hardware.ICameraClient; 22import android.hardware.ICameraServiceListener; 23import android.hardware.IProCameraCallbacks; 24import android.hardware.IProCameraUser; 25import android.hardware.camera2.ICameraDeviceCallbacks; 26import android.hardware.camera2.ICameraDeviceUser; 27import android.hardware.camera2.impl.CameraMetadataNative; 28import android.hardware.camera2.impl.CaptureResultExtras; 29import android.hardware.camera2.utils.BinderHolder; 30import android.hardware.camera2.utils.CameraBinderDecorator; 31import android.os.Binder; 32import android.os.IBinder; 33import android.os.RemoteException; 34import android.test.AndroidTestCase; 35import android.test.suitebuilder.annotation.SmallTest; 36import android.util.Log; 37 38/** 39 * <p> 40 * Junit / Instrumentation test case for the camera2 api 41 * </p> 42 * <p> 43 * To run only tests in this class: 44 * </p> 45 * 46 * <pre> 47 * adb shell am instrument \ 48 * -e class com.android.mediaframeworktest.integration.CameraBinderTest \ 49 * -w com.android.mediaframeworktest/.MediaFrameworkIntegrationTestRunner 50 * </pre> 51 */ 52public class CameraBinderTest extends AndroidTestCase { 53 private static final int MAX_PARAMETERS_LENGTH = 100; 54 55 static String TAG = "CameraBinderTest"; 56 57 // From ICameraService.h 58 private static final int API_VERSION_1 = 1; 59 private static final int API_VERSION_2 = 2; 60 61 protected CameraBinderTestUtils mUtils; 62 63 public CameraBinderTest() { 64 } 65 66 @Override 67 protected void setUp() throws Exception { 68 super.setUp(); 69 70 mUtils = new CameraBinderTestUtils(getContext()); 71 } 72 73 @SmallTest 74 public void testNumberOfCameras() throws Exception { 75 76 int numCameras = mUtils.getCameraService().getNumberOfCameras(); 77 assertTrue("At least this many cameras: " + mUtils.getGuessedNumCameras(), 78 numCameras >= mUtils.getGuessedNumCameras()); 79 Log.v(TAG, "Number of cameras " + numCameras); 80 } 81 82 @SmallTest 83 public void testCameraInfo() throws Exception { 84 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) { 85 86 CameraInfo info = new CameraInfo(); 87 info.info.facing = -1; 88 info.info.orientation = -1; 89 90 assertTrue( 91 "Camera service returned info for camera " + cameraId, 92 mUtils.getCameraService().getCameraInfo(cameraId, info) == 93 CameraBinderTestUtils.NO_ERROR); 94 assertTrue("Facing was not set for camera " + cameraId, info.info.facing != -1); 95 assertTrue("Orientation was not set for camera " + cameraId, 96 info.info.orientation != -1); 97 98 Log.v(TAG, "Camera " + cameraId + " info: facing " + info.info.facing 99 + ", orientation " + info.info.orientation); 100 } 101 } 102 103 @SmallTest 104 public void testGetLegacyParameters() throws Exception { 105 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) { 106 107 String[] parameters = new String[1]; 108 assertEquals("Camera service returned parameters for camera " + cameraId, 109 CameraBinderTestUtils.NO_ERROR, 110 mUtils.getCameraService().getLegacyParameters(cameraId, /*out*/parameters)); 111 assertNotNull(parameters[0]); 112 assertTrue("Parameters should have at least one character in it", 113 parameters[0].length() > 0); 114 115 int end = parameters[0].length(); 116 if (end > MAX_PARAMETERS_LENGTH) { 117 end = MAX_PARAMETERS_LENGTH; 118 } 119 120 Log.v(TAG, "Camera " + cameraId + " parameters: " + parameters[0].substring(0, end)); 121 } 122 } 123 124 /** The camera2 api is only supported on HAL3.2+ devices */ 125 @SmallTest 126 public void testSupportsCamera2Api() throws Exception { 127 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) { 128 129 int res = mUtils.getCameraService().supportsCameraApi(cameraId, API_VERSION_2); 130 131 if (res != CameraBinderTestUtils.NO_ERROR && res != CameraBinderTestUtils.EOPNOTSUPP) { 132 fail("Camera service returned bad value when queried if it supports camera2 api: " 133 + res + " for camera ID " + cameraId); 134 } 135 136 boolean supports = res == CameraBinderTestUtils.NO_ERROR; 137 Log.v(TAG, "Camera " + cameraId + " supports api2: " + supports); 138 } 139 } 140 141 /** The camera1 api is supported on *all* devices regardless of HAL version */ 142 @SmallTest 143 public void testSupportsCamera1Api() throws Exception { 144 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) { 145 146 int res = mUtils.getCameraService().supportsCameraApi(cameraId, API_VERSION_1); 147 assertEquals( 148 "Camera service returned bad value when queried if it supports camera1 api: " 149 + res + " for camera ID " + cameraId, CameraBinderTestUtils.NO_ERROR, res); 150 } 151 } 152 153 static abstract class DummyBase extends Binder implements android.os.IInterface { 154 @Override 155 public IBinder asBinder() { 156 return this; 157 } 158 } 159 160 static class DummyCameraClient extends DummyBase implements ICameraClient { 161 } 162 163 @SmallTest 164 public void testConnect() throws Exception { 165 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) { 166 167 ICameraClient dummyCallbacks = new DummyCameraClient(); 168 169 String clientPackageName = getContext().getPackageName(); 170 171 BinderHolder holder = new BinderHolder(); 172 CameraBinderDecorator.newInstance(mUtils.getCameraService()) 173 .connect(dummyCallbacks, cameraId, clientPackageName, 174 CameraBinderTestUtils.USE_CALLING_UID, holder); 175 ICamera cameraUser = ICamera.Stub.asInterface(holder.getBinder()); 176 assertNotNull(String.format("Camera %s was null", cameraId), cameraUser); 177 178 Log.v(TAG, String.format("Camera %s connected", cameraId)); 179 180 cameraUser.disconnect(); 181 } 182 } 183 184 static class DummyProCameraCallbacks extends DummyBase implements IProCameraCallbacks { 185 } 186 187 @SmallTest 188 public void testConnectPro() throws Exception { 189 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) { 190 191 IProCameraCallbacks dummyCallbacks = new DummyProCameraCallbacks(); 192 193 String clientPackageName = getContext().getPackageName(); 194 195 BinderHolder holder = new BinderHolder(); 196 CameraBinderDecorator.newInstance(mUtils.getCameraService()) 197 .connectPro(dummyCallbacks, cameraId, 198 clientPackageName, CameraBinderTestUtils.USE_CALLING_UID, holder); 199 IProCameraUser cameraUser = IProCameraUser.Stub.asInterface(holder.getBinder()); 200 assertNotNull(String.format("Camera %s was null", cameraId), cameraUser); 201 202 Log.v(TAG, String.format("Camera %s connected", cameraId)); 203 204 cameraUser.disconnect(); 205 } 206 } 207 208 @SmallTest 209 public void testConnectLegacy() throws Exception { 210 final int CAMERA_HAL_API_VERSION_1_0 = 0x100; 211 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) { 212 ICamera cameraUser = null; 213 ICameraClient dummyCallbacks = new DummyCameraClient(); 214 215 String clientPackageName = getContext().getPackageName(); 216 217 BinderHolder holder = new BinderHolder(); 218 219 try { 220 CameraBinderDecorator.newInstance(mUtils.getCameraService()) 221 .connectLegacy(dummyCallbacks, cameraId, CAMERA_HAL_API_VERSION_1_0, 222 clientPackageName, 223 CameraBinderTestUtils.USE_CALLING_UID, holder); 224 cameraUser = ICamera.Stub.asInterface(holder.getBinder()); 225 assertNotNull(String.format("Camera %s was null", cameraId), cameraUser); 226 227 Log.v(TAG, String.format("Camera %s connected as HAL1 legacy device", cameraId)); 228 } catch (RuntimeException e) { 229 // Not all camera device support openLegacy. 230 Log.i(TAG, "Unable to open camera as HAL1 legacy camera device " + e); 231 } finally { 232 if (cameraUser != null) { 233 cameraUser.disconnect(); 234 } 235 } 236 } 237 } 238 239 static class DummyCameraDeviceCallbacks extends ICameraDeviceCallbacks.Stub { 240 241 /* 242 * (non-Javadoc) 243 * @see 244 * android.hardware.camera2.ICameraDeviceCallbacks#onCameraError(int, 245 * android.hardware.camera2.CaptureResultExtras) 246 */ 247 @Override 248 public void onDeviceError(int errorCode, CaptureResultExtras resultExtras) 249 throws RemoteException { 250 // TODO Auto-generated method stub 251 252 } 253 254 /* 255 * (non-Javadoc) 256 * @see 257 * android.hardware.camera2.ICameraDeviceCallbacks#onCaptureStarted( 258 * android.hardware.camera2.CaptureResultExtras, long) 259 */ 260 @Override 261 public void onCaptureStarted(CaptureResultExtras resultExtras, long timestamp) 262 throws RemoteException { 263 // TODO Auto-generated method stub 264 265 } 266 267 /* 268 * (non-Javadoc) 269 * @see 270 * android.hardware.camera2.ICameraDeviceCallbacks#onResultReceived( 271 * android.hardware.camera2.impl.CameraMetadataNative, 272 * android.hardware.camera2.CaptureResultExtras) 273 */ 274 @Override 275 public void onResultReceived(CameraMetadataNative result, CaptureResultExtras resultExtras) 276 throws RemoteException { 277 // TODO Auto-generated method stub 278 279 } 280 281 /* 282 * (non-Javadoc) 283 * @see android.hardware.camera2.ICameraDeviceCallbacks#onCameraIdle() 284 */ 285 @Override 286 public void onDeviceIdle() throws RemoteException { 287 // TODO Auto-generated method stub 288 289 } 290 } 291 292 @SmallTest 293 public void testConnectDevice() throws Exception { 294 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) { 295 296 ICameraDeviceCallbacks dummyCallbacks = new DummyCameraDeviceCallbacks(); 297 298 String clientPackageName = getContext().getPackageName(); 299 300 BinderHolder holder = new BinderHolder(); 301 CameraBinderDecorator.newInstance(mUtils.getCameraService()) 302 .connectDevice(dummyCallbacks, cameraId, 303 clientPackageName, CameraBinderTestUtils.USE_CALLING_UID, holder); 304 ICameraDeviceUser cameraUser = ICameraDeviceUser.Stub.asInterface(holder.getBinder()); 305 assertNotNull(String.format("Camera %s was null", cameraId), cameraUser); 306 307 Log.v(TAG, String.format("Camera %s connected", cameraId)); 308 309 cameraUser.disconnect(); 310 } 311 } 312 313 static class DummyCameraServiceListener extends ICameraServiceListener.Stub { 314 @Override 315 public void onStatusChanged(int status, int cameraId) 316 throws RemoteException { 317 Log.v(TAG, String.format("Camera %d has status changed to 0x%x", cameraId, status)); 318 } 319 } 320 321 /** 322 * <pre> 323 * adb shell am instrument \ 324 * -e class 'com.android.mediaframeworktest.integration.CameraBinderTest#testAddRemoveListeners' \ 325 * -w com.android.mediaframeworktest/.MediaFrameworkIntegrationTestRunner 326 * </pre> 327 */ 328 @SmallTest 329 public void testAddRemoveListeners() throws Exception { 330 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) { 331 332 ICameraServiceListener listener = new DummyCameraServiceListener(); 333 334 assertTrue( 335 "Listener was removed before added", 336 mUtils.getCameraService().removeListener(listener) == 337 CameraBinderTestUtils.BAD_VALUE); 338 339 assertTrue("Listener was not added", 340 mUtils.getCameraService().addListener(listener) == 341 CameraBinderTestUtils.NO_ERROR); 342 assertTrue( 343 "Listener was wrongly added again", 344 mUtils.getCameraService().addListener(listener) == 345 CameraBinderTestUtils.ALREADY_EXISTS); 346 347 assertTrue( 348 "Listener was not removed", 349 mUtils.getCameraService().removeListener(listener) == 350 CameraBinderTestUtils.NO_ERROR); 351 assertTrue( 352 "Listener was wrongly removed again", 353 mUtils.getCameraService().removeListener(listener) == 354 CameraBinderTestUtils.BAD_VALUE); 355 } 356 } 357} 358