125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb/*
225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb * Copyright (C) 2012 The Android Open Source Project
325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb *
425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb * Licensed under the Apache License, Version 2.0 (the "License");
525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb * you may not use this file except in compliance with the License.
625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb * You may obtain a copy of the License at
725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb *
825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb *      http://www.apache.org/licenses/LICENSE-2.0
925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb *
1025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb * Unless required by applicable law or agreed to in writing, software
1125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb * distributed under the License is distributed on an "AS IS" BASIS,
1225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb * See the License for the specific language governing permissions and
1425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb * limitations under the License.
1525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb */
1625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
1725668cd6ed661c59295cb65348a126fb245757d4Michael Kolbpackage com.android.camera;
1825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
1925668cd6ed661c59295cb65348a126fb245757d4Michael Kolbimport static com.android.camera.Util.Assert;
2025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
2125668cd6ed661c59295cb65348a126fb245757d4Michael Kolbimport android.annotation.TargetApi;
2225668cd6ed661c59295cb65348a126fb245757d4Michael Kolbimport android.graphics.SurfaceTexture;
2325668cd6ed661c59295cb65348a126fb245757d4Michael Kolbimport android.hardware.Camera.AutoFocusCallback;
2425668cd6ed661c59295cb65348a126fb245757d4Michael Kolbimport android.hardware.Camera.AutoFocusMoveCallback;
2525668cd6ed661c59295cb65348a126fb245757d4Michael Kolbimport android.hardware.Camera.ErrorCallback;
2625668cd6ed661c59295cb65348a126fb245757d4Michael Kolbimport android.hardware.Camera.FaceDetectionListener;
2725668cd6ed661c59295cb65348a126fb245757d4Michael Kolbimport android.hardware.Camera.OnZoomChangeListener;
2825668cd6ed661c59295cb65348a126fb245757d4Michael Kolbimport android.hardware.Camera.Parameters;
2925668cd6ed661c59295cb65348a126fb245757d4Michael Kolbimport android.hardware.Camera.PictureCallback;
3025668cd6ed661c59295cb65348a126fb245757d4Michael Kolbimport android.hardware.Camera.PreviewCallback;
3125668cd6ed661c59295cb65348a126fb245757d4Michael Kolbimport android.hardware.Camera.ShutterCallback;
3225668cd6ed661c59295cb65348a126fb245757d4Michael Kolbimport android.os.Handler;
3325668cd6ed661c59295cb65348a126fb245757d4Michael Kolbimport android.os.HandlerThread;
3425668cd6ed661c59295cb65348a126fb245757d4Michael Kolbimport android.os.Looper;
3525668cd6ed661c59295cb65348a126fb245757d4Michael Kolbimport android.os.Message;
3625668cd6ed661c59295cb65348a126fb245757d4Michael Kolbimport android.util.Log;
371d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kongimport android.view.SurfaceHolder;
3825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
3925668cd6ed661c59295cb65348a126fb245757d4Michael Kolbimport com.android.gallery3d.common.ApiHelper;
4025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
4125668cd6ed661c59295cb65348a126fb245757d4Michael Kolbimport java.io.IOException;
4225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
4325668cd6ed661c59295cb65348a126fb245757d4Michael Kolbpublic class CameraManager {
4425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    private static final String TAG = "CameraManager";
4525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    private static CameraManager sCameraManager = new CameraManager();
4625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
4725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    private Parameters mParameters;
481d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong    private boolean mParametersIsDirty;
493cc47764ae04eef5d50e3c0d070baee9b4a21150Angus Kong    private IOException mReconnectIOException;
5025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
5125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    private static final int RELEASE = 1;
5225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    private static final int RECONNECT = 2;
5325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    private static final int UNLOCK = 3;
5425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    private static final int LOCK = 4;
5525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    private static final int SET_PREVIEW_TEXTURE_ASYNC = 5;
5625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    private static final int START_PREVIEW_ASYNC = 6;
5725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    private static final int STOP_PREVIEW = 7;
5825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    private static final int SET_PREVIEW_CALLBACK_WITH_BUFFER = 8;
5925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    private static final int ADD_CALLBACK_BUFFER = 9;
6025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    private static final int AUTO_FOCUS = 10;
6125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    private static final int CANCEL_AUTO_FOCUS = 11;
6225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    private static final int SET_AUTO_FOCUS_MOVE_CALLBACK = 12;
6325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    private static final int SET_DISPLAY_ORIENTATION = 13;
6425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    private static final int SET_ZOOM_CHANGE_LISTENER = 14;
6525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    private static final int SET_FACE_DETECTION_LISTENER = 15;
6625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    private static final int START_FACE_DETECTION = 16;
6725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    private static final int STOP_FACE_DETECTION = 17;
6825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    private static final int SET_ERROR_CALLBACK = 18;
6925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    private static final int SET_PARAMETERS = 19;
7025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    private static final int GET_PARAMETERS = 20;
71f7771f98aed9f253048af7dd8b2a143b9258c139Angus Kong    private static final int SET_PREVIEW_DISPLAY_ASYNC = 21;
72f7771f98aed9f253048af7dd8b2a143b9258c139Angus Kong    private static final int SET_PREVIEW_CALLBACK = 22;
73f7771f98aed9f253048af7dd8b2a143b9258c139Angus Kong    private static final int ENABLE_SHUTTER_SOUND = 23;
74f7771f98aed9f253048af7dd8b2a143b9258c139Angus Kong    private static final int REFRESH_PARAMETERS = 24;
7525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
7625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    private Handler mCameraHandler;
7725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    private android.hardware.Camera mCamera;
7825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
79f7771f98aed9f253048af7dd8b2a143b9258c139Angus Kong    // Used to retain a copy of Parameters for setting parameters.
80f7771f98aed9f253048af7dd8b2a143b9258c139Angus Kong    private Parameters mParamsToSet;
81f7771f98aed9f253048af7dd8b2a143b9258c139Angus Kong
82f7771f98aed9f253048af7dd8b2a143b9258c139Angus Kong
831d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong    // This holder is used when we need to pass the exception
841d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong    // back to the calling thread. SynchornousQueue doesn't
851d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong    // allow we to pass a null object thus a holder is needed.
861d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong    private class IOExceptionHolder {
871d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong        public IOException ex;
881d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong    }
891d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong
9025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    public static CameraManager instance() {
9125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        return sCameraManager;
9225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    }
9325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
9425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    private CameraManager() {
9525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        HandlerThread ht = new HandlerThread("Camera Handler Thread");
9625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        ht.start();
9725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        mCameraHandler = new CameraHandler(ht.getLooper());
9825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    }
9925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
10025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    private class CameraHandler extends Handler {
10125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        CameraHandler(Looper looper) {
10225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            super(looper);
10325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
10425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
10525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
10625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        private void startFaceDetection() {
10725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            mCamera.startFaceDetection();
10825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
10925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
11025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
11125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        private void stopFaceDetection() {
11225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            mCamera.stopFaceDetection();
11325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
11425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
11525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
11625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        private void setFaceDetectionListener(FaceDetectionListener listener) {
11725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            mCamera.setFaceDetectionListener(listener);
11825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
11925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
12025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        @TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
12125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        private void setPreviewTexture(Object surfaceTexture) {
12225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            try {
12325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                mCamera.setPreviewTexture((SurfaceTexture) surfaceTexture);
1241d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong            } catch (IOException e) {
12525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                throw new RuntimeException(e);
12625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            }
12725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
12825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
12925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        @TargetApi(ApiHelper.VERSION_CODES.JELLY_BEAN_MR1)
13025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        private void enableShutterSound(boolean enable) {
13125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            mCamera.enableShutterSound(enable);
13225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
13325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
13425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        /*
13525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb         * This method does not deal with the build version check.  Everyone should
13625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb         * check first before sending message to this handler.
13725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb         */
13825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        @Override
13925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        public void handleMessage(final Message msg) {
14025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            try {
14125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                switch (msg.what) {
14225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    case RELEASE:
14325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                        mCamera.release();
14425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                        mCamera = null;
1451d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong                        return;
14625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
14725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    case RECONNECT:
1483cc47764ae04eef5d50e3c0d070baee9b4a21150Angus Kong                        mReconnectIOException = null;
14925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                        try {
15025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                            mCamera.reconnect();
15125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                        } catch (IOException ex) {
1523cc47764ae04eef5d50e3c0d070baee9b4a21150Angus Kong                            mReconnectIOException = ex;
1531d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong                        }
1541d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong                        return;
15525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
15625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    case UNLOCK:
15725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                        mCamera.unlock();
1581d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong                        return;
15925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
16025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    case LOCK:
16125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                        mCamera.lock();
1621d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong                        return;
16325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
16425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    case SET_PREVIEW_TEXTURE_ASYNC:
16525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                        setPreviewTexture(msg.obj);
1661d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong                        return;
16725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
16825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    case SET_PREVIEW_DISPLAY_ASYNC:
16925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                        try {
17025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                            mCamera.setPreviewDisplay((SurfaceHolder) msg.obj);
1711d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong                        } catch (IOException e) {
17225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                            throw new RuntimeException(e);
17325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                        }
1741d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong                        return;
17525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
17625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    case START_PREVIEW_ASYNC:
17725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                        mCamera.startPreview();
1781d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong                        return;
17925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
18025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    case STOP_PREVIEW:
18125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                        mCamera.stopPreview();
1821d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong                        return;
18325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
18425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    case SET_PREVIEW_CALLBACK_WITH_BUFFER:
18525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                        mCamera.setPreviewCallbackWithBuffer(
18625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                            (PreviewCallback) msg.obj);
1871d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong                        return;
18825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
18925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    case ADD_CALLBACK_BUFFER:
19025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                        mCamera.addCallbackBuffer((byte[]) msg.obj);
1911d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong                        return;
19225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
19325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    case AUTO_FOCUS:
19425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                        mCamera.autoFocus((AutoFocusCallback) msg.obj);
1951d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong                        return;
19625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
19725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    case CANCEL_AUTO_FOCUS:
19825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                        mCamera.cancelAutoFocus();
1991d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong                        return;
20025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
20125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    case SET_AUTO_FOCUS_MOVE_CALLBACK:
20225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                        setAutoFocusMoveCallback(mCamera, msg.obj);
2031d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong                        return;
20425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
20525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    case SET_DISPLAY_ORIENTATION:
20625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                        mCamera.setDisplayOrientation(msg.arg1);
2071d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong                        return;
20825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
20925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    case SET_ZOOM_CHANGE_LISTENER:
21025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                        mCamera.setZoomChangeListener(
21125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                            (OnZoomChangeListener) msg.obj);
2121d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong                        return;
21325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
21425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    case SET_FACE_DETECTION_LISTENER:
21525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                        setFaceDetectionListener((FaceDetectionListener) msg.obj);
2161d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong                        return;
21725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
21825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    case START_FACE_DETECTION:
21925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                        startFaceDetection();
2201d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong                        return;
22125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
22225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    case STOP_FACE_DETECTION:
22325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                        stopFaceDetection();
2241d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong                        return;
22525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
22625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    case SET_ERROR_CALLBACK:
22725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                        mCamera.setErrorCallback((ErrorCallback) msg.obj);
2281d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong                        return;
22925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
23025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    case SET_PARAMETERS:
231b1666afb8778b371c52e7a9cc7680f1c3a05de34Angus Kong                        mParametersIsDirty = true;
232f7771f98aed9f253048af7dd8b2a143b9258c139Angus Kong                        mParamsToSet.unflatten((String) msg.obj);
233f7771f98aed9f253048af7dd8b2a143b9258c139Angus Kong                        mCamera.setParameters(mParamsToSet);
2341d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong                        return;
23525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
23625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    case GET_PARAMETERS:
237b1666afb8778b371c52e7a9cc7680f1c3a05de34Angus Kong                        if (mParametersIsDirty) {
238b1666afb8778b371c52e7a9cc7680f1c3a05de34Angus Kong                            mParameters = mCamera.getParameters();
239b1666afb8778b371c52e7a9cc7680f1c3a05de34Angus Kong                            mParametersIsDirty = false;
240b1666afb8778b371c52e7a9cc7680f1c3a05de34Angus Kong                        }
2411d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong                        return;
24225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
24325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    case SET_PREVIEW_CALLBACK:
24425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                        mCamera.setPreviewCallback((PreviewCallback) msg.obj);
2451d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong                        return;
24625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
24725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    case ENABLE_SHUTTER_SOUND:
24825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                        enableShutterSound((msg.arg1 == 1) ? true : false);
2491d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong                        return;
25025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
251a7e85b7ce7c87ad9d233bb941e568dcc5b8cf5e7Angus Kong                    case REFRESH_PARAMETERS:
252a7e85b7ce7c87ad9d233bb941e568dcc5b8cf5e7Angus Kong                        mParametersIsDirty = true;
253a7e85b7ce7c87ad9d233bb941e568dcc5b8cf5e7Angus Kong                        return;
254a7e85b7ce7c87ad9d233bb941e568dcc5b8cf5e7Angus Kong
25525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    default:
25625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                        throw new RuntimeException("Invalid CameraProxy message=" + msg.what);
25725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                }
25825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            } catch (RuntimeException e) {
25925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                if (msg.what != RELEASE && mCamera != null) {
26025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    try {
26125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                        mCamera.release();
26225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    } catch (Exception ex) {
26325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                        Log.e(TAG, "Fail to release the camera.");
26425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    }
26525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    mCamera = null;
26625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                }
26725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                throw e;
26825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            }
26925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
27025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    }
27125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
27225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    @TargetApi(ApiHelper.VERSION_CODES.JELLY_BEAN)
27325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    private void setAutoFocusMoveCallback(android.hardware.Camera camera,
27425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            Object cb) {
27525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        camera.setAutoFocusMoveCallback((AutoFocusMoveCallback) cb);
27625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    }
27725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
27825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    // Open camera synchronously. This method is invoked in the context of a
27925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    // background thread.
28025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    CameraProxy cameraOpen(int cameraId) {
28125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        // Cannot open camera in mCameraHandler, otherwise all camera events
28225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        // will be routed to mCameraHandler looper, which in turn will call
28325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        // event handler like Camera.onFaceDetection, which in turn will modify
28425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        // UI and cause exception like this:
28525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        // CalledFromWrongThreadException: Only the original thread that created
28625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        // a view hierarchy can touch its views.
28725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        mCamera = android.hardware.Camera.open(cameraId);
28825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        if (mCamera != null) {
2891d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong            mParametersIsDirty = true;
290f7771f98aed9f253048af7dd8b2a143b9258c139Angus Kong            if (mParamsToSet == null) {
291f7771f98aed9f253048af7dd8b2a143b9258c139Angus Kong                mParamsToSet = mCamera.getParameters();
292f7771f98aed9f253048af7dd8b2a143b9258c139Angus Kong            }
293b1666afb8778b371c52e7a9cc7680f1c3a05de34Angus Kong            return new CameraProxy();
29425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        } else {
29525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            return null;
29625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
29725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    }
29825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
29925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    public class CameraProxy {
3001d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong
30125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        private CameraProxy() {
30225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            Assert(mCamera != null);
30325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
30425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
30525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        public android.hardware.Camera getCamera() {
30625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            return mCamera;
30725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
30825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
30925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        public void release() {
310eb543cfb2f598b68791321a7747cdba02204e1faAngus Kong            // release() must be synchronous so we know exactly when the camera
311eb543cfb2f598b68791321a7747cdba02204e1faAngus Kong            // is released and can continue on.
31225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            mCameraHandler.sendEmptyMessage(RELEASE);
313eb543cfb2f598b68791321a7747cdba02204e1faAngus Kong            waitDone();
31425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
31525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
31625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        public void reconnect() throws IOException {
31725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            mCameraHandler.sendEmptyMessage(RECONNECT);
3183cc47764ae04eef5d50e3c0d070baee9b4a21150Angus Kong            waitDone();
3193cc47764ae04eef5d50e3c0d070baee9b4a21150Angus Kong            if (mReconnectIOException != null) {
3203cc47764ae04eef5d50e3c0d070baee9b4a21150Angus Kong                throw mReconnectIOException;
32125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            }
32225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
32325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
32425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        public void unlock() {
32525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            mCameraHandler.sendEmptyMessage(UNLOCK);
32625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
32725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
32825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        public void lock() {
32925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            mCameraHandler.sendEmptyMessage(LOCK);
33025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
33125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
33225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        @TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
33325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        public void setPreviewTextureAsync(final SurfaceTexture surfaceTexture) {
33425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            mCameraHandler.obtainMessage(SET_PREVIEW_TEXTURE_ASYNC, surfaceTexture).sendToTarget();
33525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
33625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
33725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        public void setPreviewDisplayAsync(final SurfaceHolder surfaceHolder) {
33825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            mCameraHandler.obtainMessage(SET_PREVIEW_DISPLAY_ASYNC, surfaceHolder).sendToTarget();
33925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
34025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
34125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        public void startPreviewAsync() {
34225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            mCameraHandler.sendEmptyMessage(START_PREVIEW_ASYNC);
34325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
34425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
345676be54cad694d27342ec5573acba4ce0560834eAngus Kong        // stopPreview() is synchronous because many resources should be released after
346676be54cad694d27342ec5573acba4ce0560834eAngus Kong        // the preview is stopped.
34725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        public void stopPreview() {
34825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            mCameraHandler.sendEmptyMessage(STOP_PREVIEW);
349676be54cad694d27342ec5573acba4ce0560834eAngus Kong            waitDone();
35025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
35125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
35225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        public void setPreviewCallback(final PreviewCallback cb) {
35325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            mCameraHandler.obtainMessage(SET_PREVIEW_CALLBACK, cb).sendToTarget();
35425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
35525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
35625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        public void setPreviewCallbackWithBuffer(final PreviewCallback cb) {
35725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            mCameraHandler.obtainMessage(SET_PREVIEW_CALLBACK_WITH_BUFFER, cb).sendToTarget();
35825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
35925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
36025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        public void addCallbackBuffer(byte[] callbackBuffer) {
36125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            mCameraHandler.obtainMessage(ADD_CALLBACK_BUFFER, callbackBuffer).sendToTarget();
36225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
36325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
36425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        public void autoFocus(AutoFocusCallback cb) {
36525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            mCameraHandler.obtainMessage(AUTO_FOCUS, cb).sendToTarget();
36625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
36725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
36825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        public void cancelAutoFocus() {
3691d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong            mCameraHandler.removeMessages(AUTO_FOCUS);
37025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            mCameraHandler.sendEmptyMessage(CANCEL_AUTO_FOCUS);
37125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
37225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
37325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        @TargetApi(ApiHelper.VERSION_CODES.JELLY_BEAN)
37425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        public void setAutoFocusMoveCallback(AutoFocusMoveCallback cb) {
37525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            mCameraHandler.obtainMessage(SET_AUTO_FOCUS_MOVE_CALLBACK, cb).sendToTarget();
37625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
37725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
37825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        public void takePicture(final ShutterCallback shutter, final PictureCallback raw,
37925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                final PictureCallback postview, final PictureCallback jpeg) {
38025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            // Too many parameters, so use post for simplicity
38125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            mCameraHandler.post(new Runnable() {
38225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                @Override
38325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                public void run() {
38425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    mCamera.takePicture(shutter, raw, postview, jpeg);
38525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                }
38625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            });
38725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
38825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
38925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        public void takePicture2(final ShutterCallback shutter, final PictureCallback raw,
39025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                final PictureCallback postview, final PictureCallback jpeg,
39125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                final int cameraState, final int focusState) {
39225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            // Too many parameters, so use post for simplicity
39325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            mCameraHandler.post(new Runnable() {
39425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                @Override
39525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                public void run() {
39625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    try {
39725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                        mCamera.takePicture(shutter, raw, postview, jpeg);
39825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    } catch (RuntimeException e) {
39925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                        Log.w(TAG, "take picture failed; cameraState:" + cameraState
40025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                            + ", focusState:" + focusState);
40125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                        throw e;
40225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    }
40325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                }
40425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            });
40525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
40625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
40725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        public void setDisplayOrientation(int degrees) {
40825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            mCameraHandler.obtainMessage(SET_DISPLAY_ORIENTATION, degrees, 0)
40925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    .sendToTarget();
41025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
41125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
41225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        public void setZoomChangeListener(OnZoomChangeListener listener) {
41325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            mCameraHandler.obtainMessage(SET_ZOOM_CHANGE_LISTENER, listener).sendToTarget();
41425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
41525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
41625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
41725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        public void setFaceDetectionListener(FaceDetectionListener listener) {
41825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            mCameraHandler.obtainMessage(SET_FACE_DETECTION_LISTENER, listener).sendToTarget();
41925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
42025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
42125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        public void startFaceDetection() {
42225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            mCameraHandler.sendEmptyMessage(START_FACE_DETECTION);
42325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
42425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
42525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        public void stopFaceDetection() {
42625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            mCameraHandler.sendEmptyMessage(STOP_FACE_DETECTION);
42725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
42825668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
42925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        public void setErrorCallback(ErrorCallback cb) {
43025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            mCameraHandler.obtainMessage(SET_ERROR_CALLBACK, cb).sendToTarget();
43125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
43225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
43325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        public void setParameters(Parameters params) {
434fe549800064a2b50211b005dbd2c727b256c44b0Angus Kong            if (params == null) {
435fe549800064a2b50211b005dbd2c727b256c44b0Angus Kong                Log.v(TAG, "null parameters in setParameters()");
436fe549800064a2b50211b005dbd2c727b256c44b0Angus Kong                return;
437fe549800064a2b50211b005dbd2c727b256c44b0Angus Kong            }
438f7771f98aed9f253048af7dd8b2a143b9258c139Angus Kong            mCameraHandler.obtainMessage(SET_PARAMETERS, params.flatten())
439f7771f98aed9f253048af7dd8b2a143b9258c139Angus Kong                    .sendToTarget();
44025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
44125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
44225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        public Parameters getParameters() {
443b1666afb8778b371c52e7a9cc7680f1c3a05de34Angus Kong            mCameraHandler.sendEmptyMessage(GET_PARAMETERS);
444b1666afb8778b371c52e7a9cc7680f1c3a05de34Angus Kong            waitDone();
4451d75253194716a89e5f5a865b1993bc2bb9b492dAngus Kong            return mParameters;
44625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
44725668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
448a7e85b7ce7c87ad9d233bb941e568dcc5b8cf5e7Angus Kong        public void refreshParameters() {
449a7e85b7ce7c87ad9d233bb941e568dcc5b8cf5e7Angus Kong            mCameraHandler.sendEmptyMessage(REFRESH_PARAMETERS);
450a7e85b7ce7c87ad9d233bb941e568dcc5b8cf5e7Angus Kong        }
451a7e85b7ce7c87ad9d233bb941e568dcc5b8cf5e7Angus Kong
45225668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        public void enableShutterSound(boolean enable) {
45325668cd6ed661c59295cb65348a126fb245757d4Michael Kolb            mCameraHandler.obtainMessage(
45425668cd6ed661c59295cb65348a126fb245757d4Michael Kolb                    ENABLE_SHUTTER_SOUND, (enable ? 1 : 0), 0).sendToTarget();
45525668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
45625668cd6ed661c59295cb65348a126fb245757d4Michael Kolb
457fe549800064a2b50211b005dbd2c727b256c44b0Angus Kong        // return false if cancelled.
458fe549800064a2b50211b005dbd2c727b256c44b0Angus Kong        public boolean waitDone() {
4593cc47764ae04eef5d50e3c0d070baee9b4a21150Angus Kong            final Object waitDoneLock = new Object();
4603cc47764ae04eef5d50e3c0d070baee9b4a21150Angus Kong            final Runnable unlockRunnable = new Runnable() {
4613cc47764ae04eef5d50e3c0d070baee9b4a21150Angus Kong                @Override
4623cc47764ae04eef5d50e3c0d070baee9b4a21150Angus Kong                public void run() {
4633cc47764ae04eef5d50e3c0d070baee9b4a21150Angus Kong                    synchronized (waitDoneLock) {
4643cc47764ae04eef5d50e3c0d070baee9b4a21150Angus Kong                        waitDoneLock.notifyAll();
4653cc47764ae04eef5d50e3c0d070baee9b4a21150Angus Kong                    }
4663cc47764ae04eef5d50e3c0d070baee9b4a21150Angus Kong                }
4673cc47764ae04eef5d50e3c0d070baee9b4a21150Angus Kong            };
4683cc47764ae04eef5d50e3c0d070baee9b4a21150Angus Kong
4693cc47764ae04eef5d50e3c0d070baee9b4a21150Angus Kong            synchronized (waitDoneLock) {
4703cc47764ae04eef5d50e3c0d070baee9b4a21150Angus Kong                mCameraHandler.post(unlockRunnable);
4713cc47764ae04eef5d50e3c0d070baee9b4a21150Angus Kong                try {
4723cc47764ae04eef5d50e3c0d070baee9b4a21150Angus Kong                    waitDoneLock.wait();
4733cc47764ae04eef5d50e3c0d070baee9b4a21150Angus Kong                } catch (InterruptedException ex) {
4743cc47764ae04eef5d50e3c0d070baee9b4a21150Angus Kong                    Log.v(TAG, "waitDone interrupted");
475fe549800064a2b50211b005dbd2c727b256c44b0Angus Kong                    return false;
4763cc47764ae04eef5d50e3c0d070baee9b4a21150Angus Kong                }
4773cc47764ae04eef5d50e3c0d070baee9b4a21150Angus Kong            }
478fe549800064a2b50211b005dbd2c727b256c44b0Angus Kong            return true;
47925668cd6ed661c59295cb65348a126fb245757d4Michael Kolb        }
48025668cd6ed661c59295cb65348a126fb245757d4Michael Kolb    }
48125668cd6ed661c59295cb65348a126fb245757d4Michael Kolb}
482