• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.robolectric.shadows;
2 
3 import static com.google.common.truth.Truth.assertThat;
4 import static java.nio.charset.StandardCharsets.UTF_8;
5 import static org.junit.Assert.fail;
6 
7 import android.graphics.Canvas;
8 import android.graphics.ImageFormat;
9 import android.graphics.Rect;
10 import android.hardware.Camera;
11 import android.view.Surface;
12 import android.view.SurfaceHolder;
13 import androidx.test.ext.junit.runners.AndroidJUnit4;
14 import org.junit.After;
15 import org.junit.Before;
16 import org.junit.Test;
17 import org.junit.runner.RunWith;
18 import org.robolectric.Shadows;
19 
20 @RunWith(AndroidJUnit4.class)
21 public class ShadowCameraTest {
22 
23   private Camera camera;
24   private ShadowCamera shadowCamera;
25 
26   @Before
setUp()27   public void setUp() throws Exception {
28     camera = Camera.open();
29     shadowCamera = Shadows.shadowOf(camera);
30   }
31 
32   @After
tearDown()33   public void tearDown() throws Exception {
34     ShadowCamera.clearCameraInfo();
35   }
36 
37   @Test
testOpen()38   public void testOpen() throws Exception {
39     assertThat(camera).isNotNull();
40     assertThat(ShadowCamera.getLastOpenedCameraId()).isEqualTo(0);
41   }
42 
43   @Test
testOpenWithId()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
testUnlock()51   public void testUnlock() throws Exception {
52     assertThat(shadowCamera.isLocked()).isTrue();
53     camera.unlock();
54     assertThat(shadowCamera.isLocked()).isFalse();
55   }
56 
57   @Test
testReconnect()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
testGetParameters()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
testSetParameters()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
testSetPreviewDisplay()83   public void testSetPreviewDisplay() throws Exception {
84     SurfaceHolder previewSurfaceHolder = new TestSurfaceHolder();
85     camera.setPreviewDisplay(previewSurfaceHolder);
86     assertThat(shadowCamera.getPreviewDisplay()).isSameInstanceAs(previewSurfaceHolder);
87   }
88 
89   @Test
testStartPreview()90   public void testStartPreview() throws Exception {
91     assertThat(shadowCamera.isPreviewing()).isFalse();
92     camera.startPreview();
93     assertThat(shadowCamera.isPreviewing()).isTrue();
94   }
95 
96   @Test
testStopPreview()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
testRelease()105   public void testRelease() throws Exception {
106     assertThat(shadowCamera.isReleased()).isFalse();
107     camera.release();
108     assertThat(shadowCamera.isReleased()).isTrue();
109   }
110 
111   @Test
testSetPreviewCallbacks()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).isSameInstanceAs(camera);
121     assertThat(callback.data).isEqualTo("foobar".getBytes(UTF_8));
122   }
123 
124   @Test
testSetOneShotPreviewCallbacks()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).isSameInstanceAs(camera);
134     assertThat(callback.data).isEqualTo("foobar".getBytes(UTF_8));
135   }
136 
137   @Test
testPreviewCallbacksWithBuffers()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).isSameInstanceAs(camera);
147     assertThat(callback.data).isEqualTo("foobar".getBytes(UTF_8));
148   }
149 
150   @Test
testClearPreviewCallback()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
testAddCallbackBuffer()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
testDisplayOrientation()189   public void testDisplayOrientation() {
190     camera.setDisplayOrientation(180);
191     assertThat(shadowCamera.getDisplayOrientation()).isEqualTo(180);
192   }
193 
194   @Test
testSetDisplayOrientationUpdatesCameraInfos()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
testAutoFocus()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
testInvokeAutoFocusCallbackMissing()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
testCancelAutoFocus()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
testCameraInfoNoCameras()248   public void testCameraInfoNoCameras() throws Exception {
249     assertThat(Camera.getNumberOfCameras()).isEqualTo(0);
250   }
251 
252   @Test
testCameraInfoBackOnly()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
testCameraInfoBackAndFront()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   @Test
testTakePicture()280   public void testTakePicture() throws Exception {
281     camera.takePicture(null, null, null);
282 
283     TestShutterCallback shutterCallback = new TestShutterCallback();
284     TestPictureCallback rawCallback = new TestPictureCallback();
285     TestPictureCallback jpegCallback = new TestPictureCallback();
286     camera.takePicture(shutterCallback, rawCallback, jpegCallback);
287 
288     assertThat(shutterCallback.wasCalled).isTrue();
289     assertThat(rawCallback.wasCalled).isTrue();
290     assertThat(jpegCallback.wasCalled).isTrue();
291   }
292 
addBackCamera()293   private void addBackCamera() {
294     Camera.CameraInfo backCamera = new Camera.CameraInfo();
295     backCamera.facing = Camera.CameraInfo.CAMERA_FACING_BACK;
296     backCamera.orientation = 0;
297     ShadowCamera.addCameraInfo(0, backCamera);
298   }
299 
addFrontCamera()300   private void addFrontCamera() {
301     Camera.CameraInfo frontCamera = new Camera.CameraInfo();
302     frontCamera.facing = Camera.CameraInfo.CAMERA_FACING_FRONT;
303     frontCamera.orientation = 90;
304     ShadowCamera.addCameraInfo(1, frontCamera);
305   }
306 
307   private static class TestPreviewCallback implements Camera.PreviewCallback {
308     public Camera camera = null;
309     public byte[] data = null;
310 
311     @Override
onPreviewFrame(byte[] data, Camera camera)312     public void onPreviewFrame(byte[] data, Camera camera) {
313       this.data = data;
314       this.camera = camera;
315     }
316   }
317 
318   private static class TestAutoFocusCallback implements Camera.AutoFocusCallback {
319     public boolean success;
320     public Camera camera;
321 
322     @Override
onAutoFocus(boolean success, Camera camera)323     public void onAutoFocus(boolean success, Camera camera) {
324       this.success = success;
325       this.camera = camera;
326     }
327   }
328 
329   private static class TestShutterCallback implements Camera.ShutterCallback {
330     public boolean wasCalled;
331 
332     @Override
onShutter()333     public void onShutter() {
334       wasCalled = true;
335     }
336   }
337 
338   private static class TestPictureCallback implements Camera.PictureCallback {
339     public boolean wasCalled;
340 
341     @Override
onPictureTaken(byte[] data, Camera camera)342     public void onPictureTaken(byte[] data, Camera camera) {
343       wasCalled = true;
344     }
345   }
346 
347   private static class TestSurfaceHolder implements SurfaceHolder {
348 
349     @Override
addCallback(Callback callback)350     public void addCallback(Callback callback) {
351     }
352 
353     @Override
getSurface()354     public Surface getSurface() {
355       return null;
356     }
357 
358     @Override
getSurfaceFrame()359     public Rect getSurfaceFrame() {
360       return null;
361     }
362 
363     @Override
isCreating()364     public boolean isCreating() {
365       return false;
366     }
367 
368     @Override
lockCanvas()369     public Canvas lockCanvas() {
370       return null;
371     }
372 
373     @Override
lockCanvas(Rect dirty)374     public Canvas lockCanvas(Rect dirty) {
375       return null;
376     }
377 
378     @Override
removeCallback(Callback callback)379     public void removeCallback(Callback callback) {
380     }
381 
382     @Override
setFixedSize(int width, int height)383     public void setFixedSize(int width, int height) {
384     }
385 
386     @Override
setFormat(int format)387     public void setFormat(int format) {
388     }
389 
390     @Override
setKeepScreenOn(boolean screenOn)391     public void setKeepScreenOn(boolean screenOn) {
392     }
393 
394     @Override
setSizeFromLayout()395     public void setSizeFromLayout() {
396     }
397 
398     @Override
setType(int type)399     public void setType(int type) {
400     }
401 
402     @Override
unlockCanvasAndPost(Canvas canvas)403     public void unlockCanvasAndPost(Canvas canvas) {
404     }
405   }
406 }
407