1475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting/*
2475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting * Copyright (C) 2012 The Android Open Source Project
3475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting *
4475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting * Licensed under the Apache License, Version 2.0 (the "License");
5475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting * you may not use this file except in compliance with the License.
6475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting * You may obtain a copy of the License at
7475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting *
8475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting *      http://www.apache.org/licenses/LICENSE-2.0
9475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting *
10475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting * Unless required by applicable law or agreed to in writing, software
11475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting * distributed under the License is distributed on an "AS IS" BASIS,
12475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting * See the License for the specific language governing permissions and
14475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting * limitations under the License.
15475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting */
16475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
17475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Tingpackage com.android.camera;
18475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
19475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Tingimport static com.android.camera.Util.Assert;
20475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
213022fc1b6b1d666cbb2ee77c9ab1d7961200ab11Chih-Chung Changimport android.annotation.TargetApi;
22475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Tingimport android.graphics.SurfaceTexture;
23475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Tingimport android.hardware.Camera.AutoFocusCallback;
24475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Tingimport android.hardware.Camera.AutoFocusMoveCallback;
25475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Tingimport android.hardware.Camera.ErrorCallback;
26475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Tingimport android.hardware.Camera.FaceDetectionListener;
27475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Tingimport android.hardware.Camera.OnZoomChangeListener;
28475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Tingimport android.hardware.Camera.Parameters;
29475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Tingimport android.hardware.Camera.PictureCallback;
30475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Tingimport android.hardware.Camera.PreviewCallback;
31475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Tingimport android.hardware.Camera.ShutterCallback;
32475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Tingimport android.os.ConditionVariable;
33475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Tingimport android.os.Handler;
34475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Tingimport android.os.HandlerThread;
35475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Tingimport android.os.Looper;
36475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Tingimport android.os.Message;
378a91b608b73eac4677eba27db621b48ce2e66849Michael Kolbimport android.view.SurfaceHolder;
38cd4b5bd53fe9cbf3cdccfbba94f2bc12250eb187Iliyan Malchevimport android.util.Log;
39475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
403022fc1b6b1d666cbb2ee77c9ab1d7961200ab11Chih-Chung Changimport com.android.gallery3d.common.ApiHelper;
413022fc1b6b1d666cbb2ee77c9ab1d7961200ab11Chih-Chung Chang
42475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Tingimport java.io.IOException;
43475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
44475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Tingpublic class CameraManager {
452921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li    private static final String TAG = "CameraManager";
46475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    private static CameraManager sCameraManager = new CameraManager();
47475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
48475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    // Thread progress signals
49475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    private ConditionVariable mSig = new ConditionVariable();
50475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
51475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    private Parameters mParameters;
52475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    private IOException mReconnectException;
53475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
54475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    private static final int RELEASE = 1;
55475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    private static final int RECONNECT = 2;
56475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    private static final int UNLOCK = 3;
57475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    private static final int LOCK = 4;
582921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li    private static final int SET_PREVIEW_TEXTURE_ASYNC = 5;
592921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li    private static final int START_PREVIEW_ASYNC = 6;
60475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    private static final int STOP_PREVIEW = 7;
61475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    private static final int SET_PREVIEW_CALLBACK_WITH_BUFFER = 8;
62475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    private static final int ADD_CALLBACK_BUFFER = 9;
63475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    private static final int AUTO_FOCUS = 10;
64475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    private static final int CANCEL_AUTO_FOCUS = 11;
65475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    private static final int SET_AUTO_FOCUS_MOVE_CALLBACK = 12;
66475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    private static final int SET_DISPLAY_ORIENTATION = 13;
67475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    private static final int SET_ZOOM_CHANGE_LISTENER = 14;
68475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    private static final int SET_FACE_DETECTION_LISTENER = 15;
69475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    private static final int START_FACE_DETECTION = 16;
70475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    private static final int STOP_FACE_DETECTION = 17;
71475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    private static final int SET_ERROR_CALLBACK = 18;
72475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    private static final int SET_PARAMETERS = 19;
73475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    private static final int GET_PARAMETERS = 20;
748498e7cd3b97fbcf28417c38b46f6ba299a59d08Pin Ting    private static final int SET_PARAMETERS_ASYNC = 21;
752921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li    private static final int WAIT_FOR_IDLE = 22;
768e3ccacccd2b128734322877561b8b78a70e103bWu-cheng Li    private static final int SET_PREVIEW_DISPLAY_ASYNC = 23;
777e790a54e9940ac8a7e3e625bf9e30bb4cc726b2Wu-cheng Li    private static final int SET_PREVIEW_CALLBACK = 24;
78c0c5d69598061725bd5a4828a87796c25b515b68Wu-cheng Li    private static final int ENABLE_SHUTTER_SOUND = 25;
79475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
80475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    private Handler mCameraHandler;
81475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    private CameraProxy mCameraProxy;
82475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    private android.hardware.Camera mCamera;
83475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
84475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    public static CameraManager instance() {
85475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        return sCameraManager;
86475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    }
87475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
88475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    private CameraManager() {
89475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        HandlerThread ht = new HandlerThread("Camera Handler Thread");
90475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        ht.start();
91475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        mCameraHandler = new CameraHandler(ht.getLooper());
92475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    }
93475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
94475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    private class CameraHandler extends Handler {
95475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        CameraHandler(Looper looper) {
96475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            super(looper);
97475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        }
98475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
99a9081cd1f9727bb6bdaf406e8ef82bf451002c09Ahbong Chang        @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
100a9081cd1f9727bb6bdaf406e8ef82bf451002c09Ahbong Chang        private void startFaceDetection() {
101a9081cd1f9727bb6bdaf406e8ef82bf451002c09Ahbong Chang            mCamera.startFaceDetection();
102a9081cd1f9727bb6bdaf406e8ef82bf451002c09Ahbong Chang        }
103a9081cd1f9727bb6bdaf406e8ef82bf451002c09Ahbong Chang
104a9081cd1f9727bb6bdaf406e8ef82bf451002c09Ahbong Chang        @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
105a9081cd1f9727bb6bdaf406e8ef82bf451002c09Ahbong Chang        private void stopFaceDetection() {
106a9081cd1f9727bb6bdaf406e8ef82bf451002c09Ahbong Chang            mCamera.stopFaceDetection();
107a9081cd1f9727bb6bdaf406e8ef82bf451002c09Ahbong Chang        }
108a9081cd1f9727bb6bdaf406e8ef82bf451002c09Ahbong Chang
109a9081cd1f9727bb6bdaf406e8ef82bf451002c09Ahbong Chang        @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
110a9081cd1f9727bb6bdaf406e8ef82bf451002c09Ahbong Chang        private void setFaceDetectionListener(FaceDetectionListener listener) {
111a9081cd1f9727bb6bdaf406e8ef82bf451002c09Ahbong Chang            mCamera.setFaceDetectionListener(listener);
112a9081cd1f9727bb6bdaf406e8ef82bf451002c09Ahbong Chang        }
113a9081cd1f9727bb6bdaf406e8ef82bf451002c09Ahbong Chang
114c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li        @TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
115c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li        private void setPreviewTexture(Object surfaceTexture) {
116c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li            try {
117c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li                mCamera.setPreviewTexture((SurfaceTexture) surfaceTexture);
118c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li            } catch(IOException e) {
119c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li                throw new RuntimeException(e);
120c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li            }
121c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li        }
122c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li
123c0c5d69598061725bd5a4828a87796c25b515b68Wu-cheng Li        @TargetApi(ApiHelper.VERSION_CODES.JELLY_BEAN_MR1)
124c0c5d69598061725bd5a4828a87796c25b515b68Wu-cheng Li        private void enableShutterSound(boolean enable) {
125c0c5d69598061725bd5a4828a87796c25b515b68Wu-cheng Li            mCamera.enableShutterSound(enable);
126c0c5d69598061725bd5a4828a87796c25b515b68Wu-cheng Li        }
127c0c5d69598061725bd5a4828a87796c25b515b68Wu-cheng Li
128a9081cd1f9727bb6bdaf406e8ef82bf451002c09Ahbong Chang        /*
129a9081cd1f9727bb6bdaf406e8ef82bf451002c09Ahbong Chang         * This method does not deal with the build version check.  Everyone should
130a9081cd1f9727bb6bdaf406e8ef82bf451002c09Ahbong Chang         * check first before sending message to this handler.
131a9081cd1f9727bb6bdaf406e8ef82bf451002c09Ahbong Chang         */
132475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        @Override
133475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        public void handleMessage(final Message msg) {
1342921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li            try {
1352921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                switch (msg.what) {
1362921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                    case RELEASE:
1372921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        mCamera.release();
1382921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        mCamera = null;
1392921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        mCameraProxy = null;
1402921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        break;
1412921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li
1422921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                    case RECONNECT:
1432921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        mReconnectException = null;
1442921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        try {
1452921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                            mCamera.reconnect();
1462921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        } catch (IOException ex) {
1472921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                            mReconnectException = ex;
1482921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        }
1492921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        break;
1502921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li
1512921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                    case UNLOCK:
1522921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        mCamera.unlock();
1532921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        break;
1542921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li
1552921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                    case LOCK:
1562921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        mCamera.lock();
1572921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        break;
1582921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li
1592921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                    case SET_PREVIEW_TEXTURE_ASYNC:
160c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li                        setPreviewTexture(msg.obj);
1612921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        return;  // no need to call mSig.open()
1622921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li
1638e3ccacccd2b128734322877561b8b78a70e103bWu-cheng Li                    case SET_PREVIEW_DISPLAY_ASYNC:
1648e3ccacccd2b128734322877561b8b78a70e103bWu-cheng Li                        try {
1658e3ccacccd2b128734322877561b8b78a70e103bWu-cheng Li                            mCamera.setPreviewDisplay((SurfaceHolder) msg.obj);
1668e3ccacccd2b128734322877561b8b78a70e103bWu-cheng Li                        } catch(IOException e) {
1678e3ccacccd2b128734322877561b8b78a70e103bWu-cheng Li                            throw new RuntimeException(e);
1688e3ccacccd2b128734322877561b8b78a70e103bWu-cheng Li                        }
1698e3ccacccd2b128734322877561b8b78a70e103bWu-cheng Li                        return;  // no need to call mSig.open()
1708e3ccacccd2b128734322877561b8b78a70e103bWu-cheng Li
1712921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                    case START_PREVIEW_ASYNC:
1722921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        mCamera.startPreview();
1732921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        return;  // no need to call mSig.open()
1742921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li
1752921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                    case STOP_PREVIEW:
1762921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        mCamera.stopPreview();
1772921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        break;
1782921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li
1792921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                    case SET_PREVIEW_CALLBACK_WITH_BUFFER:
1802921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        mCamera.setPreviewCallbackWithBuffer(
1812921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                            (PreviewCallback) msg.obj);
1822921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        break;
1832921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li
1842921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                    case ADD_CALLBACK_BUFFER:
1852921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        mCamera.addCallbackBuffer((byte[]) msg.obj);
1862921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        break;
1872921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li
1882921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                    case AUTO_FOCUS:
1892921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        mCamera.autoFocus((AutoFocusCallback) msg.obj);
1902921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        break;
1912921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li
1922921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                    case CANCEL_AUTO_FOCUS:
1932921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        mCamera.cancelAutoFocus();
1942921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        break;
1952921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li
1962921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                    case SET_AUTO_FOCUS_MOVE_CALLBACK:
1973022fc1b6b1d666cbb2ee77c9ab1d7961200ab11Chih-Chung Chang                        setAutoFocusMoveCallback(mCamera, msg.obj);
1982921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        break;
1992921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li
2002921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                    case SET_DISPLAY_ORIENTATION:
2012921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        mCamera.setDisplayOrientation(msg.arg1);
2022921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        break;
2032921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li
2042921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                    case SET_ZOOM_CHANGE_LISTENER:
2052921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        mCamera.setZoomChangeListener(
2062921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                            (OnZoomChangeListener) msg.obj);
2072921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        break;
2082921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li
2092921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                    case SET_FACE_DETECTION_LISTENER:
210a9081cd1f9727bb6bdaf406e8ef82bf451002c09Ahbong Chang                        setFaceDetectionListener((FaceDetectionListener) msg.obj);
2112921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        break;
2122921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li
2132921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                    case START_FACE_DETECTION:
214a9081cd1f9727bb6bdaf406e8ef82bf451002c09Ahbong Chang                        startFaceDetection();
2152921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        break;
2162921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li
2172921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                    case STOP_FACE_DETECTION:
218a9081cd1f9727bb6bdaf406e8ef82bf451002c09Ahbong Chang                        stopFaceDetection();
2192921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        break;
2202921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li
2212921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                    case SET_ERROR_CALLBACK:
2222921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        mCamera.setErrorCallback((ErrorCallback) msg.obj);
2232921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        break;
2242921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li
2252921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                    case SET_PARAMETERS:
2262921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        mCamera.setParameters((Parameters) msg.obj);
2272921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        break;
2282921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li
2292921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                    case GET_PARAMETERS:
2302921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        mParameters = mCamera.getParameters();
2312921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        break;
2322921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li
2332921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                    case SET_PARAMETERS_ASYNC:
2342921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        mCamera.setParameters((Parameters) msg.obj);
2352921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        return;  // no need to call mSig.open()
2362921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li
2377e790a54e9940ac8a7e3e625bf9e30bb4cc726b2Wu-cheng Li                    case SET_PREVIEW_CALLBACK:
2387e790a54e9940ac8a7e3e625bf9e30bb4cc726b2Wu-cheng Li                        mCamera.setPreviewCallback((PreviewCallback) msg.obj);
2397e790a54e9940ac8a7e3e625bf9e30bb4cc726b2Wu-cheng Li                        break;
2407e790a54e9940ac8a7e3e625bf9e30bb4cc726b2Wu-cheng Li
241c0c5d69598061725bd5a4828a87796c25b515b68Wu-cheng Li                    case ENABLE_SHUTTER_SOUND:
242c0c5d69598061725bd5a4828a87796c25b515b68Wu-cheng Li                        enableShutterSound((msg.arg1 == 1) ? true : false);
243c0c5d69598061725bd5a4828a87796c25b515b68Wu-cheng Li                        break;
244c0c5d69598061725bd5a4828a87796c25b515b68Wu-cheng Li
2452921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                    case WAIT_FOR_IDLE:
2462921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        // do nothing
2472921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        break;
248c0c5d69598061725bd5a4828a87796c25b515b68Wu-cheng Li
249c0c5d69598061725bd5a4828a87796c25b515b68Wu-cheng Li                    default:
250c0c5d69598061725bd5a4828a87796c25b515b68Wu-cheng Li                        throw new RuntimeException("Invalid CameraProxy message=" + msg.what);
2512921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                }
2522921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li            } catch (RuntimeException e) {
2532921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                if (msg.what != RELEASE && mCamera != null) {
254475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting                    try {
2552921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        mCamera.release();
2562921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                    } catch (Exception ex) {
2572921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                        Log.e(TAG, "Fail to release the camera.");
258475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting                    }
2592921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                    mCamera = null;
2602921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                    mCameraProxy = null;
2612921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                }
2622921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li                throw e;
263475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            }
264475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.open();
265475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        }
266475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    }
267475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
2683022fc1b6b1d666cbb2ee77c9ab1d7961200ab11Chih-Chung Chang    @TargetApi(ApiHelper.VERSION_CODES.JELLY_BEAN)
2693022fc1b6b1d666cbb2ee77c9ab1d7961200ab11Chih-Chung Chang    private void setAutoFocusMoveCallback(android.hardware.Camera camera,
2703022fc1b6b1d666cbb2ee77c9ab1d7961200ab11Chih-Chung Chang            Object cb) {
2713022fc1b6b1d666cbb2ee77c9ab1d7961200ab11Chih-Chung Chang        camera.setAutoFocusMoveCallback((AutoFocusMoveCallback) cb);
2723022fc1b6b1d666cbb2ee77c9ab1d7961200ab11Chih-Chung Chang    }
2733022fc1b6b1d666cbb2ee77c9ab1d7961200ab11Chih-Chung Chang
274475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    // Open camera synchronously. This method is invoked in the context of a
275475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    // background thread.
276475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    CameraProxy cameraOpen(int cameraId) {
277475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        // Cannot open camera in mCameraHandler, otherwise all camera events
278475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        // will be routed to mCameraHandler looper, which in turn will call
279475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        // event handler like Camera.onFaceDetection, which in turn will modify
280475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        // UI and cause exception like this:
281475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        // CalledFromWrongThreadException: Only the original thread that created
282475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        // a view hierarchy can touch its views.
283475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        mCamera = android.hardware.Camera.open(cameraId);
284475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        if (mCamera != null) {
285475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mCameraProxy = new CameraProxy();
286475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            return mCameraProxy;
287475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        } else {
288475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            return null;
289475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        }
290475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    }
291475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
292475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    public class CameraProxy {
293475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        private CameraProxy() {
294475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            Assert(mCamera != null);
295475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        }
296475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
297475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        public android.hardware.Camera getCamera() {
298475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            return mCamera;
299475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        }
300475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
301475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        public void release() {
302475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.close();
303475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mCameraHandler.sendEmptyMessage(RELEASE);
304475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.block();
305475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        }
306475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
307475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        public void reconnect() throws IOException {
308475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.close();
309475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mCameraHandler.sendEmptyMessage(RECONNECT);
310475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.block();
311475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            if (mReconnectException != null) {
312475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting                throw mReconnectException;
313475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            }
314475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        }
315475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
316475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        public void unlock() {
317475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.close();
318475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mCameraHandler.sendEmptyMessage(UNLOCK);
319475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.block();
320475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        }
321475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
322475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        public void lock() {
323475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.close();
324475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mCameraHandler.sendEmptyMessage(LOCK);
325475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.block();
326475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        }
327475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
328c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li        @TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
3292921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li        public void setPreviewTextureAsync(final SurfaceTexture surfaceTexture) {
3302921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li            mCameraHandler.obtainMessage(SET_PREVIEW_TEXTURE_ASYNC, surfaceTexture).sendToTarget();
331475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        }
332475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
3338e3ccacccd2b128734322877561b8b78a70e103bWu-cheng Li        public void setPreviewDisplayAsync(final SurfaceHolder surfaceHolder) {
3348e3ccacccd2b128734322877561b8b78a70e103bWu-cheng Li            mCameraHandler.obtainMessage(SET_PREVIEW_DISPLAY_ASYNC, surfaceHolder).sendToTarget();
3358e3ccacccd2b128734322877561b8b78a70e103bWu-cheng Li        }
3368e3ccacccd2b128734322877561b8b78a70e103bWu-cheng Li
3372921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li        public void startPreviewAsync() {
3382921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li            mCameraHandler.sendEmptyMessage(START_PREVIEW_ASYNC);
339475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        }
340475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
341475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        public void stopPreview() {
342475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.close();
343475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mCameraHandler.sendEmptyMessage(STOP_PREVIEW);
344475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.block();
345475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        }
346475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
3477e790a54e9940ac8a7e3e625bf9e30bb4cc726b2Wu-cheng Li        public void setPreviewCallback(final PreviewCallback cb) {
3487e790a54e9940ac8a7e3e625bf9e30bb4cc726b2Wu-cheng Li            mSig.close();
3497e790a54e9940ac8a7e3e625bf9e30bb4cc726b2Wu-cheng Li            mCameraHandler.obtainMessage(SET_PREVIEW_CALLBACK, cb).sendToTarget();
3507e790a54e9940ac8a7e3e625bf9e30bb4cc726b2Wu-cheng Li            mSig.block();
3517e790a54e9940ac8a7e3e625bf9e30bb4cc726b2Wu-cheng Li        }
3527e790a54e9940ac8a7e3e625bf9e30bb4cc726b2Wu-cheng Li
353475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        public void setPreviewCallbackWithBuffer(final PreviewCallback cb) {
354475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.close();
355475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mCameraHandler.obtainMessage(SET_PREVIEW_CALLBACK_WITH_BUFFER, cb).sendToTarget();
356475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.block();
357475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        }
358475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
359475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        public void addCallbackBuffer(byte[] callbackBuffer) {
360475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.close();
361475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mCameraHandler.obtainMessage(ADD_CALLBACK_BUFFER, callbackBuffer).sendToTarget();
362475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.block();
363475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        }
364475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
365475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        public void autoFocus(AutoFocusCallback cb) {
366475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.close();
367475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mCameraHandler.obtainMessage(AUTO_FOCUS, cb).sendToTarget();
368475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.block();
369475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        }
370475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
371475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        public void cancelAutoFocus() {
372475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.close();
373475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mCameraHandler.sendEmptyMessage(CANCEL_AUTO_FOCUS);
374475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.block();
375475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        }
376475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
3773022fc1b6b1d666cbb2ee77c9ab1d7961200ab11Chih-Chung Chang        @TargetApi(ApiHelper.VERSION_CODES.JELLY_BEAN)
378475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        public void setAutoFocusMoveCallback(AutoFocusMoveCallback cb) {
379475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.close();
380475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mCameraHandler.obtainMessage(SET_AUTO_FOCUS_MOVE_CALLBACK, cb).sendToTarget();
381475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.block();
382475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        }
383475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
384475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        public void takePicture(final ShutterCallback shutter, final PictureCallback raw,
385475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting                final PictureCallback postview, final PictureCallback jpeg) {
386475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.close();
387475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            // Too many parameters, so use post for simplicity
388475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mCameraHandler.post(new Runnable() {
389475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting                @Override
390475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting                public void run() {
391475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting                    mCamera.takePicture(shutter, raw, postview, jpeg);
392475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting                    mSig.open();
393475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting                }
394475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            });
395475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.block();
396475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        }
397475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
398dd5a6f95999ec217453fc2d1caa2856e33d122afMangesh Ghiware        public void takePicture2(final ShutterCallback shutter, final PictureCallback raw,
399dd5a6f95999ec217453fc2d1caa2856e33d122afMangesh Ghiware                final PictureCallback postview, final PictureCallback jpeg,
400dd5a6f95999ec217453fc2d1caa2856e33d122afMangesh Ghiware                final int cameraState, final int focusState) {
401dd5a6f95999ec217453fc2d1caa2856e33d122afMangesh Ghiware            mSig.close();
402dd5a6f95999ec217453fc2d1caa2856e33d122afMangesh Ghiware            // Too many parameters, so use post for simplicity
403dd5a6f95999ec217453fc2d1caa2856e33d122afMangesh Ghiware            mCameraHandler.post(new Runnable() {
404dd5a6f95999ec217453fc2d1caa2856e33d122afMangesh Ghiware                @Override
405dd5a6f95999ec217453fc2d1caa2856e33d122afMangesh Ghiware                public void run() {
406dd5a6f95999ec217453fc2d1caa2856e33d122afMangesh Ghiware                    try {
407dd5a6f95999ec217453fc2d1caa2856e33d122afMangesh Ghiware                        mCamera.takePicture(shutter, raw, postview, jpeg);
408dd5a6f95999ec217453fc2d1caa2856e33d122afMangesh Ghiware                    } catch (RuntimeException e) {
409dd5a6f95999ec217453fc2d1caa2856e33d122afMangesh Ghiware                        Log.w(TAG, "take picture failed; cameraState:" + cameraState
410dd5a6f95999ec217453fc2d1caa2856e33d122afMangesh Ghiware                            + ", focusState:" + focusState);
411dd5a6f95999ec217453fc2d1caa2856e33d122afMangesh Ghiware                        throw e;
412dd5a6f95999ec217453fc2d1caa2856e33d122afMangesh Ghiware                    }
413dd5a6f95999ec217453fc2d1caa2856e33d122afMangesh Ghiware                    mSig.open();
414dd5a6f95999ec217453fc2d1caa2856e33d122afMangesh Ghiware                }
415dd5a6f95999ec217453fc2d1caa2856e33d122afMangesh Ghiware            });
416dd5a6f95999ec217453fc2d1caa2856e33d122afMangesh Ghiware            mSig.block();
417dd5a6f95999ec217453fc2d1caa2856e33d122afMangesh Ghiware        }
418dd5a6f95999ec217453fc2d1caa2856e33d122afMangesh Ghiware
419475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        public void setDisplayOrientation(int degrees) {
420475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.close();
421475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mCameraHandler.obtainMessage(SET_DISPLAY_ORIENTATION, degrees, 0)
422475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting                    .sendToTarget();
423475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.block();
424475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        }
425475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
426475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        public void setZoomChangeListener(OnZoomChangeListener listener) {
427475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.close();
428475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mCameraHandler.obtainMessage(SET_ZOOM_CHANGE_LISTENER, listener).sendToTarget();
429475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.block();
430475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        }
431475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
432a9081cd1f9727bb6bdaf406e8ef82bf451002c09Ahbong Chang        @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
433475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        public void setFaceDetectionListener(FaceDetectionListener listener) {
434475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.close();
435475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mCameraHandler.obtainMessage(SET_FACE_DETECTION_LISTENER, listener).sendToTarget();
436475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.block();
437475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        }
438475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
439475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        public void startFaceDetection() {
440475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.close();
441475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mCameraHandler.sendEmptyMessage(START_FACE_DETECTION);
442475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.block();
443475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        }
444475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
445475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        public void stopFaceDetection() {
446475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.close();
447475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mCameraHandler.sendEmptyMessage(STOP_FACE_DETECTION);
448475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.block();
449475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        }
450475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
451475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        public void setErrorCallback(ErrorCallback cb) {
452475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.close();
453475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mCameraHandler.obtainMessage(SET_ERROR_CALLBACK, cb).sendToTarget();
454475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.block();
455475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        }
456475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
457475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        public void setParameters(Parameters params) {
458475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.close();
459475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mCameraHandler.obtainMessage(SET_PARAMETERS, params).sendToTarget();
460475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.block();
461475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        }
462475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting
4638498e7cd3b97fbcf28417c38b46f6ba299a59d08Pin Ting        public void setParametersAsync(Parameters params) {
4648498e7cd3b97fbcf28417c38b46f6ba299a59d08Pin Ting            mCameraHandler.removeMessages(SET_PARAMETERS_ASYNC);
4658498e7cd3b97fbcf28417c38b46f6ba299a59d08Pin Ting            mCameraHandler.obtainMessage(SET_PARAMETERS_ASYNC, params).sendToTarget();
4668498e7cd3b97fbcf28417c38b46f6ba299a59d08Pin Ting        }
4678498e7cd3b97fbcf28417c38b46f6ba299a59d08Pin Ting
468475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        public Parameters getParameters() {
469475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.close();
470475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mCameraHandler.sendEmptyMessage(GET_PARAMETERS);
471475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting            mSig.block();
4723ddad2b0eb468abd8b9a64e302102d9055038db5Wu-cheng Li            Parameters parameters = mParameters;
4733ddad2b0eb468abd8b9a64e302102d9055038db5Wu-cheng Li            mParameters = null;
4743ddad2b0eb468abd8b9a64e302102d9055038db5Wu-cheng Li            return parameters;
475475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting        }
4762921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li
477c0c5d69598061725bd5a4828a87796c25b515b68Wu-cheng Li        public void enableShutterSound(boolean enable) {
478c0c5d69598061725bd5a4828a87796c25b515b68Wu-cheng Li            mSig.close();
479c0c5d69598061725bd5a4828a87796c25b515b68Wu-cheng Li            mCameraHandler.obtainMessage(
480c0c5d69598061725bd5a4828a87796c25b515b68Wu-cheng Li                    ENABLE_SHUTTER_SOUND, (enable ? 1 : 0), 0).sendToTarget();
481c0c5d69598061725bd5a4828a87796c25b515b68Wu-cheng Li            mSig.block();
482c0c5d69598061725bd5a4828a87796c25b515b68Wu-cheng Li        }
483c0c5d69598061725bd5a4828a87796c25b515b68Wu-cheng Li
4842921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li        public void waitForIdle() {
4852921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li            mSig.close();
4862921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li            mCameraHandler.sendEmptyMessage(WAIT_FOR_IDLE);
4872921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li            mSig.block();
4882921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li        }
489475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting    }
4902921239d121f488dd1fa03d6aa510c88c596445dWu-cheng Li}
491