CameraAgent.java revision 01e7c02174ef268b6d6daaa5a5bb4f752d55964c
1/*
2 * Copyright (C) 2012 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.ex.camera2.portability;
18
19import android.annotation.TargetApi;
20import android.graphics.SurfaceTexture;
21import android.hardware.Camera;
22import android.hardware.Camera.OnZoomChangeListener;
23import android.os.Build;
24import android.os.Handler;
25import android.os.Looper;
26import android.view.SurfaceHolder;
27
28/**
29 * An interface which provides possible camera device operations.
30 *
31 * The client should call {@code CameraAgent.openCamera} to get an instance
32 * of {@link CameraAgent.CameraProxy} to control the camera. Classes
33 * implementing this interface should have its own one unique {@code Thread}
34 * other than the main thread for camera operations. Camera device callbacks
35 * are wrapped since the client should not deal with
36 * {@code android.hardware.Camera} directly.
37 *
38 * TODO: provide callback interfaces for:
39 * {@code android.hardware.Camera.ErrorCallback},
40 * {@code android.hardware.Camera.OnZoomChangeListener}, and
41 */
42public interface CameraAgent {
43    public static final long CAMERA_OPERATION_TIMEOUT_MS = 2500;
44
45    public static class CameraStartPreviewCallbackForward
46            implements CameraStartPreviewCallback {
47        private final Handler mHandler;
48        private final CameraStartPreviewCallback mCallback;
49
50        public static CameraStartPreviewCallbackForward getNewInstance(
51                Handler handler, CameraStartPreviewCallback cb) {
52            if (handler == null || cb == null) {
53                return null;
54            }
55            return new CameraStartPreviewCallbackForward(handler, cb);
56        }
57
58        private CameraStartPreviewCallbackForward(Handler h,
59                CameraStartPreviewCallback cb) {
60            mHandler = h;
61            mCallback = cb;
62        }
63
64        @Override
65        public void onPreviewStarted() {
66            mHandler.post(new Runnable() {
67                @Override
68                public void run() {
69                    mCallback.onPreviewStarted();
70                }
71            });
72        }
73    }
74
75    /**
76     * A callback helps to invoke the original callback on another
77     * {@link android.os.Handler}.
78     */
79    public static class CameraOpenCallbackForward implements CameraOpenCallback {
80        private final Handler mHandler;
81        private final CameraOpenCallback mCallback;
82
83        /**
84         * Returns a new instance of {@link FaceDetectionCallbackForward}.
85         *
86         * @param handler The handler in which the callback will be invoked in.
87         * @param cb The callback to be invoked.
88         * @return The instance of the {@link FaceDetectionCallbackForward}, or
89         *         null if any parameter is null.
90         */
91        public static CameraOpenCallbackForward getNewInstance(
92                Handler handler, CameraOpenCallback cb) {
93            if (handler == null || cb == null) {
94                return null;
95            }
96            return new CameraOpenCallbackForward(handler, cb);
97        }
98
99        private CameraOpenCallbackForward(Handler h, CameraOpenCallback cb) {
100            // Given that we are using the main thread handler, we can create it
101            // here instead of holding onto the PhotoModule objects. In this
102            // way, we can avoid memory leak.
103            mHandler = new Handler(Looper.getMainLooper());
104            mCallback = cb;
105        }
106
107        @Override
108        public void onCameraOpened(final CameraProxy camera) {
109            mHandler.post(new Runnable() {
110                @Override
111                public void run() {
112                    mCallback.onCameraOpened(camera);
113                }
114            });
115        }
116
117        @Override
118        public void onCameraDisabled(final int cameraId) {
119            mHandler.post(new Runnable() {
120                @Override
121                public void run() {
122                    mCallback.onCameraDisabled(cameraId);
123                }
124            });
125        }
126
127        @Override
128        public void onDeviceOpenFailure(final int cameraId, final String info) {
129            mHandler.post(new Runnable() {
130                @Override
131                public void run() {
132                    mCallback.onDeviceOpenFailure(cameraId, info);
133                }
134            });
135        }
136
137        @Override
138        public void onDeviceOpenedAlready(final int cameraId, final String info) {
139            mHandler.post(new Runnable() {
140                @Override
141                public void run() {
142                    mCallback.onDeviceOpenedAlready(cameraId, info);
143                }
144            });
145        }
146
147        @Override
148        public void onReconnectionFailure(final CameraAgent mgr, final String info) {
149            mHandler.post(new Runnable() {
150                @Override
151                public void run() {
152                    mCallback.onReconnectionFailure(mgr, info);
153                }
154            });
155        }
156    }
157
158    /**
159     * A handler for all camera api runtime exceptions.
160     * The default behavior is to throw the runtime exception.
161     */
162    public interface CameraExceptionCallback {
163        public void onCameraException(RuntimeException e);
164    }
165
166    /**
167     * An interface which wraps
168     * {@link android.hardware.Camera.ErrorCallback}
169     */
170    public interface CameraErrorCallback {
171        public void onError(int error, CameraProxy camera);
172    }
173
174    /**
175     * An interface which wraps
176     * {@link android.hardware.Camera.AutoFocusCallback}.
177     */
178    public interface CameraAFCallback {
179        public void onAutoFocus(boolean focused, CameraProxy camera);
180    }
181
182    /**
183     * An interface which wraps
184     * {@link android.hardware.Camera.AutoFocusMoveCallback}.
185     */
186    public interface CameraAFMoveCallback {
187        public void onAutoFocusMoving(boolean moving, CameraProxy camera);
188    }
189
190    /**
191     * An interface which wraps
192     * {@link android.hardware.Camera.ShutterCallback}.
193     */
194    public interface CameraShutterCallback {
195        public void onShutter(CameraProxy camera);
196    }
197
198    /**
199     * An interface which wraps
200     * {@link android.hardware.Camera.PictureCallback}.
201     */
202    public interface CameraPictureCallback {
203        public void onPictureTaken(byte[] data, CameraProxy camera);
204    }
205
206    /**
207     * An interface which wraps
208     * {@link android.hardware.Camera.PreviewCallback}.
209     */
210    public interface CameraPreviewDataCallback {
211        public void onPreviewFrame(byte[] data, CameraProxy camera);
212    }
213
214    /**
215     * An interface which wraps
216     * {@link android.hardware.Camera.FaceDetectionListener}.
217     */
218    public interface CameraFaceDetectionCallback {
219        /**
220         * Callback for face detection.
221         *
222         * @param faces   Recognized face in the preview.
223         * @param camera  The camera which the preview image comes from.
224         */
225        public void onFaceDetection(Camera.Face[] faces, CameraProxy camera);
226    }
227
228    /**
229     * An interface to be called when the camera preview has started.
230     */
231    public interface CameraStartPreviewCallback {
232        /**
233         * Callback when the preview starts.
234         */
235        public void onPreviewStarted();
236    }
237
238    /**
239     * An interface to be called for any events when opening or closing the
240     * camera device. This error callback is different from the one defined
241     * in the framework, {@link android.hardware.Camera.ErrorCallback}, which
242     * is used after the camera is opened.
243     */
244    public interface CameraOpenCallback {
245        /**
246         * Callback when camera open succeeds.
247         */
248        public void onCameraOpened(CameraProxy camera);
249
250        /**
251         * Callback when {@link com.android.camera.CameraDisabledException} is
252         * caught.
253         *
254         * @param cameraId The disabled camera.
255         */
256        public void onCameraDisabled(int cameraId);
257
258        /**
259         * Callback when {@link com.android.camera.CameraHardwareException} is
260         * caught.
261         *
262         * @param cameraId The camera with the hardware failure.
263         * @param info The extra info regarding this failure.
264         */
265        public void onDeviceOpenFailure(int cameraId, String info);
266
267        /**
268         * Callback when trying to open the camera which is already opened.
269         *
270         * @param cameraId The camera which is causing the open error.
271         */
272        public void onDeviceOpenedAlready(int cameraId, String info);
273
274        /**
275         * Callback when {@link java.io.IOException} is caught during
276         * {@link android.hardware.Camera#reconnect()}.
277         *
278         * @param mgr The {@link CameraAgent}
279         *            with the reconnect failure.
280         */
281        public void onReconnectionFailure(CameraAgent mgr, String info);
282    }
283
284    /**
285     * Opens the camera of the specified ID asynchronously. The camera device
286     * will be opened in the camera handler thread and will be returned through
287     * the {@link CameraAgent.CameraOpenCallback#
288     * onCameraOpened(com.android.camera.cameradevice.CameraAgent.CameraProxy)}.
289     *
290     * @param handler The {@link android.os.Handler} in which the callback
291     *                was handled.
292     * @param callback The callback for the result.
293     * @param cameraId The camera ID to open.
294     */
295    public void openCamera(Handler handler, int cameraId, CameraOpenCallback callback);
296
297    /**
298     * Closes the camera device.
299     *
300     * @param camera The camera to close. {@code null} means all.
301     * @param synced Whether this call should be synchronous.
302     */
303    public void closeCamera(CameraProxy camera, boolean synced);
304
305    /**
306     * Sets a callback for handling camera api runtime exceptions on
307     * a handler.
308     */
309    public void setCameraDefaultExceptionCallback(CameraExceptionCallback callback,
310            Handler handler);
311
312    /**
313     * Recycles the resources used by this instance. CameraAgent will be in
314     * an unusable state after calling this.
315     */
316    public void recycle();
317
318    /**
319     * @return The camera devices info.
320     */
321    public CameraDeviceInfo getCameraDeviceInfo();
322
323    /**
324     * An interface that takes camera operation requests and post messages to the
325     * camera handler thread. All camera operations made through this interface is
326     * asynchronous by default except those mentioned specifically.
327     */
328    public interface CameraProxy {
329
330        /**
331         * Returns the underlying {@link android.hardware.Camera} object used
332         * by this proxy. This method should only be used when handing the
333         * camera device over to {@link android.media.MediaRecorder} for
334         * recording.
335         */
336        @Deprecated
337        public android.hardware.Camera getCamera();
338
339        /**
340         * @return The camera ID associated to by this
341         * {@link CameraAgent.CameraProxy}.
342         */
343        public int getCameraId();
344
345        /**
346         * @return The camera capabilities.
347         */
348        public CameraCapabilities getCapabilities();
349
350        /**
351         * Reconnects to the camera device. On success, the camera device will
352         * be returned through {@link CameraAgent
353         * .CameraOpenCallback#onCameraOpened(com.android.camera.cameradevice.CameraAgent
354         * .CameraProxy)}.
355         * @see android.hardware.Camera#reconnect()
356         *
357         * @param handler The {@link android.os.Handler} in which the callback
358         *                was handled.
359         * @param cb The callback when any error happens.
360         */
361        public void reconnect(Handler handler, CameraOpenCallback cb);
362
363        /**
364         * Unlocks the camera device.
365         *
366         * @see android.hardware.Camera#unlock()
367         */
368        public void unlock();
369
370        /**
371         * Locks the camera device.
372         * @see android.hardware.Camera#lock()
373         */
374        public void lock();
375
376        /**
377         * Sets the {@link android.graphics.SurfaceTexture} for preview.
378         *
379         * @param surfaceTexture The {@link SurfaceTexture} for preview.
380         */
381        public void setPreviewTexture(final SurfaceTexture surfaceTexture);
382
383        /**
384         * Blocks until a {@link android.graphics.SurfaceTexture} has been set
385         * for preview.
386         *
387         * @param surfaceTexture The {@link SurfaceTexture} for preview.
388         */
389        public void setPreviewTextureSync(final SurfaceTexture surfaceTexture);
390
391        /**
392         * Sets the {@link android.view.SurfaceHolder} for preview.
393         *
394         * @param surfaceHolder The {@link SurfaceHolder} for preview.
395         */
396        public void setPreviewDisplay(final SurfaceHolder surfaceHolder);
397
398        /**
399         * Starts the camera preview.
400         */
401        public void startPreview();
402
403        /**
404         * Starts the camera preview and executes a callback on a handler once
405         * the preview starts.
406         */
407        public void startPreviewWithCallback(Handler h, CameraStartPreviewCallback cb);
408
409        /**
410         * Stops the camera preview synchronously.
411         * {@code stopPreview()} must be synchronous to ensure that the caller can
412         * continues to release resources related to camera preview.
413         */
414        public void stopPreview();
415
416        /**
417         * Sets the callback for preview data.
418         *
419         * @param handler    The {@link android.os.Handler} in which the callback was handled.
420         * @param cb         The callback to be invoked when the preview data is available.
421         * @see  android.hardware.Camera#setPreviewCallback(android.hardware.Camera.PreviewCallback)
422         */
423        public void setPreviewDataCallback(Handler handler, CameraPreviewDataCallback cb);
424
425        /**
426         * Sets the one-time callback for preview data.
427         *
428         * @param handler    The {@link android.os.Handler} in which the callback was handled.
429         * @param cb         The callback to be invoked when the preview data for
430         *                   next frame is available.
431         * @see  android.hardware.Camera#setPreviewCallback(android.hardware.Camera.PreviewCallback)
432         */
433        public void setOneShotPreviewCallback(Handler handler, CameraPreviewDataCallback cb);
434
435        /**
436         * Sets the callback for preview data.
437         *
438         * @param handler The handler in which the callback will be invoked.
439         * @param cb      The callback to be invoked when the preview data is available.
440         * @see android.hardware.Camera#setPreviewCallbackWithBuffer(android.hardware.Camera.PreviewCallback)
441         */
442        public void setPreviewDataCallbackWithBuffer(Handler handler, CameraPreviewDataCallback cb);
443
444        /**
445         * Adds buffer for the preview callback.
446         *
447         * @param callbackBuffer The buffer allocated for the preview data.
448         */
449        public void addCallbackBuffer(byte[] callbackBuffer);
450
451        /**
452         * Starts the auto-focus process. The result will be returned through the callback.
453         *
454         * @param handler The handler in which the callback will be invoked.
455         * @param cb      The auto-focus callback.
456         */
457        public void autoFocus(Handler handler, CameraAFCallback cb);
458
459        /**
460         * Cancels the auto-focus process.
461         */
462        public void cancelAutoFocus();
463
464        /**
465         * Sets the auto-focus callback
466         *
467         * @param handler The handler in which the callback will be invoked.
468         * @param cb      The callback to be invoked when the preview data is available.
469         */
470        @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
471        public void setAutoFocusMoveCallback(Handler handler, CameraAFMoveCallback cb);
472
473        /**
474         * Instrument the camera to take a picture.
475         *
476         * @param handler   The handler in which the callback will be invoked.
477         * @param shutter   The callback for shutter action, may be null.
478         * @param raw       The callback for uncompressed data, may be null.
479         * @param postview  The callback for postview image data, may be null.
480         * @param jpeg      The callback for jpeg image data, may be null.
481         * @see android.hardware.Camera#takePicture(
482         *         android.hardware.Camera.ShutterCallback,
483         *         android.hardware.Camera.PictureCallback,
484         *         android.hardware.Camera.PictureCallback)
485         */
486        public void takePicture(
487                Handler handler,
488                CameraShutterCallback shutter,
489                CameraPictureCallback raw,
490                CameraPictureCallback postview,
491                CameraPictureCallback jpeg);
492
493        /**
494         * Sets the display orientation for camera to adjust the preview orientation.
495         *
496         * @param degrees The rotation in degrees. Should be 0, 90, 180 or 270.
497         */
498        public void setDisplayOrientation(int degrees);
499
500        /**
501         * Sets the listener for zoom change.
502         *
503         * @param listener The listener.
504         */
505        public void setZoomChangeListener(OnZoomChangeListener listener);
506
507        /**
508         * Sets the face detection listener.
509         *
510         * @param handler  The handler in which the callback will be invoked.
511         * @param callback The callback for face detection results.
512         */
513        public void setFaceDetectionCallback(Handler handler, CameraFaceDetectionCallback callback);
514
515        /**
516         * Starts the face detection.
517         */
518        public void startFaceDetection();
519
520        /**
521         * Stops the face detection.
522         */
523        public void stopFaceDetection();
524
525        /**
526         * Registers an error callback.
527         *
528         * @param handler  The handler on which the callback will be invoked.
529         * @param cb The error callback.
530         * @see android.hardware.Camera#setErrorCallback(android.hardware.Camera.ErrorCallback)
531         */
532        public void setErrorCallback(Handler handler, CameraErrorCallback cb);
533
534        /**
535         * Sets the camera parameters.
536         *
537         * @param params The camera parameters to use.
538         */
539        @Deprecated
540        public void setParameters(Camera.Parameters params);
541
542        /**
543         * Gets the current camera parameters synchronously. This method is
544         * synchronous since the caller has to wait for the camera to return
545         * the parameters. If the parameters are already cached, it returns
546         * immediately.
547         */
548        @Deprecated
549        public Camera.Parameters getParameters();
550
551        /**
552         * Gets the current camera settings synchronously.
553         * <p>This method is synchronous since the caller has to wait for the
554         * camera to return the parameters. If the parameters are already
555         * cached, it returns immediately.</p>
556         */
557        public CameraSettings getSettings();
558
559        /**
560         * Applies the settings to the camera device.
561         *
562         * @param settings The settings to use on the device.
563         * @return Whether the settings can be applied.
564         */
565        public boolean applySettings(CameraSettings settings);
566
567        /**
568         * Forces {@code CameraProxy} to update the cached version of the camera
569         * settings regardless of the dirty bit.
570         */
571        public void refreshSettings();
572
573        /**
574         * Enables/Disables the camera shutter sound.
575         *
576         * @param enable   {@code true} to enable the shutter sound,
577         *                 {@code false} to disable it.
578         */
579        public void enableShutterSound(boolean enable);
580
581        /**
582         * Dumps the current settings of the camera device.
583         *
584         * <p>The content varies based on the underlying camera API settings
585         * implementation.</p>
586         *
587         * @return The content of the device settings represented by a string.
588         */
589        public String dumpDeviceSettings();
590    }
591}
592