CameraAgent.java revision b30d2c670f1262f0d60181e40dad33f2151fee4a
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 characteristics.
347         */
348        public CameraDeviceInfo.Characteristics getCharacteristics();
349
350        /**
351         * @return The camera capabilities.
352         */
353        public CameraCapabilities getCapabilities();
354
355        /**
356         * Reconnects to the camera device. On success, the camera device will
357         * be returned through {@link CameraAgent
358         * .CameraOpenCallback#onCameraOpened(com.android.camera.cameradevice.CameraAgent
359         * .CameraProxy)}.
360         * @see android.hardware.Camera#reconnect()
361         *
362         * @param handler The {@link android.os.Handler} in which the callback
363         *                was handled.
364         * @param cb The callback when any error happens.
365         */
366        public void reconnect(Handler handler, CameraOpenCallback cb);
367
368        /**
369         * Unlocks the camera device.
370         *
371         * @see android.hardware.Camera#unlock()
372         */
373        public void unlock();
374
375        /**
376         * Locks the camera device.
377         * @see android.hardware.Camera#lock()
378         */
379        public void lock();
380
381        /**
382         * Sets the {@link android.graphics.SurfaceTexture} for preview.
383         *
384         * @param surfaceTexture The {@link SurfaceTexture} for preview.
385         */
386        public void setPreviewTexture(final SurfaceTexture surfaceTexture);
387
388        /**
389         * Blocks until a {@link android.graphics.SurfaceTexture} has been set
390         * for preview.
391         *
392         * @param surfaceTexture The {@link SurfaceTexture} for preview.
393         */
394        public void setPreviewTextureSync(final SurfaceTexture surfaceTexture);
395
396        /**
397         * Sets the {@link android.view.SurfaceHolder} for preview.
398         *
399         * @param surfaceHolder The {@link SurfaceHolder} for preview.
400         */
401        public void setPreviewDisplay(final SurfaceHolder surfaceHolder);
402
403        /**
404         * Starts the camera preview.
405         */
406        public void startPreview();
407
408        /**
409         * Starts the camera preview and executes a callback on a handler once
410         * the preview starts.
411         */
412        public void startPreviewWithCallback(Handler h, CameraStartPreviewCallback cb);
413
414        /**
415         * Stops the camera preview synchronously.
416         * {@code stopPreview()} must be synchronous to ensure that the caller can
417         * continues to release resources related to camera preview.
418         */
419        public void stopPreview();
420
421        /**
422         * Sets the callback for preview data.
423         *
424         * @param handler    The {@link android.os.Handler} in which the callback was handled.
425         * @param cb         The callback to be invoked when the preview data is available.
426         * @see  android.hardware.Camera#setPreviewCallback(android.hardware.Camera.PreviewCallback)
427         */
428        public void setPreviewDataCallback(Handler handler, CameraPreviewDataCallback cb);
429
430        /**
431         * Sets the one-time callback for preview data.
432         *
433         * @param handler    The {@link android.os.Handler} in which the callback was handled.
434         * @param cb         The callback to be invoked when the preview data for
435         *                   next frame is available.
436         * @see  android.hardware.Camera#setPreviewCallback(android.hardware.Camera.PreviewCallback)
437         */
438        public void setOneShotPreviewCallback(Handler handler, CameraPreviewDataCallback cb);
439
440        /**
441         * Sets the callback for preview data.
442         *
443         * @param handler The handler in which the callback will be invoked.
444         * @param cb      The callback to be invoked when the preview data is available.
445         * @see android.hardware.Camera#setPreviewCallbackWithBuffer(android.hardware.Camera.PreviewCallback)
446         */
447        public void setPreviewDataCallbackWithBuffer(Handler handler, CameraPreviewDataCallback cb);
448
449        /**
450         * Adds buffer for the preview callback.
451         *
452         * @param callbackBuffer The buffer allocated for the preview data.
453         */
454        public void addCallbackBuffer(byte[] callbackBuffer);
455
456        /**
457         * Starts the auto-focus process. The result will be returned through the callback.
458         *
459         * @param handler The handler in which the callback will be invoked.
460         * @param cb      The auto-focus callback.
461         */
462        public void autoFocus(Handler handler, CameraAFCallback cb);
463
464        /**
465         * Cancels the auto-focus process.
466         */
467        public void cancelAutoFocus();
468
469        /**
470         * Sets the auto-focus callback
471         *
472         * @param handler The handler in which the callback will be invoked.
473         * @param cb      The callback to be invoked when the preview data is available.
474         */
475        @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
476        public void setAutoFocusMoveCallback(Handler handler, CameraAFMoveCallback cb);
477
478        /**
479         * Instrument the camera to take a picture.
480         *
481         * @param handler   The handler in which the callback will be invoked.
482         * @param shutter   The callback for shutter action, may be null.
483         * @param raw       The callback for uncompressed data, may be null.
484         * @param postview  The callback for postview image data, may be null.
485         * @param jpeg      The callback for jpeg image data, may be null.
486         * @see android.hardware.Camera#takePicture(
487         *         android.hardware.Camera.ShutterCallback,
488         *         android.hardware.Camera.PictureCallback,
489         *         android.hardware.Camera.PictureCallback)
490         */
491        public void takePicture(
492                Handler handler,
493                CameraShutterCallback shutter,
494                CameraPictureCallback raw,
495                CameraPictureCallback postview,
496                CameraPictureCallback jpeg);
497
498        /**
499         * Sets the display orientation for camera to adjust the preview orientation.
500         *
501         * @param degrees The rotation in degrees. Should be 0, 90, 180 or 270.
502         */
503        public void setDisplayOrientation(int degrees);
504
505        /**
506         * Sets the listener for zoom change.
507         *
508         * @param listener The listener.
509         */
510        public void setZoomChangeListener(OnZoomChangeListener listener);
511
512        /**
513         * Sets the face detection listener.
514         *
515         * @param handler  The handler in which the callback will be invoked.
516         * @param callback The callback for face detection results.
517         */
518        public void setFaceDetectionCallback(Handler handler, CameraFaceDetectionCallback callback);
519
520        /**
521         * Starts the face detection.
522         */
523        public void startFaceDetection();
524
525        /**
526         * Stops the face detection.
527         */
528        public void stopFaceDetection();
529
530        /**
531         * Registers an error callback.
532         *
533         * @param handler  The handler on which the callback will be invoked.
534         * @param cb The error callback.
535         * @see android.hardware.Camera#setErrorCallback(android.hardware.Camera.ErrorCallback)
536         */
537        public void setErrorCallback(Handler handler, CameraErrorCallback cb);
538
539        /**
540         * Sets the camera parameters.
541         *
542         * @param params The camera parameters to use.
543         */
544        @Deprecated
545        public void setParameters(Camera.Parameters params);
546
547        /**
548         * Gets the current camera parameters synchronously. This method is
549         * synchronous since the caller has to wait for the camera to return
550         * the parameters. If the parameters are already cached, it returns
551         * immediately.
552         */
553        @Deprecated
554        public Camera.Parameters getParameters();
555
556        /**
557         * Gets the current camera settings synchronously.
558         * <p>This method is synchronous since the caller has to wait for the
559         * camera to return the parameters. If the parameters are already
560         * cached, it returns immediately.</p>
561         */
562        public CameraSettings getSettings();
563
564        /**
565         * Applies the settings to the camera device.
566         *
567         * @param settings The settings to use on the device.
568         * @return Whether the settings can be applied.
569         */
570        public boolean applySettings(CameraSettings settings);
571
572        /**
573         * Forces {@code CameraProxy} to update the cached version of the camera
574         * settings regardless of the dirty bit.
575         */
576        public void refreshSettings();
577
578        /**
579         * Enables/Disables the camera shutter sound.
580         *
581         * @param enable   {@code true} to enable the shutter sound,
582         *                 {@code false} to disable it.
583         */
584        public void enableShutterSound(boolean enable);
585
586        /**
587         * Dumps the current settings of the camera device.
588         *
589         * <p>The content varies based on the underlying camera API settings
590         * implementation.</p>
591         *
592         * @return The content of the device settings represented by a string.
593         */
594        public String dumpDeviceSettings();
595    }
596}
597