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.ICameraService; 23import android.hardware.ICameraServiceListener; 24import android.hardware.camera2.ICameraDeviceCallbacks; 25import android.hardware.camera2.ICameraDeviceUser; 26import android.hardware.camera2.impl.CameraMetadataNative; 27import android.hardware.camera2.impl.CaptureResultExtras; 28import android.os.Binder; 29import android.os.IBinder; 30import android.os.RemoteException; 31import android.os.ServiceSpecificException; 32import android.test.AndroidTestCase; 33import android.test.suitebuilder.annotation.SmallTest; 34import android.util.Log; 35 36/** 37 * <p> 38 * Junit / Instrumentation test case for the camera2 api 39 * </p> 40 * <p> 41 * To run only tests in this class: 42 * </p> 43 * 44 * <pre> 45 * adb shell am instrument \ 46 * -e class com.android.mediaframeworktest.integration.CameraBinderTest \ 47 * -w com.android.mediaframeworktest/.MediaFrameworkIntegrationTestRunner 48 * </pre> 49 */ 50public class CameraBinderTest extends AndroidTestCase { 51 private static final int MAX_PARAMETERS_LENGTH = 100; 52 53 static String TAG = "CameraBinderTest"; 54 55 // From ICameraService.h 56 private static final int API_VERSION_1 = 1; 57 private static final int API_VERSION_2 = 2; 58 59 private static final int CAMERA_TYPE_BACKWARD_COMPATIBLE = 0; 60 private static final int CAMERA_TYPE_ALL = 1; 61 62 protected CameraBinderTestUtils mUtils; 63 64 public CameraBinderTest() { 65 } 66 67 @Override 68 protected void setUp() throws Exception { 69 super.setUp(); 70 71 mUtils = new CameraBinderTestUtils(getContext()); 72 } 73 74 @SmallTest 75 public void testNumberOfCameras() throws Exception { 76 77 int numCameras = mUtils.getCameraService().getNumberOfCameras(CAMERA_TYPE_ALL); 78 assertTrue("At least this many cameras: " + mUtils.getGuessedNumCameras(), 79 numCameras >= mUtils.getGuessedNumCameras()); 80 Log.v(TAG, "Number of cameras " + numCameras); 81 } 82 83 @SmallTest 84 public void testCameraInfo() throws Exception { 85 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) { 86 87 CameraInfo info = mUtils.getCameraService().getCameraInfo(cameraId); 88 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 97 @SmallTest 98 public void testGetLegacyParameters() throws Exception { 99 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) { 100 101 String parameters = mUtils.getCameraService().getLegacyParameters(cameraId); 102 assertNotNull(parameters); 103 assertTrue("Parameters should have at least one character in it", 104 parameters.length() > 0); 105 106 int end = parameters.length(); 107 if (end > MAX_PARAMETERS_LENGTH) { 108 end = MAX_PARAMETERS_LENGTH; 109 } 110 111 Log.v(TAG, "Camera " + cameraId + " parameters: " + parameters.substring(0, end)); 112 } 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) { 119 boolean supports = mUtils.getCameraService().supportsCameraApi( 120 String.valueOf(cameraId), API_VERSION_2); 121 122 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 131 boolean supports = mUtils.getCameraService().supportsCameraApi( 132 String.valueOf(cameraId), API_VERSION_1); 133 assertTrue( 134 "Camera service returned false when queried if it supports camera1 api " + 135 " for camera ID " + cameraId, supports); 136 } 137 } 138 139 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 { 151 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) { 152 153 ICameraClient dummyCallbacks = new DummyCameraClient(); 154 155 String clientPackageName = getContext().getPackageName(); 156 157 ICamera cameraUser = mUtils.getCameraService() 158 .connect(dummyCallbacks, cameraId, clientPackageName, 159 ICameraService.USE_CALLING_UID, 160 ICameraService.USE_CALLING_PID); 161 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 169 @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 178 try { 179 cameraUser = mUtils.getCameraService() 180 .connectLegacy(dummyCallbacks, cameraId, CAMERA_HAL_API_VERSION_1_0, 181 clientPackageName, 182 ICameraService.USE_CALLING_UID); 183 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 197 static class DummyCameraDeviceCallbacks extends ICameraDeviceCallbacks.Stub { 198 199 /* 200 * (non-Javadoc) 201 * @see 202 * android.hardware.camera2.ICameraDeviceCallbacks#onCameraError(int, 203 * android.hardware.camera2.CaptureResultExtras) 204 */ 205 @Override 206 public void onDeviceError(int errorCode, CaptureResultExtras resultExtras) 207 throws RemoteException { 208 // 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 */ 218 @Override 219 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 */ 232 @Override 233 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 */ 243 @Override 244 public void onDeviceIdle() throws RemoteException { 245 // TODO Auto-generated method stub 246 247 } 248 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 } 258 259 /* 260 * (non-Javadoc) 261 * @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) 271 * @see android.hardware.camera2.ICameraDeviceCallbacks#onRepeatingRequestError() 272 */ 273 @Override 274 public void onRepeatingRequestError(long lastFrameNumber) { 275 // TODO Auto-generated method stub 276 } 277 } 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 287 ICameraDeviceUser cameraUser = 288 mUtils.getCameraService().connectDevice( 289 dummyCallbacks, String.valueOf(cameraId), 290 clientPackageName, 291 ICameraService.USE_CALLING_UID); 292 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 300 static class DummyCameraServiceListener extends ICameraServiceListener.Stub { 301 @Override 302 public void onStatusChanged(int status, String cameraId) 303 throws RemoteException { 304 Log.v(TAG, String.format("Camera %s has status changed to 0x%x", cameraId, status)); 305 } 306 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 } 311 } 312 313 /** 314 * <pre> 315 * adb shell am instrument \ 316 * -e class 'com.android.mediaframeworktest.integration.CameraBinderTest#testAddRemoveListeners' \ 317 * -w com.android.mediaframeworktest/.MediaFrameworkIntegrationTestRunner 318 * </pre> 319 */ 320 @SmallTest 321 public void testAddRemoveListeners() throws Exception { 322 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) { 323 324 ICameraServiceListener listener = new DummyCameraServiceListener(); 325 326 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 } 333 334 mUtils.getCameraService().addListener(listener); 335 336 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 } 353 } 354 } 355} 356