AndroidCameraAgentImpl.java revision 7e6c76ef7faf26aa1060b4abc1c65934b4e45338
1bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong/* 2bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Copyright (C) 2013 The Android Open Source Project 3bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 4bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Licensed under the Apache License, Version 2.0 (the "License"); 5bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * you may not use this file except in compliance with the License. 6bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * You may obtain a copy of the License at 7bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 8bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * http://www.apache.org/licenses/LICENSE-2.0 9bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 10bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Unless required by applicable law or agreed to in writing, software 11bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * distributed under the License is distributed on an "AS IS" BASIS, 12bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * See the License for the specific language governing permissions and 14bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * limitations under the License. 15bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 16bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 17bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongpackage com.android.ex.camera2.portability; 18bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 19bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongimport android.annotation.TargetApi; 20bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongimport android.graphics.SurfaceTexture; 21bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongimport android.hardware.Camera; 22bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongimport android.hardware.Camera.AutoFocusCallback; 23bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongimport android.hardware.Camera.AutoFocusMoveCallback; 24bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongimport android.hardware.Camera.ErrorCallback; 25bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongimport android.hardware.Camera.FaceDetectionListener; 26bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongimport android.hardware.Camera.OnZoomChangeListener; 27bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongimport android.hardware.Camera.Parameters; 28bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongimport android.hardware.Camera.PictureCallback; 29bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongimport android.hardware.Camera.PreviewCallback; 30bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongimport android.hardware.Camera.ShutterCallback; 31bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongimport android.os.Build; 32bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongimport android.os.Handler; 33bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongimport android.os.HandlerThread; 34bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongimport android.os.Looper; 35bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongimport android.os.Message; 36bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongimport android.os.SystemClock; 37bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongimport android.view.SurfaceHolder; 38bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 39bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongimport com.android.ex.camera2.portability.debug.Log; 40bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 41bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongimport java.io.IOException; 42bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongimport java.util.LinkedList; 43bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongimport java.util.Queue; 44bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 45bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong/** 46bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A class to implement {@link CameraManager} of the Android camera framework. 47bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 48bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongclass AndroidCameraManagerImpl implements CameraManager { 49bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final Log.Tag TAG = new Log.Tag("AndroidCamMgrImpl"); 50bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final long CAMERA_OPERATION_TIMEOUT_MS = 2500; 51bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final long MAX_MESSAGE_QUEUE_LENGTH = 256; 52b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong private static final int MAX_HISTORY_SIZE = 400; 53bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 54bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private Parameters mParameters; 55bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private boolean mParametersIsDirty; 56bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 57bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /* Messages used in CameraHandler. */ 58bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong // Camera initialization/finalization 59bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int OPEN_CAMERA = 1; 60bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int RELEASE = 2; 61bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int RECONNECT = 3; 62bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int UNLOCK = 4; 63bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int LOCK = 5; 64bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong // Preview 65bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int SET_PREVIEW_TEXTURE_ASYNC = 101; 66bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int START_PREVIEW_ASYNC = 102; 67bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int STOP_PREVIEW = 103; 68bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int SET_PREVIEW_CALLBACK_WITH_BUFFER = 104; 69bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int ADD_CALLBACK_BUFFER = 105; 70bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int SET_PREVIEW_DISPLAY_ASYNC = 106; 71bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int SET_PREVIEW_CALLBACK = 107; 72bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int SET_ONE_SHOT_PREVIEW_CALLBACK = 108; 73bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong // Parameters 74bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int SET_PARAMETERS = 201; 75bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int GET_PARAMETERS = 202; 76bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int REFRESH_PARAMETERS = 203; 77bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong // Focus, Zoom 78bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int AUTO_FOCUS = 301; 79bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int CANCEL_AUTO_FOCUS = 302; 80bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int SET_AUTO_FOCUS_MOVE_CALLBACK = 303; 81bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int SET_ZOOM_CHANGE_LISTENER = 304; 82bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong // Face detection 83bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int SET_FACE_DETECTION_LISTENER = 461; 84bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int START_FACE_DETECTION = 462; 85bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int STOP_FACE_DETECTION = 463; 86bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int SET_ERROR_CALLBACK = 464; 87bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong // Presentation 88bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int ENABLE_SHUTTER_SOUND = 501; 89bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int SET_DISPLAY_ORIENTATION = 502; 90bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong // Capture 91bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int CAPTURE_PHOTO = 601; 92bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 93bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** Camera states **/ 94bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong // These states are defined bitwise so we can easily to specify a set of 95bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong // states together. 96bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int CAMERA_UNOPENED = 1; 97bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int CAMERA_IDLE = 1 << 1; 98bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int CAMERA_UNLOCKED = 1 << 2; 99bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int CAMERA_CAPTURING = 1 << 3; 100bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final int CAMERA_FOCUSING = 1 << 4; 101bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 102bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraHandler mCameraHandler; 103bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final HandlerThread mCameraHandlerThread; 104bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraStateHolder mCameraState; 105bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final DispatchThread mDispatchThread; 106bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 107bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong // Used to retain a copy of Parameters for setting parameters. 108bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private Parameters mParamsToSet; 109bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 110bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private Handler mCameraExceptionCallbackHandler; 111bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private CameraExceptionCallback mCameraExceptionCallback = 112bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong new CameraExceptionCallback() { 113bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 114bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onCameraException(RuntimeException e) { 115bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong throw e; 116bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 117bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }; 118bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 119bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong AndroidCameraManagerImpl() { 120bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandlerThread = new HandlerThread("Camera Handler Thread"); 121bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandlerThread.start(); 122bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler = new CameraHandler(mCameraHandlerThread.getLooper()); 123bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraExceptionCallbackHandler = mCameraHandler; 124bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraState = new CameraStateHolder(); 125bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread = new DispatchThread(); 126bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.start(); 127bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 128bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 129bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 130bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setCameraDefaultExceptionCallback(CameraExceptionCallback callback, 131bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler) { 132bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong synchronized (mCameraExceptionCallback) { 133bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraExceptionCallback = callback; 134bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraExceptionCallbackHandler = handler; 135bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 136bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 137bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 13860520c4df78e595964605cf8acfa21bbafaeba84Angus Kong @Override 139bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void recycle() { 14060520c4df78e595964605cf8acfa21bbafaeba84Angus Kong closeCamera(null, true); 141bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.end(); 142bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1437e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1447e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong @Override 1457e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong public CameraDeviceInfo getCameraDeviceInfo() { 1467e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return AndroidCameraDeviceInfo.create(); 1477e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1487e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1497e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong private static class AndroidCameraDeviceInfo implements CameraDeviceInfo { 1507e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong private final Camera.CameraInfo[] mCameraInfos; 1517e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong private final int mNumberOfCameras; 1527e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong private final int mFirstBackCameraId; 1537e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong private final int mFirstFrontCameraId; 1547e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1557e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong private AndroidCameraDeviceInfo(Camera.CameraInfo[] info, int numberOfCameras, 1567e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong int firstBackCameraId, int firstFrontCameraId) { 1577e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1587e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong mCameraInfos = info; 1597e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong mNumberOfCameras = numberOfCameras; 1607e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong mFirstBackCameraId = firstBackCameraId; 1617e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong mFirstFrontCameraId = firstFrontCameraId; 1627e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1637e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1647e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong public static AndroidCameraDeviceInfo create() { 1657e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong int numberOfCameras; 1667e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong Camera.CameraInfo[] cameraInfos; 1677e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong try { 1687e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong numberOfCameras = Camera.getNumberOfCameras(); 1697e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong cameraInfos = new Camera.CameraInfo[numberOfCameras]; 1707e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong for (int i = 0; i < numberOfCameras; i++) { 1717e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong cameraInfos[i] = new Camera.CameraInfo(); 1727e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong Camera.getCameraInfo(i, cameraInfos[i]); 1737e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1747e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } catch (RuntimeException ex) { 1757e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return null; 1767e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1777e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1787e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong int firstFront = NO_DEVICE; 1797e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong int firstBack = NO_DEVICE; 1807e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong // Get the first (smallest) back and first front camera id. 1817e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong for (int i = numberOfCameras - 1; i >= 0; i--) { 1827e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong if (cameraInfos[i].facing == Camera.CameraInfo.CAMERA_FACING_BACK) { 1837e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong firstBack = i; 1847e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } else { 1857e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong if (cameraInfos[i].facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 1867e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong firstFront = i; 1877e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1887e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1897e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1907e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1917e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return new AndroidCameraDeviceInfo(cameraInfos, numberOfCameras, firstBack, firstFront); 1927e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1937e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1947e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong @Override 1957e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong public Camera.CameraInfo[] getCameraInfos() { 1967e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return mCameraInfos; 1977e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1987e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1997e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong @Override 2007e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong public int getNumberOfCameras() { 2017e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return mNumberOfCameras; 2027e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 2037e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 2047e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong @Override 2057e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong public int getFirstBackCameraId() { 2067e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return mFirstBackCameraId; 2077e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 2087e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 2097e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong @Override 2107e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong public int getFirstFrontCameraId() { 2117e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return mFirstFrontCameraId; 2127e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 2137e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 214bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 215bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class CameraStateHolder { 216bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private int mState; 217bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 218bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public CameraStateHolder() { 219bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong setState(CAMERA_UNOPENED); 220bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 221bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 222bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public CameraStateHolder(int state) { 223bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong setState(state); 224bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 225bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 226bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public synchronized void setState(int state) { 227bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mState = state; 228bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong this.notifyAll(); 229bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 230bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 231bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public synchronized int getState() { 232bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return mState; 233bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 234bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 235bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private interface ConditionChecker { 236bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 237bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return Whether the condition holds. 238bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 239bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong boolean success(); 240bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 241bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 242bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 243bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A helper method used by {@link #waitToAvoidStates(int)} and 244bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * {@link #waitForStates(int)}. This method will wait until the 245bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * condition is successful. 246bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 247bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param stateChecker The state checker to be used. 248bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param timeoutMs The timeout limit in milliseconds. 249bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return {@code false} if the wait is interrupted or timeout limit is 250bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * reached. 251bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 252bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private boolean waitForCondition(ConditionChecker stateChecker, 253bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong long timeoutMs) { 254bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong long timeBound = SystemClock.uptimeMillis() + timeoutMs; 255bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong synchronized (this) { 256bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong while (!stateChecker.success()) { 257bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 258bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong this.wait(timeoutMs); 259bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (InterruptedException ex) { 260bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (SystemClock.uptimeMillis() > timeBound) { 261bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong // Timeout. 262bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.w(TAG, "Timeout waiting."); 263bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 264bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return false; 265bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 266bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 267bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 268bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return true; 269bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 270bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 271bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 272bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Block the current thread until the state becomes one of the 273bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * specified. 274bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 275bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param states Expected states. 276bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return {@code false} if the wait is interrupted or timeout limit is 277bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * reached. 278bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 279bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public boolean waitForStates(final int states) { 280bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return waitForCondition(new ConditionChecker() { 281bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 282bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public boolean success() { 283bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return (states | mState) == states; 284bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 285bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }, CAMERA_OPERATION_TIMEOUT_MS); 286bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 287bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 288bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 289bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Block the current thread until the state becomes NOT one of the 290bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * specified. 291bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 292bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param states States to avoid. 293bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return {@code false} if the wait is interrupted or timeout limit is 294bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * reached. 295bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 296bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public boolean waitToAvoidStates(final int states) { 297bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return waitForCondition(new ConditionChecker() { 298bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 299bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public boolean success() { 300bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return (states & mState) == 0; 301bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 302bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }, CAMERA_OPERATION_TIMEOUT_MS); 303bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 304bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 305bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 306bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 307bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * The handler on which the actual camera operations happen. 308bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 309bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private class CameraHandler extends Handler { 310b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong 311bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private Camera mCamera; 31260520c4df78e595964605cf8acfa21bbafaeba84Angus Kong private int mCameraId; 313bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 314742beb4e81cfcdfa9d4f7d3252be7be797a1e462Sascha Haeberling private final LinkedList<Integer> mMsgHistory; 315b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong 316bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private class CaptureCallbacks { 317bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public final ShutterCallback mShutter; 318bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public final PictureCallback mRaw; 319bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public final PictureCallback mPostView; 320bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public final PictureCallback mJpeg; 321bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 322bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong CaptureCallbacks(ShutterCallback shutter, PictureCallback raw, PictureCallback postView, 323bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong PictureCallback jpeg) { 324bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mShutter = shutter; 325bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mRaw = raw; 326bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mPostView = postView; 327bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mJpeg = jpeg; 328bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 329bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 330bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 331bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong CameraHandler(Looper looper) { 332bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong super(looper); 333b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong mMsgHistory = new LinkedList<Integer>(); 334b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong // We add a -1 at the beginning to mark the very beginning of the 335b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong // history. 336b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong mMsgHistory.offerLast(-1); 337b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong } 338b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong 339b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong private String generateHistoryString(int cameraId) { 340b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong String info = new String("HIST"); 341b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong info += "_ID" + cameraId; 342b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong for (Integer msg : mMsgHistory) { 343b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong info = info + '_' + msg.toString(); 344b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong } 345b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong info += "_HEND"; 346b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong return info; 347bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 348bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 349bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void startFaceDetection() { 350bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.startFaceDetection(); 351bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 352bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 353bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void stopFaceDetection() { 354bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.stopFaceDetection(); 355bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 356bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 357bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void setFaceDetectionListener(FaceDetectionListener listener) { 358bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setFaceDetectionListener(listener); 359bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 360bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 361bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void setPreviewTexture(Object surfaceTexture) { 362bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 363bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setPreviewTexture((SurfaceTexture) surfaceTexture); 364bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (IOException e) { 365bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.e(TAG, "Could not set preview texture", e); 366bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 367bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 368bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 369bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) 370bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void enableShutterSound(boolean enable) { 371bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.enableShutterSound(enable); 372bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 373bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 374bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 375bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void setAutoFocusMoveCallback( 376bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong android.hardware.Camera camera, Object cb) { 377bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 378bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong camera.setAutoFocusMoveCallback((AutoFocusMoveCallback) cb); 379bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (RuntimeException ex) { 380bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.w(TAG, ex.getMessage()); 381bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 382bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 383bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 384bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void capture(final CaptureCallbacks cb) { 385bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 386bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.takePicture(cb.mShutter, cb.mRaw, cb.mPostView, cb.mJpeg); 387bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (RuntimeException e) { 388bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong // TODO: output camera state and focus state for debugging. 389bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.e(TAG, "take picture failed."); 390bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong throw e; 391bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 392bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 393bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 394bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void requestTakePicture( 395bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final ShutterCallback shutter, 396bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final PictureCallback raw, 397bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final PictureCallback postView, 398bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final PictureCallback jpeg) { 399bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CaptureCallbacks callbacks = new CaptureCallbacks(shutter, raw, postView, jpeg); 400bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong obtainMessage(CAPTURE_PHOTO, callbacks).sendToTarget(); 401bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 402bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 403bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 404bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * This method does not deal with the API level check. Everyone should 405bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * check first for supported operations before sending message to this handler. 406bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 407bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 408bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void handleMessage(final Message msg) { 409b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong mMsgHistory.offerLast(msg.what); 410b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong while (mMsgHistory.size() > MAX_HISTORY_SIZE) { 411b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong mMsgHistory.pollFirst(); 412b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong } 413bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 414bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong switch (msg.what) { 415bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong case OPEN_CAMERA: { 416bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraOpenCallback openCallback = (CameraOpenCallback) msg.obj; 417bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final int cameraId = msg.arg1; 418bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (mCameraState.getState() != CAMERA_UNOPENED) { 41960520c4df78e595964605cf8acfa21bbafaeba84Angus Kong openCallback.onDeviceOpenedAlready(cameraId, generateHistoryString(cameraId)); 420bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 421bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 422bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 423bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = android.hardware.Camera.open(cameraId); 424bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (mCamera != null) { 42560520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mCameraId = cameraId; 426bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mParametersIsDirty = true; 427bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 428bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong // Get a instance of Camera.Parameters for later use. 429742beb4e81cfcdfa9d4f7d3252be7be797a1e462Sascha Haeberling mParamsToSet = mCamera.getParameters(); 430bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 431bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraState.setState(CAMERA_IDLE); 432bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (openCallback != null) { 433bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong openCallback.onCameraOpened( 434c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong new AndroidCameraProxyImpl(cameraId, mCamera, 435c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong new AndroidCameraCapabilities(mParamsToSet)) 436c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong ); 437bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 438bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } else { 439bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (openCallback != null) { 440b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong openCallback.onDeviceOpenFailure(cameraId, generateHistoryString(cameraId)); 441bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 442bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 443bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 444bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 445bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 446bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong case RELEASE: { 44760520c4df78e595964605cf8acfa21bbafaeba84Angus Kong if (mCamera != null) { 44860520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mCamera.release(); 44960520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mCameraState.setState(CAMERA_UNOPENED); 45060520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mCamera = null; 45160520c4df78e595964605cf8acfa21bbafaeba84Angus Kong } else { 45260520c4df78e595964605cf8acfa21bbafaeba84Angus Kong Log.w(TAG, "Releasing camera without any camera opened."); 45360520c4df78e595964605cf8acfa21bbafaeba84Angus Kong } 454bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 455bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 456bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 457bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong case RECONNECT: { 458bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraOpenCallbackForward cbForward = 459bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong (CameraOpenCallbackForward) msg.obj; 460bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final int cameraId = msg.arg1; 461bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 462bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.reconnect(); 463bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (IOException ex) { 464bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (cbForward != null) { 46560520c4df78e595964605cf8acfa21bbafaeba84Angus Kong cbForward.onReconnectionFailure(AndroidCameraManagerImpl.this, 46660520c4df78e595964605cf8acfa21bbafaeba84Angus Kong generateHistoryString(mCameraId)); 467bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 468bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 469bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 470bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 471bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraState.setState(CAMERA_IDLE); 472bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (cbForward != null) { 473c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong cbForward.onCameraOpened(new AndroidCameraProxyImpl(cameraId, mCamera, 474c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong new AndroidCameraCapabilities(mParamsToSet))); 475bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 476bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 477bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 478bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 479bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong case UNLOCK: { 480bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.unlock(); 481bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraState.setState(CAMERA_UNLOCKED); 482bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 483bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 484bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 485bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong case LOCK: { 486bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.lock(); 487bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraState.setState(CAMERA_IDLE); 488bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 489bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 490bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 491bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong case SET_PREVIEW_TEXTURE_ASYNC: { 492bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong setPreviewTexture(msg.obj); 493bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 494bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 495bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 496bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong case SET_PREVIEW_DISPLAY_ASYNC: { 497bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 498bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setPreviewDisplay((SurfaceHolder) msg.obj); 499bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (IOException e) { 500bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong throw new RuntimeException(e); 501bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 502bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 503bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 504bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 505bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong case START_PREVIEW_ASYNC: { 506bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraStartPreviewCallbackForward cbForward = 507bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong (CameraStartPreviewCallbackForward) msg.obj; 508bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.startPreview(); 509bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (cbForward != null) { 510bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong cbForward.onPreviewStarted(); 511bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 512bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 513bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 514bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 515bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong case STOP_PREVIEW: { 516bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.stopPreview(); 517bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 518bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 519bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 520bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong case SET_PREVIEW_CALLBACK_WITH_BUFFER: { 521bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setPreviewCallbackWithBuffer((PreviewCallback) msg.obj); 522bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 523bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 524bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 525bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong case SET_ONE_SHOT_PREVIEW_CALLBACK: { 526bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setOneShotPreviewCallback((PreviewCallback) msg.obj); 527bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 528bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 529bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 530bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong case ADD_CALLBACK_BUFFER: { 531bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.addCallbackBuffer((byte[]) msg.obj); 532bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 533bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 534bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 535bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong case AUTO_FOCUS: { 536bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraState.setState(CAMERA_FOCUSING); 537bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.autoFocus((AutoFocusCallback) msg.obj); 538bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 539bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 540bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 541bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong case CANCEL_AUTO_FOCUS: { 542bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.cancelAutoFocus(); 543bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraState.setState(CAMERA_IDLE); 544bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 545bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 546bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 547bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong case SET_AUTO_FOCUS_MOVE_CALLBACK: { 548bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong setAutoFocusMoveCallback(mCamera, msg.obj); 549bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 550bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 551bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 552bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong case SET_DISPLAY_ORIENTATION: { 553bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setDisplayOrientation(msg.arg1); 554bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 555bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 556bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 557bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong case SET_ZOOM_CHANGE_LISTENER: { 558bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setZoomChangeListener((OnZoomChangeListener) msg.obj); 559bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 560bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 561bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 562bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong case SET_FACE_DETECTION_LISTENER: { 563bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong setFaceDetectionListener((FaceDetectionListener) msg.obj); 564bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 565bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 566bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 567bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong case START_FACE_DETECTION: { 568bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong startFaceDetection(); 569bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 570bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 571bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 572bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong case STOP_FACE_DETECTION: { 573bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong stopFaceDetection(); 574bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 575bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 576bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 577bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong case SET_ERROR_CALLBACK: { 578bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setErrorCallback((ErrorCallback) msg.obj); 579bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 580bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 581bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 582bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong case SET_PARAMETERS: { 583bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mParametersIsDirty = true; 584bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mParamsToSet.unflatten((String) msg.obj); 585bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setParameters(mParamsToSet); 586bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 587bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 588bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 589bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong case GET_PARAMETERS: { 590bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (mParametersIsDirty) { 591bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mParameters = mCamera.getParameters(); 592bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mParametersIsDirty = false; 593bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 594bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 595bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 596bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 597bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong case SET_PREVIEW_CALLBACK: { 598bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setPreviewCallback((PreviewCallback) msg.obj); 599bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 600bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 601bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 602bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong case ENABLE_SHUTTER_SOUND: { 603bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong enableShutterSound((msg.arg1 == 1) ? true : false); 604bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 605bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 606bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 607bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong case REFRESH_PARAMETERS: { 608bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mParametersIsDirty = true; 609bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 610bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 611bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 612bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong case CAPTURE_PHOTO: { 613bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraState.setState(CAMERA_CAPTURING); 614bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong capture((CaptureCallbacks) msg.obj); 615bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 616bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 617bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 618bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong default: { 619bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong throw new RuntimeException("Invalid CameraProxy message=" + msg.what); 620bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 621bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 622bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (final RuntimeException e) { 623bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (msg.what != RELEASE && mCamera != null) { 624bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 625bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.release(); 626bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraState.setState(CAMERA_UNOPENED); 627bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (Exception ex) { 628bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.e(TAG, "Fail to release the camera."); 629bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 630bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = null; 631bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } else { 632bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (mCamera == null) { 633bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (msg.what == OPEN_CAMERA) { 634b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong final int cameraId = msg.arg1; 635bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (msg.obj != null) { 636b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong ((CameraOpenCallback) msg.obj).onDeviceOpenFailure( 637b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong msg.arg1, generateHistoryString(cameraId)); 638bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 639bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } else { 640bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.w(TAG, "Cannot handle message " + msg.what + ", mCamera is null."); 641bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 642bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return; 643bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 644bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 645bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong synchronized (mCameraExceptionCallback) { 646bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraExceptionCallbackHandler.post(new Runnable() { 647bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 648bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 649bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraExceptionCallback.onCameraException(e); 650bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 651bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 652bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 653bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 654bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 655bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 656bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 657bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private class DispatchThread extends Thread { 658bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 659bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Queue<Runnable> mJobQueue; 660bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private Boolean mIsEnded; 661bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 662bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public DispatchThread() { 663bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong super("Camera Job Dispatch Thread"); 664bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mJobQueue = new LinkedList<Runnable>(); 665bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mIsEnded = new Boolean(false); 666bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 667bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 668bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 669bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Queues up the job. 670bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 671bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param job The job to run. 672bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 673bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void runJob(Runnable job) { 674bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (isEnded()) { 675bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong throw new IllegalStateException( 676bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong "Trying to run job on interrupted dispatcher thread"); 677bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 678bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong synchronized (mJobQueue) { 679bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (mJobQueue.size() == MAX_MESSAGE_QUEUE_LENGTH) { 680bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong throw new RuntimeException("Camera master thread job queue full"); 681bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 682bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 683bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mJobQueue.add(job); 684bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mJobQueue.notifyAll(); 685bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 686bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 687bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 688bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 689bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Queues up the job and wait for it to be done. 690bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 691bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param job The job to run. 692bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param timeoutMs Timeout limit in milliseconds. 693bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param jobMsg The message to log when the job runs timeout. 694bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return Whether the job finishes before timeout. 695bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 696bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public boolean runJobSync(final Runnable job, Object waitLock, long timeoutMs, String jobMsg) { 697bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong synchronized (waitLock) { 698bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong long timeoutBound = SystemClock.uptimeMillis() + timeoutMs; 699bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 700bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong runJob(job); 701bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong waitLock.wait(); 702bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (InterruptedException ex) { 70360520c4df78e595964605cf8acfa21bbafaeba84Angus Kong Log.w(TAG, "Job interrupted"); 704bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (SystemClock.uptimeMillis() > timeoutBound) { 705bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong // Timeout. 706bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.w(TAG, "Timeout waiting camera operation:" + jobMsg); 707bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 708bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return false; 709bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 710bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 711bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return true; 712bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 713bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 714bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 715bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Gracefully ends this thread. Will stop after all jobs are processed. 716bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 717bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void end() { 718bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong synchronized (mIsEnded) { 719bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mIsEnded = true; 720bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 721bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong synchronized(mJobQueue) { 722bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mJobQueue.notifyAll(); 723bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 724bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 725bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 726bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private boolean isEnded() { 727bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong synchronized (mIsEnded) { 728bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return mIsEnded; 729bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 730bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 731bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 732bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 733bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 734bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong while(true) { 735bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Runnable job = null; 736bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong synchronized (mJobQueue) { 737bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong while (mJobQueue.size() == 0 && !isEnded()) { 738bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 739bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mJobQueue.wait(); 740bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (InterruptedException ex) { 74160520c4df78e595964605cf8acfa21bbafaeba84Angus Kong Log.w(TAG, "Dispatcher thread wait() interrupted, exiting"); 742bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 743bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 744bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 745bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 746bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong job = mJobQueue.poll(); 747bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 748bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 749bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (job == null) { 750bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong // mJobQueue.poll() returning null means wait() is 751bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong // interrupted and the queue is empty. 752bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (isEnded()) { 753bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 754bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 755bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong continue; 756bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 757bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 758bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong job.run(); 759bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 760bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong synchronized (DispatchThread.this) { 761bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.post(new Runnable() { 762bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 763bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 764bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong synchronized (DispatchThread.this) { 765bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong DispatchThread.this.notifyAll(); 766bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 767bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 768bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 769bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 770bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong DispatchThread.this.wait(); 771bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (InterruptedException ex) { 772bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong // TODO: do something here. 773bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 774bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 775bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 776bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandlerThread.quitSafely(); 777bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 778bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 779bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 780bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 78160520c4df78e595964605cf8acfa21bbafaeba84Angus Kong public void openCamera(final Handler handler, final int cameraId, 78260520c4df78e595964605cf8acfa21bbafaeba84Angus Kong final CameraOpenCallback callback) { 783bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 784bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 785bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 786bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.obtainMessage(OPEN_CAMERA, cameraId, 0, 787bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong CameraOpenCallbackForward.getNewInstance(handler, callback)).sendToTarget(); 788bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 789bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 790bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 791bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 79260520c4df78e595964605cf8acfa21bbafaeba84Angus Kong @Override 79360520c4df78e595964605cf8acfa21bbafaeba84Angus Kong public void closeCamera(CameraProxy camera, boolean synced) { 79460520c4df78e595964605cf8acfa21bbafaeba84Angus Kong if (synced) { 79560520c4df78e595964605cf8acfa21bbafaeba84Angus Kong final WaitDoneBundle bundle = new WaitDoneBundle(); 79660520c4df78e595964605cf8acfa21bbafaeba84Angus Kong 79760520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mDispatchThread.runJobSync(new Runnable() { 79860520c4df78e595964605cf8acfa21bbafaeba84Angus Kong @Override 79960520c4df78e595964605cf8acfa21bbafaeba84Angus Kong public void run() { 80060520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mCameraHandler.obtainMessage(RELEASE).sendToTarget(); 80160520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mCameraHandler.post(bundle.mUnlockRunnable); 80260520c4df78e595964605cf8acfa21bbafaeba84Angus Kong } 80360520c4df78e595964605cf8acfa21bbafaeba84Angus Kong }, bundle.mWaitLock, CAMERA_OPERATION_TIMEOUT_MS, "camera release"); 80460520c4df78e595964605cf8acfa21bbafaeba84Angus Kong } else { 80560520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mDispatchThread.runJob(new Runnable() { 80660520c4df78e595964605cf8acfa21bbafaeba84Angus Kong @Override 80760520c4df78e595964605cf8acfa21bbafaeba84Angus Kong public void run() { 80860520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mCameraHandler.removeCallbacksAndMessages(null); 80960520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mCameraHandler.obtainMessage(RELEASE).sendToTarget(); 81060520c4df78e595964605cf8acfa21bbafaeba84Angus Kong } 81160520c4df78e595964605cf8acfa21bbafaeba84Angus Kong }); 81260520c4df78e595964605cf8acfa21bbafaeba84Angus Kong } 81360520c4df78e595964605cf8acfa21bbafaeba84Angus Kong } 81460520c4df78e595964605cf8acfa21bbafaeba84Angus Kong 815bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 816bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A class which implements {@link CameraManager.CameraProxy} and 817bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * camera handler thread. 818bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 819bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private class AndroidCameraProxyImpl implements CameraManager.CameraProxy { 820bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final int mCameraId; 821bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /* TODO: remove this Camera instance. */ 822bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Camera mCamera; 823c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong private final AndroidCameraCapabilities mCapabilities; 824bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 825c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong private AndroidCameraProxyImpl(int cameraId, Camera camera, 826c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong AndroidCameraCapabilities capabilities) { 827bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 828bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraId = cameraId; 829c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong mCapabilities = capabilities; 830bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 831bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 832bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 833bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public android.hardware.Camera getCamera() { 834bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return mCamera; 835bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 836bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 837bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 838bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public int getCameraId() { 839bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return mCameraId; 840bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 841bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 842bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 843c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong public CameraCapabilities getCapabilities() { 844c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong return new AndroidCameraCapabilities(mCapabilities); 845c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong } 846c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong 847c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong @Override 848bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void reconnect(final Handler handler, final CameraOpenCallback cb) { 849bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 850bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 851bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 852bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.obtainMessage(RECONNECT, mCameraId, 0, 853bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong CameraOpenCallbackForward.getNewInstance(handler, cb)).sendToTarget(); 854bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 855bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 856bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 857bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 858bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 859bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void unlock() { 860bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final WaitDoneBundle bundle = new WaitDoneBundle(); 861bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJobSync(new Runnable() { 862bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 863bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 864bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.sendEmptyMessage(UNLOCK); 865bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.post(bundle.mUnlockRunnable); 866bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 867bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }, bundle.mWaitLock, CAMERA_OPERATION_TIMEOUT_MS, "camera unlock"); 868bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 869bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 870bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 871bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void lock() { 872bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 873bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 874bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 875bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.sendEmptyMessage(LOCK); 876bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 877bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 878bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 879bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 880bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 881bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setPreviewTexture(final SurfaceTexture surfaceTexture) { 882bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 883bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 884bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 885bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.obtainMessage(SET_PREVIEW_TEXTURE_ASYNC, surfaceTexture) 886bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 887bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 888bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 889bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 890bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 891bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 892bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setPreviewTextureSync(final SurfaceTexture surfaceTexture) { 893bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final WaitDoneBundle bundle = new WaitDoneBundle(); 894bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJobSync(new Runnable() { 895bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 896bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 897bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.obtainMessage(SET_PREVIEW_TEXTURE_ASYNC, surfaceTexture) 898bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 899bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.post(bundle.mUnlockRunnable); 900bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 901bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }, bundle.mWaitLock, CAMERA_OPERATION_TIMEOUT_MS, "set preview texture"); 902bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 903bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 904bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 905bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setPreviewDisplay(final SurfaceHolder surfaceHolder) { 906bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 907bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 908bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 909bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.obtainMessage(SET_PREVIEW_DISPLAY_ASYNC, surfaceHolder) 910bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 911bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 912bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 913bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 914bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 915bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 916bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void startPreview() { 917bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 918bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 919bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 920bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.obtainMessage(START_PREVIEW_ASYNC, null).sendToTarget(); 921bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 922bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 923bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 924bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 925bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 926bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void startPreviewWithCallback(final Handler handler, 927bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraStartPreviewCallback cb) { 928bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 929bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 930bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 931bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.obtainMessage(START_PREVIEW_ASYNC, 932bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong CameraStartPreviewCallbackForward.getNewInstance(handler, cb)).sendToTarget(); 933bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 934bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 935bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 936bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 937bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 938bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void stopPreview() { 939bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final WaitDoneBundle bundle = new WaitDoneBundle(); 940bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJobSync(new Runnable() { 941bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 942bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 943bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.sendEmptyMessage(STOP_PREVIEW); 944bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.post(bundle.mUnlockRunnable); 945bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 946bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }, bundle.mWaitLock, CAMERA_OPERATION_TIMEOUT_MS, "stop preview"); 947bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 948bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 949bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 950bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setPreviewDataCallback( 951bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final Handler handler, final CameraPreviewDataCallback cb) { 952bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 953bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 954bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 955bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.obtainMessage(SET_PREVIEW_CALLBACK, PreviewCallbackForward 956bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .getNewInstance(handler, AndroidCameraProxyImpl.this, cb)) 957bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 958bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 959bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 960bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 961bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 962bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setOneShotPreviewCallback(final Handler handler, 963bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraPreviewDataCallback cb) { 964bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 965bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 966bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 967bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.obtainMessage(SET_ONE_SHOT_PREVIEW_CALLBACK, 968bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong PreviewCallbackForward 969bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .getNewInstance(handler, AndroidCameraProxyImpl.this, cb)) 970bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 971bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 972bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 973bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 974bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 975bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 976bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setPreviewDataCallbackWithBuffer( 977bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final Handler handler, final CameraPreviewDataCallback cb) { 978bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 979bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 980bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 981bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.obtainMessage(SET_PREVIEW_CALLBACK_WITH_BUFFER, 982bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong PreviewCallbackForward 983bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .getNewInstance(handler, AndroidCameraProxyImpl.this, cb)) 984bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 985bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 986bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 987bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 988bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 989bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 990bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void addCallbackBuffer(final byte[] callbackBuffer) { 991bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 992bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 993bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 994bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.obtainMessage(ADD_CALLBACK_BUFFER, callbackBuffer) 995bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 996bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 997bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 998bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 999bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1000bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1001bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void autoFocus(final Handler handler, final CameraAFCallback cb) { 1002bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final AutoFocusCallback afCallback = new AutoFocusCallback() { 1003bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1004bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onAutoFocus(final boolean b, Camera camera) { 1005bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (mCameraState.getState() != CAMERA_FOCUSING) { 1006bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.w(TAG, "onAutoFocus callback returning when not focusing"); 1007bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } else { 1008bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraState.setState(CAMERA_IDLE); 1009bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1010bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong handler.post(new Runnable() { 1011bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1012bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1013bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong cb.onAutoFocus(b, AndroidCameraProxyImpl.this); 1014bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1015bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1016bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1017bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }; 1018bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 1019bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1020bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1021bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraState.waitForStates(CAMERA_IDLE); 1022bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.obtainMessage(AUTO_FOCUS, afCallback).sendToTarget(); 1023bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1024bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1025bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1026bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1027bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1028bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void cancelAutoFocus() { 1029bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 1030bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1031bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1032bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.removeMessages(AUTO_FOCUS); 1033bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.sendEmptyMessage(CANCEL_AUTO_FOCUS); 1034bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1035bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1036bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1037bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1038bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 1039bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1040bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setAutoFocusMoveCallback( 1041bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final Handler handler, final CameraAFMoveCallback cb) { 1042bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 1043bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1044bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1045bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.obtainMessage(SET_AUTO_FOCUS_MOVE_CALLBACK, AFMoveCallbackForward 1046bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .getNewInstance(handler, AndroidCameraProxyImpl.this, cb)) 1047bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 1048bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1049bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1050bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1051bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1052bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1053bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void takePicture( 1054bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final Handler handler, final CameraShutterCallback shutter, 1055bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraPictureCallback raw, final CameraPictureCallback post, 1056bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraPictureCallback jpeg) { 1057bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final PictureCallback jpegCallback = new PictureCallback() { 1058bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1059bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onPictureTaken(final byte[] data, Camera camera) { 1060bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (mCameraState.getState() != CAMERA_CAPTURING) { 106160520c4df78e595964605cf8acfa21bbafaeba84Angus Kong Log.w(TAG, "picture callback returning when not capturing"); 1062bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } else { 1063bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraState.setState(CAMERA_IDLE); 1064bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1065bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong handler.post(new Runnable() { 1066bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1067bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1068bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong jpeg.onPictureTaken(data, AndroidCameraProxyImpl.this); 1069bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1070bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1071bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1072bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }; 1073bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1074bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 1075bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1076bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1077d3865a20b022f6d54fe7ac052768a7ff0710017fDoris Liu mCameraState.waitForStates(CAMERA_IDLE | CAMERA_UNLOCKED); 1078bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.requestTakePicture(ShutterCallbackForward 1079bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .getNewInstance(handler, AndroidCameraProxyImpl.this, shutter), 1080bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong PictureCallbackForward 1081bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .getNewInstance(handler, AndroidCameraProxyImpl.this, raw), 1082bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong PictureCallbackForward 1083bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .getNewInstance(handler, AndroidCameraProxyImpl.this, post), 1084bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong jpegCallback); 1085bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1086bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1087bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1088bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1089bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1090bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setDisplayOrientation(final int degrees) { 1091bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 1092bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1093bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1094bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.obtainMessage(SET_DISPLAY_ORIENTATION, degrees, 0) 1095bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 1096bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1097bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1098bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1099bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1100bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1101bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setZoomChangeListener(final OnZoomChangeListener listener) { 1102bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 1103bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1104bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1105bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.obtainMessage(SET_ZOOM_CHANGE_LISTENER, listener).sendToTarget(); 1106bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1107bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1108bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1109bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1110bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1111bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setFaceDetectionCallback(final Handler handler, 1112bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraFaceDetectionCallback cb) { 1113bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 1114bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1115bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1116bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.obtainMessage(SET_FACE_DETECTION_LISTENER, 1117bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong FaceDetectionCallbackForward 1118bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .getNewInstance(handler, AndroidCameraProxyImpl.this, cb)) 1119bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 1120bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1121bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1122bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1123bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1124bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1125bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void startFaceDetection() { 1126bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 1127bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1128bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1129bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.sendEmptyMessage(START_FACE_DETECTION); 1130bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1131bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1132bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1133bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1134bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1135bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void stopFaceDetection() { 1136bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 1137bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1138bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1139bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.sendEmptyMessage(STOP_FACE_DETECTION); 1140bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1141bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1142bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1143bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1144bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1145bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setErrorCallback(final Handler handler, final CameraErrorCallback cb) { 1146bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 1147bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1148bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1149bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.obtainMessage(SET_ERROR_CALLBACK, ErrorCallbackForward 1150bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .getNewInstance(handler, AndroidCameraProxyImpl.this, cb) 1151bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong ).sendToTarget(); 1152bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1153bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1154bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1155bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1156bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1157bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setParameters(final Parameters params) { 1158bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (params == null) { 1159bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.v(TAG, "null parameters in setParameters()"); 1160bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return; 1161bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1162bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final String flattenedParameters = params.flatten(); 1163bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 1164bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1165bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1166bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraState.waitForStates(CAMERA_IDLE | CAMERA_UNLOCKED); 1167bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.obtainMessage(SET_PARAMETERS, flattenedParameters).sendToTarget(); 1168bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1169bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1170bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1171bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1172bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1173bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public Parameters getParameters() { 1174bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final WaitDoneBundle bundle = new WaitDoneBundle(); 1175bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJobSync(new Runnable() { 1176bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1177bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1178bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.sendEmptyMessage(GET_PARAMETERS); 1179bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.post(bundle.mUnlockRunnable); 1180bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1181bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }, bundle.mWaitLock, CAMERA_OPERATION_TIMEOUT_MS, "get parameters"); 1182bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return mParameters; 1183bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1184bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1185bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1186bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void refreshParameters() { 1187bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 1188bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1189bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1190bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.sendEmptyMessage(REFRESH_PARAMETERS); 1191bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1192bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1193bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1194bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1195bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1196bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void enableShutterSound(final boolean enable) { 1197bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 1198bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1199bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1200bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.obtainMessage(ENABLE_SHUTTER_SOUND, (enable ? 1 : 0), 0) 1201bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 1202bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1203bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1204bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1205bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1206bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1207bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class WaitDoneBundle { 1208bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public Runnable mUnlockRunnable; 1209bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Object mWaitLock; 1210bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1211bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong WaitDoneBundle() { 1212bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mWaitLock = new Object(); 1213bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mUnlockRunnable = new Runnable() { 1214bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1215bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1216bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong synchronized (mWaitLock) { 1217bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mWaitLock.notifyAll(); 1218bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1219bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1220bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }; 1221bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1222bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1223bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1224bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1225bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A helper class to forward AutoFocusCallback to another thread. 1226bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1227bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class AFCallbackForward implements AutoFocusCallback { 1228bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1229bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1230bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraAFCallback mCallback; 1231bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1232bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1233bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link AFCallbackForward}. 1234bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1235bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1236bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1237bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1238bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link AFCallbackForward}, 1239bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameter is null. 1240bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1241bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static AFCallbackForward getNewInstance( 1242bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraAFCallback cb) { 1243bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1244bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1245bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1246bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new AFCallbackForward(handler, camera, cb); 1247bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1248bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1249bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private AFCallbackForward( 1250bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraAFCallback cb) { 1251bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1252bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1253bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1254bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1255bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1256bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1257bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onAutoFocus(final boolean b, Camera camera) { 1258bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1259bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1260bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1261bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onAutoFocus(b, mCamera); 1262bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1263bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1264bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1265bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1266bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1267bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1268bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A helper class to forward ErrorCallback to another thread. 1269bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1270bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class ErrorCallbackForward implements Camera.ErrorCallback { 1271bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1272bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1273bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraErrorCallback mCallback; 1274bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1275bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1276bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link AFCallbackForward}. 1277bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1278bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1279bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1280bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1281bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link AFCallbackForward}, 1282bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameter is null. 1283bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1284bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static ErrorCallbackForward getNewInstance( 1285bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraErrorCallback cb) { 1286bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1287bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1288bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1289bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new ErrorCallbackForward(handler, camera, cb); 1290bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1291bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1292bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private ErrorCallbackForward( 1293bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraErrorCallback cb) { 1294bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1295bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1296bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1297bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1298bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1299bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1300bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onError(final int error, Camera camera) { 1301bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1302bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1303bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1304bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onError(error, mCamera); 1305bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1306bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1307bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1308bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1309bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1310bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** A helper class to forward AutoFocusMoveCallback to another thread. */ 1311bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 1312bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class AFMoveCallbackForward implements AutoFocusMoveCallback { 1313bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1314bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraAFMoveCallback mCallback; 1315bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1316bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1317bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1318bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link AFMoveCallbackForward}. 1319bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1320bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1321bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1322bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1323bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link AFMoveCallbackForward}, 1324bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameter is null. 1325bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1326bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static AFMoveCallbackForward getNewInstance( 1327bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraAFMoveCallback cb) { 1328bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1329bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1330bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1331bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new AFMoveCallbackForward(handler, camera, cb); 1332bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1333bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1334bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private AFMoveCallbackForward( 1335bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraAFMoveCallback cb) { 1336bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1337bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1338bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1339bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1340bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1341bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1342bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onAutoFocusMoving( 1343bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final boolean moving, android.hardware.Camera camera) { 1344bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1345bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1346bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1347bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onAutoFocusMoving(moving, mCamera); 1348bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1349bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1350bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1351bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1352bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1353bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1354bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A helper class to forward ShutterCallback to to another thread. 1355bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1356bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class ShutterCallbackForward implements ShutterCallback { 1357bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1358bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraShutterCallback mCallback; 1359bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1360bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1361bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1362bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link ShutterCallbackForward}. 1363bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1364bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1365bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1366bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1367bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link ShutterCallbackForward}, 1368bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameter is null. 1369bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1370bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static ShutterCallbackForward getNewInstance( 1371bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraShutterCallback cb) { 1372bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1373bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1374bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1375bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new ShutterCallbackForward(handler, camera, cb); 1376bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1377bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1378bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private ShutterCallbackForward( 1379bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraShutterCallback cb) { 1380bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1381bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1382bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1383bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1384bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1385bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1386bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onShutter() { 1387bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1388bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1389bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1390bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onShutter(mCamera); 1391bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1392bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1393bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1394bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1395bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1396bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1397bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A helper class to forward PictureCallback to another thread. 1398bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1399bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class PictureCallbackForward implements PictureCallback { 1400bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1401bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraPictureCallback mCallback; 1402bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1403bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1404bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1405bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link PictureCallbackForward}. 1406bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1407bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1408bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1409bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1410bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link PictureCallbackForward}, 1411bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameters is null. 1412bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1413bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static PictureCallbackForward getNewInstance( 1414bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraPictureCallback cb) { 1415bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1416bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1417bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1418bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new PictureCallbackForward(handler, camera, cb); 1419bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1420bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1421bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private PictureCallbackForward( 1422bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraPictureCallback cb) { 1423bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1424bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1425bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1426bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1427bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1428bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1429bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onPictureTaken( 1430bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final byte[] data, android.hardware.Camera camera) { 1431bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1432bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1433bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1434bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onPictureTaken(data, mCamera); 1435bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1436bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1437bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1438bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1439bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1440bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1441bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A helper class to forward PreviewCallback to another thread. 1442bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1443bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class PreviewCallbackForward implements PreviewCallback { 1444bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1445bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraPreviewDataCallback mCallback; 1446bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1447bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1448bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1449bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link PreviewCallbackForward}. 1450bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1451bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1452bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1453bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1454bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link PreviewCallbackForward}, 1455bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameters is null. 1456bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1457bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static PreviewCallbackForward getNewInstance( 1458bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraPreviewDataCallback cb) { 1459bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1460bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1461bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1462bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new PreviewCallbackForward(handler, camera, cb); 1463bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1464bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1465bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private PreviewCallbackForward( 1466bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraPreviewDataCallback cb) { 1467bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1468bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1469bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1470bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1471bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1472bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1473bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onPreviewFrame( 1474bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final byte[] data, android.hardware.Camera camera) { 1475bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1476bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1477bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1478bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onPreviewFrame(data, mCamera); 1479bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1480bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1481bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1482bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1483bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1484bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class FaceDetectionCallbackForward implements FaceDetectionListener { 1485bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1486bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraFaceDetectionCallback mCallback; 1487bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1488bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1489bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1490bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link FaceDetectionCallbackForward}. 1491bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1492bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1493bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1494bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1495bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link FaceDetectionCallbackForward}, 1496bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameter is null. 1497bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1498bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static FaceDetectionCallbackForward getNewInstance( 1499bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraFaceDetectionCallback cb) { 1500bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1501bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1502bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1503bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new FaceDetectionCallbackForward(handler, camera, cb); 1504bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1505bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1506bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private FaceDetectionCallbackForward( 1507bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraFaceDetectionCallback cb) { 1508bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1509bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1510bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1511bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1512bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1513bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1514bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onFaceDetection( 1515bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final Camera.Face[] faces, Camera camera) { 1516bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1517bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1518bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1519bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onFaceDetection(faces, mCamera); 1520bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1521bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1522bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1523bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1524bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1525bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1526bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A callback helps to invoke the original callback on another 1527bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * {@link android.os.Handler}. 1528bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1529bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class CameraOpenCallbackForward implements CameraOpenCallback { 1530bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1531bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraOpenCallback mCallback; 1532bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1533bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1534bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link FaceDetectionCallbackForward}. 1535bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1536bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1537bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1538bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link FaceDetectionCallbackForward}, or 1539bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * null if any parameter is null. 1540bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1541bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static CameraOpenCallbackForward getNewInstance( 1542bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraOpenCallback cb) { 1543bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || cb == null) { 1544bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1545bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1546bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new CameraOpenCallbackForward(handler, cb); 1547bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1548bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1549bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private CameraOpenCallbackForward(Handler h, CameraOpenCallback cb) { 1550bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong // Given that we are using the main thread handler, we can create it 1551bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong // here instead of holding onto the PhotoModule objects. In this 1552bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong // way, we can avoid memory leak. 1553bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = new Handler(Looper.getMainLooper()); 1554bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1555bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1556bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1557bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1558bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onCameraOpened(final CameraProxy camera) { 1559bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1560bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1561bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1562bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onCameraOpened(camera); 1563bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1564bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1565bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1566bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1567bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1568bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onCameraDisabled(final int cameraId) { 1569bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1570bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1571bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1572bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onCameraDisabled(cameraId); 1573bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1574bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1575bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1576bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1577bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1578b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong public void onDeviceOpenFailure(final int cameraId, final String info) { 1579bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1580bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1581bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1582b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong mCallback.onDeviceOpenFailure(cameraId, info); 1583bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1584bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1585bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1586bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1587bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 158860520c4df78e595964605cf8acfa21bbafaeba84Angus Kong public void onDeviceOpenedAlready(final int cameraId, final String info) { 1589bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1590bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1591bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 159260520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mCallback.onDeviceOpenedAlready(cameraId, info); 1593bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1594bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1595bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1596bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1597bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 159860520c4df78e595964605cf8acfa21bbafaeba84Angus Kong public void onReconnectionFailure(final CameraManager mgr, final String info) { 1599bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1600bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1601bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 160260520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mCallback.onReconnectionFailure(mgr, info); 1603bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1604bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1605bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1606bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1607bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1608bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class CameraStartPreviewCallbackForward 1609bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong implements CameraStartPreviewCallback { 1610bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1611bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraStartPreviewCallback mCallback; 1612bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1613bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static CameraStartPreviewCallbackForward getNewInstance( 1614bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraStartPreviewCallback cb) { 1615bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || cb == null) { 1616bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1617bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1618bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new CameraStartPreviewCallbackForward(handler, cb); 1619bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1620bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1621bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private CameraStartPreviewCallbackForward(Handler h, 1622bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong CameraStartPreviewCallback cb) { 1623bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1624bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1625bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1626bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1627bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1628bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onPreviewStarted() { 1629bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1630bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1631bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1632bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onPreviewStarted(); 1633bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1634bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1635bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1636bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1637bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong} 1638