1package com.xtremelabs.robolectric.shadows;
2
3import java.util.ArrayList;
4import java.util.HashMap;
5import java.util.List;
6import java.util.Map;
7
8import android.hardware.Camera;
9import android.view.SurfaceHolder;
10import com.xtremelabs.robolectric.Robolectric;
11import com.xtremelabs.robolectric.internal.Implementation;
12import com.xtremelabs.robolectric.internal.Implements;
13import com.xtremelabs.robolectric.internal.RealObject;
14
15/**
16 * Shadows the Android {@code Camera} class.
17 */
18@Implements(Camera.class)
19public class ShadowCamera {
20
21    private boolean locked;
22    private boolean previewing;
23    private boolean released;
24    private Camera.Parameters parameters;
25    private Camera.PreviewCallback previewCallback;
26    private SurfaceHolder surfaceHolder;
27
28    private static Map<Integer, Camera.CameraInfo> cameras = new HashMap<Integer,Camera.CameraInfo>();
29
30    @RealObject
31    private Camera realCamera;
32
33    public void __constructor__() {
34        locked = true;
35        previewing = false;
36        released = false;
37    }
38
39    @Implementation
40    public static Camera open() {
41        return Robolectric.newInstanceOf(Camera.class);
42    }
43
44    @Implementation
45    public void unlock() {
46        locked = false;
47    }
48
49    @Implementation
50    public void reconnect() {
51        locked = true;
52    }
53
54    @Implementation
55    public Camera.Parameters getParameters() {
56        if (null == parameters) {
57            parameters = Robolectric.newInstanceOf(Camera.Parameters.class);
58        }
59        return parameters;
60    }
61
62    @Implementation
63    public void setParameters(Camera.Parameters params) {
64        parameters = params;
65    }
66
67    @Implementation
68    public void setPreviewDisplay(SurfaceHolder holder) {
69        surfaceHolder = holder;
70    }
71
72    @Implementation
73    public void startPreview() {
74        previewing = true;
75    }
76
77    @Implementation
78    public void stopPreview() {
79        previewing = false;
80    }
81
82    @Implementation
83    public void release() {
84        released = true;
85    }
86
87    @Implementation
88    public void setPreviewCallback(Camera.PreviewCallback cb) {
89        previewCallback = cb;
90    }
91
92    @Implementation
93    public void setOneShotPreviewCallback(Camera.PreviewCallback cb) {
94        previewCallback = cb;
95    }
96
97    @Implementation
98    public void setPreviewCallbackWithBuffer(Camera.PreviewCallback cb) {
99        previewCallback = cb;
100    }
101
102    @Implementation
103    public static void getCameraInfo(int cameraId, Camera.CameraInfo cameraInfo ) {
104    	Camera.CameraInfo foundCam = cameras.get( cameraId );
105    	cameraInfo.facing = foundCam.facing;
106    	cameraInfo.orientation = foundCam.orientation;
107    }
108
109    @Implementation
110    public static int getNumberOfCameras() {
111    	return cameras.size();
112    }
113
114    /**
115     * Allows test cases to invoke the preview callback, to simulate a frame of camera data.
116     *
117     * @param data byte buffer of simulated camera data
118     */
119    public void invokePreviewCallback(byte[] data) {
120        if (previewCallback != null) {
121            previewCallback.onPreviewFrame(data, realCamera);
122        }
123    }
124
125    public boolean isLocked() {
126        return locked;
127    }
128
129    public boolean isPreviewing() {
130        return previewing;
131    }
132
133    public boolean isReleased() {
134        return released;
135    }
136
137    public SurfaceHolder getPreviewDisplay() {
138        return surfaceHolder;
139    }
140
141    /**
142     * Add a mock {@code Camera.CameraInfo} object to simulate
143     * the existence of one or more cameras.  By default, no
144     * cameras are defined.
145     *
146     * @param id
147     * @param camInfo
148     */
149    public static void addCameraInfo(int id, Camera.CameraInfo camInfo) {
150    	cameras.put(id, camInfo);
151    }
152
153    public static void clearCameraInfo() {
154    	cameras.clear();
155    }
156
157}
158