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 120 boolean supports = mUtils.getCameraService().supportsCameraApi(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(cameraId, API_VERSION_1); 132 assertTrue( 133 "Camera service returned false when queried if it supports camera1 api " + 134 " for camera ID " + cameraId, supports); 135 } 136 } 137 138 static abstract class DummyBase extends Binder implements android.os.IInterface { 139 @Override 140 public IBinder asBinder() { 141 return this; 142 } 143 } 144 145 static class DummyCameraClient extends DummyBase implements ICameraClient { 146 } 147 148 @SmallTest 149 public void testConnect() throws Exception { 150 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) { 151 152 ICameraClient dummyCallbacks = new DummyCameraClient(); 153 154 String clientPackageName = getContext().getPackageName(); 155 156 ICamera cameraUser = mUtils.getCameraService() 157 .connect(dummyCallbacks, cameraId, clientPackageName, 158 ICameraService.USE_CALLING_UID, 159 ICameraService.USE_CALLING_PID); 160 assertNotNull(String.format("Camera %s was null", cameraId), cameraUser); 161 162 Log.v(TAG, String.format("Camera %s connected", cameraId)); 163 164 cameraUser.disconnect(); 165 } 166 } 167 168 @SmallTest 169 public void testConnectLegacy() throws Exception { 170 final int CAMERA_HAL_API_VERSION_1_0 = 0x100; 171 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) { 172 ICamera cameraUser = null; 173 ICameraClient dummyCallbacks = new DummyCameraClient(); 174 175 String clientPackageName = getContext().getPackageName(); 176 177 try { 178 cameraUser = mUtils.getCameraService() 179 .connectLegacy(dummyCallbacks, cameraId, CAMERA_HAL_API_VERSION_1_0, 180 clientPackageName, 181 ICameraService.USE_CALLING_UID); 182 assertNotNull(String.format("Camera %s was null", cameraId), cameraUser); 183 184 Log.v(TAG, String.format("Camera %s connected as HAL1 legacy device", cameraId)); 185 } catch (RuntimeException e) { 186 // Not all camera device support openLegacy. 187 Log.i(TAG, "Unable to open camera as HAL1 legacy camera device " + e); 188 } finally { 189 if (cameraUser != null) { 190 cameraUser.disconnect(); 191 } 192 } 193 } 194 } 195 196 static class DummyCameraDeviceCallbacks extends ICameraDeviceCallbacks.Stub { 197 198 /* 199 * (non-Javadoc) 200 * @see 201 * android.hardware.camera2.ICameraDeviceCallbacks#onCameraError(int, 202 * android.hardware.camera2.CaptureResultExtras) 203 */ 204 @Override 205 public void onDeviceError(int errorCode, CaptureResultExtras resultExtras) 206 throws RemoteException { 207 // TODO Auto-generated method stub 208 209 } 210 211 /* 212 * (non-Javadoc) 213 * @see 214 * android.hardware.camera2.ICameraDeviceCallbacks#onCaptureStarted( 215 * android.hardware.camera2.CaptureResultExtras, long) 216 */ 217 @Override 218 public void onCaptureStarted(CaptureResultExtras resultExtras, long timestamp) 219 throws RemoteException { 220 // TODO Auto-generated method stub 221 222 } 223 224 /* 225 * (non-Javadoc) 226 * @see 227 * android.hardware.camera2.ICameraDeviceCallbacks#onResultReceived( 228 * android.hardware.camera2.impl.CameraMetadataNative, 229 * android.hardware.camera2.CaptureResultExtras) 230 */ 231 @Override 232 public void onResultReceived(CameraMetadataNative result, CaptureResultExtras resultExtras) 233 throws RemoteException { 234 // TODO Auto-generated method stub 235 236 } 237 238 /* 239 * (non-Javadoc) 240 * @see android.hardware.camera2.ICameraDeviceCallbacks#onCameraIdle() 241 */ 242 @Override 243 public void onDeviceIdle() throws RemoteException { 244 // TODO Auto-generated method stub 245 246 } 247 248 /* 249 * (non-Javadoc) 250 * @see android.hardware.camera2.ICameraDeviceCallbacks#onPrepared() 251 */ 252 @Override 253 public void onPrepared(int streamId) throws RemoteException { 254 // TODO Auto-generated method stub 255 256 } 257 258 /* 259 * (non-Javadoc) 260 * @see android.hardware.camera2.ICameraDeviceCallbacks#onRepeatingRequestError() 261 */ 262 @Override 263 public void onRepeatingRequestError(long lastFrameNumber) { 264 // TODO Auto-generated method stub 265 } 266 } 267 268 @SmallTest 269 public void testConnectDevice() throws Exception { 270 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) { 271 272 ICameraDeviceCallbacks dummyCallbacks = new DummyCameraDeviceCallbacks(); 273 274 String clientPackageName = getContext().getPackageName(); 275 276 ICameraDeviceUser cameraUser = 277 mUtils.getCameraService().connectDevice( 278 dummyCallbacks, cameraId, 279 clientPackageName, 280 ICameraService.USE_CALLING_UID); 281 assertNotNull(String.format("Camera %s was null", cameraId), cameraUser); 282 283 Log.v(TAG, String.format("Camera %s connected", cameraId)); 284 285 cameraUser.disconnect(); 286 } 287 } 288 289 static class DummyCameraServiceListener extends ICameraServiceListener.Stub { 290 @Override 291 public void onStatusChanged(int status, int cameraId) 292 throws RemoteException { 293 Log.v(TAG, String.format("Camera %d has status changed to 0x%x", cameraId, status)); 294 } 295 public void onTorchStatusChanged(int status, String cameraId) 296 throws RemoteException { 297 Log.v(TAG, String.format("Camera %s has torch status changed to 0x%x", 298 cameraId, status)); 299 } 300 } 301 302 /** 303 * <pre> 304 * adb shell am instrument \ 305 * -e class 'com.android.mediaframeworktest.integration.CameraBinderTest#testAddRemoveListeners' \ 306 * -w com.android.mediaframeworktest/.MediaFrameworkIntegrationTestRunner 307 * </pre> 308 */ 309 @SmallTest 310 public void testAddRemoveListeners() throws Exception { 311 for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) { 312 313 ICameraServiceListener listener = new DummyCameraServiceListener(); 314 315 try { 316 mUtils.getCameraService().removeListener(listener); 317 fail("Listener was removed before added"); 318 } catch (ServiceSpecificException e) { 319 assertEquals("Listener was removed before added", 320 e.errorCode, ICameraService.ERROR_ILLEGAL_ARGUMENT); 321 } 322 323 mUtils.getCameraService().addListener(listener); 324 325 try { 326 mUtils.getCameraService().addListener(listener); 327 fail("Listener was wrongly added again"); 328 } catch (ServiceSpecificException e) { 329 assertEquals("Listener was wrongly added again", 330 e.errorCode, ICameraService.ERROR_ALREADY_EXISTS); 331 } 332 333 mUtils.getCameraService().removeListener(listener); 334 335 try { 336 mUtils.getCameraService().removeListener(listener); 337 fail("Listener was wrongly removed twice"); 338 } catch (ServiceSpecificException e) { 339 assertEquals("Listener was wrongly removed twice", 340 e.errorCode, ICameraService.ERROR_ILLEGAL_ARGUMENT); 341 } 342 } 343 } 344} 345