1package org.robolectric.shadows; 2 3import static java.nio.charset.StandardCharsets.UTF_8; 4import static org.assertj.core.api.Assertions.assertThat; 5import static org.assertj.core.api.Fail.fail; 6 7import android.graphics.Canvas; 8import android.graphics.ImageFormat; 9import android.graphics.Rect; 10import android.hardware.Camera; 11import android.view.Surface; 12import android.view.SurfaceHolder; 13import org.junit.After; 14import org.junit.Before; 15import org.junit.Test; 16import org.junit.runner.RunWith; 17import org.robolectric.RobolectricTestRunner; 18import org.robolectric.Shadows; 19 20@RunWith(RobolectricTestRunner.class) 21public class ShadowCameraTest { 22 23 private Camera camera; 24 private ShadowCamera shadowCamera; 25 26 @Before 27 public void setUp() throws Exception { 28 camera = Camera.open(); 29 shadowCamera = Shadows.shadowOf(camera); 30 } 31 32 @After 33 public void tearDown() throws Exception { 34 ShadowCamera.clearCameraInfo(); 35 } 36 37 @Test 38 public void testOpen() throws Exception { 39 assertThat(camera).isNotNull(); 40 assertThat(ShadowCamera.getLastOpenedCameraId()).isEqualTo(0); 41 } 42 43 @Test 44 public void testOpenWithId() throws Exception { 45 camera = Camera.open(12); 46 assertThat(camera).isNotNull(); 47 assertThat(ShadowCamera.getLastOpenedCameraId()).isEqualTo(12); 48 } 49 50 @Test 51 public void testUnlock() throws Exception { 52 assertThat(shadowCamera.isLocked()).isTrue(); 53 camera.unlock(); 54 assertThat(shadowCamera.isLocked()).isFalse(); 55 } 56 57 @Test 58 public void testReconnect() throws Exception { 59 camera.unlock(); 60 assertThat(shadowCamera.isLocked()).isFalse(); 61 camera.reconnect(); 62 assertThat(shadowCamera.isLocked()).isTrue(); 63 } 64 65 @Test 66 public void testGetParameters() throws Exception { 67 Camera.Parameters parameters = camera.getParameters(); 68 assertThat(parameters).isNotNull(); 69 assertThat(parameters.getSupportedPreviewFormats()).isNotNull(); 70 assertThat(parameters.getSupportedPreviewFormats().size()).isNotEqualTo(0); 71 } 72 73 @Test 74 public void testSetParameters() throws Exception { 75 Camera.Parameters parameters = camera.getParameters(); 76 assertThat(parameters.getPreviewFormat()).isEqualTo(ImageFormat.NV21); 77 parameters.setPreviewFormat(ImageFormat.JPEG); 78 camera.setParameters(parameters); 79 assertThat(camera.getParameters().getPreviewFormat()).isEqualTo(ImageFormat.JPEG); 80 } 81 82 @Test 83 public void testSetPreviewDisplay() throws Exception { 84 SurfaceHolder previewSurfaceHolder = new TestSurfaceHolder(); 85 camera.setPreviewDisplay(previewSurfaceHolder); 86 assertThat(shadowCamera.getPreviewDisplay()).isSameAs(previewSurfaceHolder); 87 } 88 89 @Test 90 public void testStartPreview() throws Exception { 91 assertThat(shadowCamera.isPreviewing()).isFalse(); 92 camera.startPreview(); 93 assertThat(shadowCamera.isPreviewing()).isTrue(); 94 } 95 96 @Test 97 public void testStopPreview() throws Exception { 98 camera.startPreview(); 99 assertThat(shadowCamera.isPreviewing()).isTrue(); 100 camera.stopPreview(); 101 assertThat(shadowCamera.isPreviewing()).isFalse(); 102 } 103 104 @Test 105 public void testRelease() throws Exception { 106 assertThat(shadowCamera.isReleased()).isFalse(); 107 camera.release(); 108 assertThat(shadowCamera.isReleased()).isTrue(); 109 } 110 111 @Test 112 public void testSetPreviewCallbacks() throws Exception { 113 TestPreviewCallback callback = new TestPreviewCallback(); 114 assertThat(callback.camera).isNull(); 115 assertThat(callback.data).isNull(); 116 117 camera.setPreviewCallback(callback); 118 shadowCamera.invokePreviewCallback("foobar".getBytes(UTF_8)); 119 120 assertThat(callback.camera).isSameAs(camera); 121 assertThat(callback.data).isEqualTo("foobar".getBytes(UTF_8)); 122 } 123 124 @Test 125 public void testSetOneShotPreviewCallbacks() throws Exception { 126 TestPreviewCallback callback = new TestPreviewCallback(); 127 assertThat(callback.camera).isNull(); 128 assertThat(callback.data).isNull(); 129 130 camera.setOneShotPreviewCallback(callback); 131 shadowCamera.invokePreviewCallback("foobar".getBytes(UTF_8)); 132 133 assertThat(callback.camera).isSameAs(camera); 134 assertThat(callback.data).isEqualTo("foobar".getBytes(UTF_8)); 135 } 136 137 @Test 138 public void testPreviewCallbacksWithBuffers() throws Exception { 139 TestPreviewCallback callback = new TestPreviewCallback(); 140 assertThat(callback.camera).isNull(); 141 assertThat(callback.data).isNull(); 142 143 camera.setPreviewCallbackWithBuffer(callback); 144 shadowCamera.invokePreviewCallback("foobar".getBytes(UTF_8)); 145 146 assertThat(callback.camera).isSameAs(camera); 147 assertThat(callback.data).isEqualTo("foobar".getBytes(UTF_8)); 148 } 149 150 @Test 151 public void testClearPreviewCallback() throws Exception { 152 TestPreviewCallback callback = new TestPreviewCallback(); 153 assertThat(callback.camera).isNull(); 154 assertThat(callback.data).isNull(); 155 156 camera.setPreviewCallback(callback); 157 camera.setPreviewCallback(null); 158 159 shadowCamera.invokePreviewCallback("foobar".getBytes(UTF_8)); 160 assertThat(callback.camera).isNull(); 161 assertThat(callback.data).isNull(); 162 163 camera.setOneShotPreviewCallback(callback); 164 camera.setOneShotPreviewCallback(null); 165 166 shadowCamera.invokePreviewCallback("foobar".getBytes(UTF_8)); 167 assertThat(callback.camera).isNull(); 168 assertThat(callback.data).isNull(); 169 170 camera.setPreviewCallbackWithBuffer(callback); 171 camera.setPreviewCallbackWithBuffer(null); 172 173 shadowCamera.invokePreviewCallback("foobar".getBytes(UTF_8)); 174 assertThat(callback.camera).isNull(); 175 assertThat(callback.data).isNull(); 176 } 177 178 @Test 179 public void testAddCallbackBuffer() { 180 byte[] buf1 = new byte[0]; 181 byte[] buf2 = new byte[1]; 182 camera.addCallbackBuffer(buf1); 183 assertThat(shadowCamera.getAddedCallbackBuffers()).containsExactly(buf1); 184 camera.addCallbackBuffer(buf2); 185 assertThat(shadowCamera.getAddedCallbackBuffers()).containsExactly(buf1, buf2); 186 } 187 188 @Test 189 public void testDisplayOrientation() { 190 camera.setDisplayOrientation(180); 191 assertThat(shadowCamera.getDisplayOrientation()).isEqualTo(180); 192 } 193 194 @Test 195 public void testSetDisplayOrientationUpdatesCameraInfos() { 196 addBackCamera(); 197 addFrontCamera(); 198 199 camera = Camera.open(1); 200 camera.setDisplayOrientation(180); 201 202 Camera.CameraInfo cameraQuery = new Camera.CameraInfo(); 203 Camera.getCameraInfo(ShadowCamera.getLastOpenedCameraId(), cameraQuery); 204 assertThat(cameraQuery.orientation).isEqualTo(180); 205 } 206 207 @Test 208 public void testAutoFocus() { 209 assertThat(shadowCamera.hasRequestedAutoFocus()).isFalse(); 210 TestAutoFocusCallback callback = new TestAutoFocusCallback(); 211 212 camera.autoFocus(callback); 213 214 assertThat(shadowCamera.hasRequestedAutoFocus()).isTrue(); 215 shadowCamera.invokeAutoFocusCallback(true, camera); 216 assertThat(callback.success).isEqualTo(true); 217 assertThat(callback.camera).isEqualTo(camera); 218 219 assertThat(shadowCamera.hasRequestedAutoFocus()).isFalse(); 220 try { 221 shadowCamera.invokeAutoFocusCallback(true, camera); 222 fail("expected an IllegalStateException"); 223 } catch (IllegalStateException e) { 224 // expected 225 } 226 } 227 228 @Test 229 public void testInvokeAutoFocusCallbackMissing() { 230 try { 231 shadowCamera.invokeAutoFocusCallback(true, camera); 232 fail("expected an IllegalStateException"); 233 } catch (IllegalStateException e) { 234 // expected 235 } 236 } 237 238 @Test 239 public void testCancelAutoFocus() { 240 assertThat(shadowCamera.hasRequestedAutoFocus()).isFalse(); 241 camera.autoFocus(null); 242 assertThat(shadowCamera.hasRequestedAutoFocus()).isTrue(); 243 camera.cancelAutoFocus(); 244 assertThat(shadowCamera.hasRequestedAutoFocus()).isFalse(); 245 } 246 247 @Test 248 public void testCameraInfoNoCameras() throws Exception { 249 assertThat(Camera.getNumberOfCameras()).isEqualTo(0); 250 } 251 252 @Test 253 public void testCameraInfoBackOnly() throws Exception { 254 Camera.CameraInfo cameraQuery = new Camera.CameraInfo(); 255 256 addBackCamera(); 257 Camera.getCameraInfo(0, cameraQuery); 258 259 assertThat(Camera.getNumberOfCameras()).isEqualTo(1); 260 assertThat(cameraQuery.facing).isEqualTo(Camera.CameraInfo.CAMERA_FACING_BACK); 261 assertThat(cameraQuery.orientation).isEqualTo(0); 262 } 263 264 @Test 265 public void testCameraInfoBackAndFront() throws Exception { 266 Camera.CameraInfo cameraQuery = new Camera.CameraInfo(); 267 addBackCamera(); 268 addFrontCamera(); 269 270 assertThat(Camera.getNumberOfCameras()).isEqualTo(2); 271 Camera.getCameraInfo(0, cameraQuery); 272 assertThat(cameraQuery.facing).isEqualTo(Camera.CameraInfo.CAMERA_FACING_BACK); 273 assertThat(cameraQuery.orientation).isEqualTo(0); 274 Camera.getCameraInfo(1, cameraQuery); 275 assertThat(cameraQuery.facing).isEqualTo(Camera.CameraInfo.CAMERA_FACING_FRONT); 276 assertThat(cameraQuery.orientation).isEqualTo(90); 277 } 278 279 private void addBackCamera() { 280 Camera.CameraInfo backCamera = new Camera.CameraInfo(); 281 backCamera.facing = Camera.CameraInfo.CAMERA_FACING_BACK; 282 backCamera.orientation = 0; 283 ShadowCamera.addCameraInfo(0, backCamera); 284 } 285 286 private void addFrontCamera() { 287 Camera.CameraInfo frontCamera = new Camera.CameraInfo(); 288 frontCamera.facing = Camera.CameraInfo.CAMERA_FACING_FRONT; 289 frontCamera.orientation = 90; 290 ShadowCamera.addCameraInfo(1, frontCamera); 291 } 292 293 private static class TestPreviewCallback implements Camera.PreviewCallback { 294 public Camera camera = null; 295 public byte[] data = null; 296 297 @Override 298 public void onPreviewFrame(byte[] data, Camera camera) { 299 this.data = data; 300 this.camera = camera; 301 } 302 } 303 304 private static class TestAutoFocusCallback implements Camera.AutoFocusCallback { 305 public boolean success; 306 public Camera camera; 307 308 @Override 309 public void onAutoFocus(boolean success, Camera camera) { 310 this.success = success; 311 this.camera = camera; 312 } 313 } 314 315 private static class TestSurfaceHolder implements SurfaceHolder { 316 317 @Override 318 public void addCallback(Callback callback) { 319 } 320 321 @Override 322 public Surface getSurface() { 323 return null; 324 } 325 326 @Override 327 public Rect getSurfaceFrame() { 328 return null; 329 } 330 331 @Override 332 public boolean isCreating() { 333 return false; 334 } 335 336 @Override 337 public Canvas lockCanvas() { 338 return null; 339 } 340 341 @Override 342 public Canvas lockCanvas(Rect dirty) { 343 return null; 344 } 345 346 @Override 347 public void removeCallback(Callback callback) { 348 } 349 350 @Override 351 public void setFixedSize(int width, int height) { 352 } 353 354 @Override 355 public void setFormat(int format) { 356 } 357 358 @Override 359 public void setKeepScreenOn(boolean screenOn) { 360 } 361 362 @Override 363 public void setSizeFromLayout() { 364 } 365 366 @Override 367 public void setType(int type) { 368 } 369 370 @Override 371 public void unlockCanvasAndPost(Canvas canvas) { 372 } 373 } 374} 375