AndroidCameraAgentImpl.java revision cef46862d6937bc98bf1a6b087c5daa22b5239f3
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 Kong 44bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong/** 45bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A class to implement {@link CameraManager} of the Android camera framework. 46bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 47bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongclass AndroidCameraManagerImpl implements CameraManager { 48bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final Log.Tag TAG = new Log.Tag("AndroidCamMgrImpl"); 49bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 50bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private Parameters mParameters; 51bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private boolean mParametersIsDirty; 52bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 53bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraHandler mCameraHandler; 54bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final HandlerThread mCameraHandlerThread; 55bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraStateHolder mCameraState; 56bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final DispatchThread mDispatchThread; 57bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 58bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong // Used to retain a copy of Parameters for setting parameters. 59bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private Parameters mParamsToSet; 60bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 61bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private Handler mCameraExceptionCallbackHandler; 62bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private CameraExceptionCallback mCameraExceptionCallback = 63bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong new CameraExceptionCallback() { 64bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 65bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onCameraException(RuntimeException e) { 66bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong throw e; 67bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 68bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }; 69bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 70bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong AndroidCameraManagerImpl() { 71bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandlerThread = new HandlerThread("Camera Handler Thread"); 72bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandlerThread.start(); 73bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler = new CameraHandler(mCameraHandlerThread.getLooper()); 74bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraExceptionCallbackHandler = mCameraHandler; 75bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraState = new CameraStateHolder(); 76cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mDispatchThread = new DispatchThread(mCameraHandler, mCameraHandlerThread); 77bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.start(); 78bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 79bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 80bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 81bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setCameraDefaultExceptionCallback(CameraExceptionCallback callback, 82bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler) { 83bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong synchronized (mCameraExceptionCallback) { 84bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraExceptionCallback = callback; 85bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraExceptionCallbackHandler = handler; 86bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 87bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 88bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 8960520c4df78e595964605cf8acfa21bbafaeba84Angus Kong @Override 90bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void recycle() { 9160520c4df78e595964605cf8acfa21bbafaeba84Angus Kong closeCamera(null, true); 92bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.end(); 93bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 947e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 957e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong @Override 967e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong public CameraDeviceInfo getCameraDeviceInfo() { 977e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return AndroidCameraDeviceInfo.create(); 987e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 997e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1007e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong private static class AndroidCameraDeviceInfo implements CameraDeviceInfo { 1017e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong private final Camera.CameraInfo[] mCameraInfos; 1027e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong private final int mNumberOfCameras; 1037e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong private final int mFirstBackCameraId; 1047e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong private final int mFirstFrontCameraId; 1057e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1067e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong private AndroidCameraDeviceInfo(Camera.CameraInfo[] info, int numberOfCameras, 1077e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong int firstBackCameraId, int firstFrontCameraId) { 1087e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1097e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong mCameraInfos = info; 1107e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong mNumberOfCameras = numberOfCameras; 1117e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong mFirstBackCameraId = firstBackCameraId; 1127e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong mFirstFrontCameraId = firstFrontCameraId; 1137e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1147e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1157e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong public static AndroidCameraDeviceInfo create() { 1167e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong int numberOfCameras; 1177e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong Camera.CameraInfo[] cameraInfos; 1187e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong try { 1197e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong numberOfCameras = Camera.getNumberOfCameras(); 1207e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong cameraInfos = new Camera.CameraInfo[numberOfCameras]; 1217e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong for (int i = 0; i < numberOfCameras; i++) { 1227e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong cameraInfos[i] = new Camera.CameraInfo(); 1237e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong Camera.getCameraInfo(i, cameraInfos[i]); 1247e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1257e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } catch (RuntimeException ex) { 1267e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return null; 1277e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1287e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1297e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong int firstFront = NO_DEVICE; 1307e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong int firstBack = NO_DEVICE; 1317e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong // Get the first (smallest) back and first front camera id. 1327e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong for (int i = numberOfCameras - 1; i >= 0; i--) { 1337e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong if (cameraInfos[i].facing == Camera.CameraInfo.CAMERA_FACING_BACK) { 1347e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong firstBack = i; 1357e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } else { 1367e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong if (cameraInfos[i].facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 1377e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong firstFront = i; 1387e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1397e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1407e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1417e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1427e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return new AndroidCameraDeviceInfo(cameraInfos, numberOfCameras, firstBack, firstFront); 1437e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1447e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1457e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong @Override 1467e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong public Camera.CameraInfo[] getCameraInfos() { 1477e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return mCameraInfos; 1487e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1497e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1507e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong @Override 1517e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong public int getNumberOfCameras() { 1527e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return mNumberOfCameras; 1537e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1547e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1557e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong @Override 1567e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong public int getFirstBackCameraId() { 1577e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return mFirstBackCameraId; 1587e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1597e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1607e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong @Override 1617e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong public int getFirstFrontCameraId() { 1627e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return mFirstFrontCameraId; 1637e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1647e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 165bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 166bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 167bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * The handler on which the actual camera operations happen. 168bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 169cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher private class CameraHandler extends HistoryHandler { 170b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong 171bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private Camera mCamera; 17260520c4df78e595964605cf8acfa21bbafaeba84Angus Kong private int mCameraId; 173bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 174bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private class CaptureCallbacks { 175bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public final ShutterCallback mShutter; 176bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public final PictureCallback mRaw; 177bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public final PictureCallback mPostView; 178bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public final PictureCallback mJpeg; 179bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 180bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong CaptureCallbacks(ShutterCallback shutter, PictureCallback raw, PictureCallback postView, 181bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong PictureCallback jpeg) { 182bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mShutter = shutter; 183bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mRaw = raw; 184bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mPostView = postView; 185bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mJpeg = jpeg; 186bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 187bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 188bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 189bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong CameraHandler(Looper looper) { 190bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong super(looper); 191bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 192bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 193bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void startFaceDetection() { 194bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.startFaceDetection(); 195bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 196bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 197bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void stopFaceDetection() { 198bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.stopFaceDetection(); 199bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 200bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 201bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void setFaceDetectionListener(FaceDetectionListener listener) { 202bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setFaceDetectionListener(listener); 203bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 204bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 205bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void setPreviewTexture(Object surfaceTexture) { 206bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 207bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setPreviewTexture((SurfaceTexture) surfaceTexture); 208bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (IOException e) { 209bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.e(TAG, "Could not set preview texture", e); 210bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 211bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 212bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 213bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) 214bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void enableShutterSound(boolean enable) { 215bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.enableShutterSound(enable); 216bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 217bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 218bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 219bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void setAutoFocusMoveCallback( 220bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong android.hardware.Camera camera, Object cb) { 221bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 222bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong camera.setAutoFocusMoveCallback((AutoFocusMoveCallback) cb); 223bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (RuntimeException ex) { 224bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.w(TAG, ex.getMessage()); 225bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 226bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 227bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 228bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void capture(final CaptureCallbacks cb) { 229bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 230bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.takePicture(cb.mShutter, cb.mRaw, cb.mPostView, cb.mJpeg); 231bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (RuntimeException e) { 232bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong // TODO: output camera state and focus state for debugging. 233bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.e(TAG, "take picture failed."); 234bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong throw e; 235bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 236bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 237bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 238bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void requestTakePicture( 239bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final ShutterCallback shutter, 240bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final PictureCallback raw, 241bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final PictureCallback postView, 242bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final PictureCallback jpeg) { 243bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CaptureCallbacks callbacks = new CaptureCallbacks(shutter, raw, postView, jpeg); 244cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher obtainMessage(CameraActions.CAPTURE_PHOTO, callbacks).sendToTarget(); 245bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 246bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 247bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 248bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * This method does not deal with the API level check. Everyone should 249bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * check first for supported operations before sending message to this handler. 250bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 251bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 252bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void handleMessage(final Message msg) { 253cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher super.handleMessage(msg); 254bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 255bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong switch (msg.what) { 256cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.OPEN_CAMERA: { 257bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraOpenCallback openCallback = (CameraOpenCallback) msg.obj; 258bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final int cameraId = msg.arg1; 259cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher if (mCameraState.getState() != CameraStateHolder.CAMERA_UNOPENED) { 26060520c4df78e595964605cf8acfa21bbafaeba84Angus Kong openCallback.onDeviceOpenedAlready(cameraId, generateHistoryString(cameraId)); 261bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 262bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 263bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 264bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = android.hardware.Camera.open(cameraId); 265bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (mCamera != null) { 26660520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mCameraId = cameraId; 267bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mParametersIsDirty = true; 268bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 269bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong // Get a instance of Camera.Parameters for later use. 270742beb4e81cfcdfa9d4f7d3252be7be797a1e462Sascha Haeberling mParamsToSet = mCamera.getParameters(); 271bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 272cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraState.setState(CameraStateHolder.CAMERA_IDLE); 273bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (openCallback != null) { 274bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong openCallback.onCameraOpened( 275c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong new AndroidCameraProxyImpl(cameraId, mCamera, 276c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong new AndroidCameraCapabilities(mParamsToSet)) 277c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong ); 278bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 279bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } else { 280bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (openCallback != null) { 281b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong openCallback.onDeviceOpenFailure(cameraId, generateHistoryString(cameraId)); 282bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 283bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 284bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 285bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 286bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 287cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.RELEASE: { 28860520c4df78e595964605cf8acfa21bbafaeba84Angus Kong if (mCamera != null) { 28960520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mCamera.release(); 290cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraState.setState(CameraStateHolder.CAMERA_UNOPENED); 29160520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mCamera = null; 29260520c4df78e595964605cf8acfa21bbafaeba84Angus Kong } else { 29360520c4df78e595964605cf8acfa21bbafaeba84Angus Kong Log.w(TAG, "Releasing camera without any camera opened."); 29460520c4df78e595964605cf8acfa21bbafaeba84Angus Kong } 295bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 296bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 297bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 298cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.RECONNECT: { 299bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraOpenCallbackForward cbForward = 300bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong (CameraOpenCallbackForward) msg.obj; 301bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final int cameraId = msg.arg1; 302bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 303bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.reconnect(); 304bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (IOException ex) { 305bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (cbForward != null) { 30660520c4df78e595964605cf8acfa21bbafaeba84Angus Kong cbForward.onReconnectionFailure(AndroidCameraManagerImpl.this, 30760520c4df78e595964605cf8acfa21bbafaeba84Angus Kong generateHistoryString(mCameraId)); 308bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 309bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 310bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 311bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 312cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraState.setState(CameraStateHolder.CAMERA_IDLE); 313bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (cbForward != null) { 314c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong cbForward.onCameraOpened(new AndroidCameraProxyImpl(cameraId, mCamera, 315c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong new AndroidCameraCapabilities(mParamsToSet))); 316bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 317bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 318bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 319bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 320cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.UNLOCK: { 321bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.unlock(); 322cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraState.setState(CameraStateHolder.CAMERA_UNLOCKED); 323bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 324bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 325bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 326cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.LOCK: { 327bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.lock(); 328cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraState.setState(CameraStateHolder.CAMERA_IDLE); 329bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 330bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 331bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 332cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_PREVIEW_TEXTURE_ASYNC: { 333bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong setPreviewTexture(msg.obj); 334bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 335bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 336bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 337cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_PREVIEW_DISPLAY_ASYNC: { 338bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 339bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setPreviewDisplay((SurfaceHolder) msg.obj); 340bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (IOException e) { 341bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong throw new RuntimeException(e); 342bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 343bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 344bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 345bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 346cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.START_PREVIEW_ASYNC: { 347bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraStartPreviewCallbackForward cbForward = 348bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong (CameraStartPreviewCallbackForward) msg.obj; 349bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.startPreview(); 350bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (cbForward != null) { 351bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong cbForward.onPreviewStarted(); 352bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 353bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 354bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 355bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 356cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.STOP_PREVIEW: { 357bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.stopPreview(); 358bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 359bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 360bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 361cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_PREVIEW_CALLBACK_WITH_BUFFER: { 362bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setPreviewCallbackWithBuffer((PreviewCallback) msg.obj); 363bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 364bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 365bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 366cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_ONE_SHOT_PREVIEW_CALLBACK: { 367bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setOneShotPreviewCallback((PreviewCallback) msg.obj); 368bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 369bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 370bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 371cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.ADD_CALLBACK_BUFFER: { 372bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.addCallbackBuffer((byte[]) msg.obj); 373bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 374bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 375bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 376cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.AUTO_FOCUS: { 377cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraState.setState(CameraStateHolder.CAMERA_FOCUSING); 378bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.autoFocus((AutoFocusCallback) msg.obj); 379bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 380bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 381bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 382cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.CANCEL_AUTO_FOCUS: { 383bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.cancelAutoFocus(); 384cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraState.setState(CameraStateHolder.CAMERA_IDLE); 385bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 386bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 387bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 388cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_AUTO_FOCUS_MOVE_CALLBACK: { 389bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong setAutoFocusMoveCallback(mCamera, msg.obj); 390bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 391bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 392bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 393cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_DISPLAY_ORIENTATION: { 394bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setDisplayOrientation(msg.arg1); 395bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 396bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 397bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 398cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_ZOOM_CHANGE_LISTENER: { 399bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setZoomChangeListener((OnZoomChangeListener) msg.obj); 400bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 401bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 402bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 403cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_FACE_DETECTION_LISTENER: { 404bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong setFaceDetectionListener((FaceDetectionListener) msg.obj); 405bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 406bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 407bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 408cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.START_FACE_DETECTION: { 409bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong startFaceDetection(); 410bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 411bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 412bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 413cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.STOP_FACE_DETECTION: { 414bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong stopFaceDetection(); 415bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 416bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 417bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 418cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_ERROR_CALLBACK: { 419bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setErrorCallback((ErrorCallback) msg.obj); 420bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 421bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 422bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 423cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_PARAMETERS: { 424bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mParametersIsDirty = true; 425bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mParamsToSet.unflatten((String) msg.obj); 426bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setParameters(mParamsToSet); 427bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 428bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 429bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 430cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.GET_PARAMETERS: { 431bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (mParametersIsDirty) { 432bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mParameters = mCamera.getParameters(); 433bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mParametersIsDirty = false; 434bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 435bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 436bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 437bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 438cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_PREVIEW_CALLBACK: { 439bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setPreviewCallback((PreviewCallback) msg.obj); 440bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 441bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 442bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 443cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.ENABLE_SHUTTER_SOUND: { 444bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong enableShutterSound((msg.arg1 == 1) ? true : false); 445bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 446bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 447bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 448cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.REFRESH_PARAMETERS: { 449bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mParametersIsDirty = true; 450bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 451bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 452bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 453cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.CAPTURE_PHOTO: { 454cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraState.setState(CameraStateHolder.CAMERA_CAPTURING); 455bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong capture((CaptureCallbacks) msg.obj); 456bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 457bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 458bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 459bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong default: { 460bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong throw new RuntimeException("Invalid CameraProxy message=" + msg.what); 461bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 462bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 463bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (final RuntimeException e) { 464cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher if (msg.what != CameraActions.RELEASE && mCamera != null) { 465bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 466bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.release(); 467cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraState.setState(CameraStateHolder.CAMERA_UNOPENED); 468bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (Exception ex) { 469bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.e(TAG, "Fail to release the camera."); 470bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 471bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = null; 472bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } else { 473bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (mCamera == null) { 474cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher if (msg.what == CameraActions.OPEN_CAMERA) { 475b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong final int cameraId = msg.arg1; 476bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (msg.obj != null) { 477b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong ((CameraOpenCallback) msg.obj).onDeviceOpenFailure( 478b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong msg.arg1, generateHistoryString(cameraId)); 479bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 480bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } else { 481bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.w(TAG, "Cannot handle message " + msg.what + ", mCamera is null."); 482bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 483bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return; 484bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 485bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 486bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong synchronized (mCameraExceptionCallback) { 487bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraExceptionCallbackHandler.post(new Runnable() { 488bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 489bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 490bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraExceptionCallback.onCameraException(e); 491bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 492bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 493bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 494bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 495bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 496bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 497bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 498bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 49960520c4df78e595964605cf8acfa21bbafaeba84Angus Kong public void openCamera(final Handler handler, final int cameraId, 50060520c4df78e595964605cf8acfa21bbafaeba84Angus Kong final CameraOpenCallback callback) { 501bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 502bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 503bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 504cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.OPEN_CAMERA, cameraId, 0, 505bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong CameraOpenCallbackForward.getNewInstance(handler, callback)).sendToTarget(); 506bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 507bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 508bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 509bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 51060520c4df78e595964605cf8acfa21bbafaeba84Angus Kong @Override 51160520c4df78e595964605cf8acfa21bbafaeba84Angus Kong public void closeCamera(CameraProxy camera, boolean synced) { 51260520c4df78e595964605cf8acfa21bbafaeba84Angus Kong if (synced) { 51360520c4df78e595964605cf8acfa21bbafaeba84Angus Kong final WaitDoneBundle bundle = new WaitDoneBundle(); 51460520c4df78e595964605cf8acfa21bbafaeba84Angus Kong 51560520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mDispatchThread.runJobSync(new Runnable() { 51660520c4df78e595964605cf8acfa21bbafaeba84Angus Kong @Override 51760520c4df78e595964605cf8acfa21bbafaeba84Angus Kong public void run() { 518cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.RELEASE).sendToTarget(); 51960520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mCameraHandler.post(bundle.mUnlockRunnable); 52060520c4df78e595964605cf8acfa21bbafaeba84Angus Kong } 52160520c4df78e595964605cf8acfa21bbafaeba84Angus Kong }, bundle.mWaitLock, CAMERA_OPERATION_TIMEOUT_MS, "camera release"); 52260520c4df78e595964605cf8acfa21bbafaeba84Angus Kong } else { 52360520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mDispatchThread.runJob(new Runnable() { 52460520c4df78e595964605cf8acfa21bbafaeba84Angus Kong @Override 52560520c4df78e595964605cf8acfa21bbafaeba84Angus Kong public void run() { 52660520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mCameraHandler.removeCallbacksAndMessages(null); 527cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.RELEASE).sendToTarget(); 52860520c4df78e595964605cf8acfa21bbafaeba84Angus Kong } 52960520c4df78e595964605cf8acfa21bbafaeba84Angus Kong }); 53060520c4df78e595964605cf8acfa21bbafaeba84Angus Kong } 53160520c4df78e595964605cf8acfa21bbafaeba84Angus Kong } 53260520c4df78e595964605cf8acfa21bbafaeba84Angus Kong 533bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 534bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A class which implements {@link CameraManager.CameraProxy} and 535bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * camera handler thread. 536bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 537bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private class AndroidCameraProxyImpl implements CameraManager.CameraProxy { 538bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final int mCameraId; 539bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /* TODO: remove this Camera instance. */ 540bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Camera mCamera; 541c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong private final AndroidCameraCapabilities mCapabilities; 542bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 543c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong private AndroidCameraProxyImpl(int cameraId, Camera camera, 544c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong AndroidCameraCapabilities capabilities) { 545bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 546bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraId = cameraId; 547c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong mCapabilities = capabilities; 548bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 549bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 550bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 551bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public android.hardware.Camera getCamera() { 552bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return mCamera; 553bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 554bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 555bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 556bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public int getCameraId() { 557bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return mCameraId; 558bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 559bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 560bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 561c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong public CameraCapabilities getCapabilities() { 562c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong return new AndroidCameraCapabilities(mCapabilities); 563c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong } 564c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong 565c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong @Override 566bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void reconnect(final Handler handler, final CameraOpenCallback cb) { 567bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 568bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 569bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 570cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.RECONNECT, mCameraId, 0, 571bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong CameraOpenCallbackForward.getNewInstance(handler, cb)).sendToTarget(); 572bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 573bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 574bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 575bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 576bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 577bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void unlock() { 578bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final WaitDoneBundle bundle = new WaitDoneBundle(); 579bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJobSync(new Runnable() { 580bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 581bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 582cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.sendEmptyMessage(CameraActions.UNLOCK); 583bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.post(bundle.mUnlockRunnable); 584bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 585bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }, bundle.mWaitLock, CAMERA_OPERATION_TIMEOUT_MS, "camera unlock"); 586bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 587bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 588bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 589bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void lock() { 590bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 591bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 592bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 593cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.sendEmptyMessage(CameraActions.LOCK); 594bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 595bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 596bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 597bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 598bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 599bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setPreviewTexture(final SurfaceTexture surfaceTexture) { 600bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 601bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 602bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 603cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler 604cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher .obtainMessage(CameraActions.SET_PREVIEW_TEXTURE_ASYNC, surfaceTexture) 605bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 606bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 607bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 608bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 609bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 610bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 611bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setPreviewTextureSync(final SurfaceTexture surfaceTexture) { 612bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final WaitDoneBundle bundle = new WaitDoneBundle(); 613bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJobSync(new Runnable() { 614bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 615bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 616cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler 617cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher .obtainMessage(CameraActions.SET_PREVIEW_TEXTURE_ASYNC, surfaceTexture) 618bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 619bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.post(bundle.mUnlockRunnable); 620bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 621bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }, bundle.mWaitLock, CAMERA_OPERATION_TIMEOUT_MS, "set preview texture"); 622bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 623bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 624bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 625bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setPreviewDisplay(final SurfaceHolder surfaceHolder) { 626bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 627bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 628bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 629cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler 630cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher .obtainMessage(CameraActions.SET_PREVIEW_DISPLAY_ASYNC, surfaceHolder) 631bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 632bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 633bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 634bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 635bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 636bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 637bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void startPreview() { 638bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 639bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 640bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 641cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler 642cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher .obtainMessage(CameraActions.START_PREVIEW_ASYNC, null).sendToTarget(); 643bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 644bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 645bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 646bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 647bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 648bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void startPreviewWithCallback(final Handler handler, 649bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraStartPreviewCallback cb) { 650bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 651bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 652bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 653cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.START_PREVIEW_ASYNC, 654bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong CameraStartPreviewCallbackForward.getNewInstance(handler, cb)).sendToTarget(); 655bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 656bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 657bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 658bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 659bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 660bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void stopPreview() { 661bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final WaitDoneBundle bundle = new WaitDoneBundle(); 662bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJobSync(new Runnable() { 663bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 664bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 665cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.sendEmptyMessage(CameraActions.STOP_PREVIEW); 666bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.post(bundle.mUnlockRunnable); 667bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 668bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }, bundle.mWaitLock, CAMERA_OPERATION_TIMEOUT_MS, "stop preview"); 669bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 670bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 671bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 672bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setPreviewDataCallback( 673bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final Handler handler, final CameraPreviewDataCallback cb) { 674bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 675bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 676bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 677cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.SET_PREVIEW_CALLBACK, 678cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher PreviewCallbackForward.getNewInstance( 679cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher handler, AndroidCameraProxyImpl.this, cb)) 680bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 681bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 682bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 683bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 684bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 685bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setOneShotPreviewCallback(final Handler handler, 686bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraPreviewDataCallback cb) { 687bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 688bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 689bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 690cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.SET_ONE_SHOT_PREVIEW_CALLBACK, 691bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong PreviewCallbackForward 692bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .getNewInstance(handler, AndroidCameraProxyImpl.this, cb)) 693bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 694bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 695bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 696bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 697bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 698bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 699bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setPreviewDataCallbackWithBuffer( 700bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final Handler handler, final CameraPreviewDataCallback cb) { 701bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 702bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 703bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 704cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.SET_PREVIEW_CALLBACK_WITH_BUFFER, 705bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong PreviewCallbackForward 706bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .getNewInstance(handler, AndroidCameraProxyImpl.this, cb)) 707bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 708bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 709bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 710bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 711bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 712bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 713bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void addCallbackBuffer(final byte[] callbackBuffer) { 714bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 715bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 716bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 717cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.ADD_CALLBACK_BUFFER, callbackBuffer) 718bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 719bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 720bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 721bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 722bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 723bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 724bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void autoFocus(final Handler handler, final CameraAFCallback cb) { 725bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final AutoFocusCallback afCallback = new AutoFocusCallback() { 726bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 727bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onAutoFocus(final boolean b, Camera camera) { 728cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher if (mCameraState.getState() != CameraStateHolder.CAMERA_FOCUSING) { 729bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.w(TAG, "onAutoFocus callback returning when not focusing"); 730bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } else { 731cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraState.setState(CameraStateHolder.CAMERA_IDLE); 732bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 733bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong handler.post(new Runnable() { 734bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 735bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 736bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong cb.onAutoFocus(b, AndroidCameraProxyImpl.this); 737bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 738bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 739bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 740bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }; 741bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 742bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 743bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 744cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraState.waitForStates(CameraStateHolder.CAMERA_IDLE); 745cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.AUTO_FOCUS, afCallback) 746cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher .sendToTarget(); 747bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 748bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 749bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 750bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 751bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 752bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void cancelAutoFocus() { 753bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 754bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 755bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 756cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.removeMessages(CameraActions.AUTO_FOCUS); 757cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.sendEmptyMessage(CameraActions.CANCEL_AUTO_FOCUS); 758bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 759bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 760bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 761bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 762bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 763bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 764bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setAutoFocusMoveCallback( 765bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final Handler handler, final CameraAFMoveCallback cb) { 766bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 767bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 768bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 769cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.SET_AUTO_FOCUS_MOVE_CALLBACK, 770cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher AFMoveCallbackForward.getNewInstance( 771cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher handler, AndroidCameraProxyImpl.this, cb)) 772bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 773bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 774bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 775bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 776bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 777bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 778bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void takePicture( 779bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final Handler handler, final CameraShutterCallback shutter, 780bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraPictureCallback raw, final CameraPictureCallback post, 781bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraPictureCallback jpeg) { 782bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final PictureCallback jpegCallback = new PictureCallback() { 783bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 784bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onPictureTaken(final byte[] data, Camera camera) { 785cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher if (mCameraState.getState() != CameraStateHolder.CAMERA_CAPTURING) { 78660520c4df78e595964605cf8acfa21bbafaeba84Angus Kong Log.w(TAG, "picture callback returning when not capturing"); 787bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } else { 788cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraState.setState(CameraStateHolder.CAMERA_IDLE); 789bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 790bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong handler.post(new Runnable() { 791bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 792bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 793bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong jpeg.onPictureTaken(data, AndroidCameraProxyImpl.this); 794bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 795bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 796bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 797bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }; 798bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 799bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 800bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 801bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 802cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraState.waitForStates( 803cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher CameraStateHolder.CAMERA_IDLE | CameraStateHolder.CAMERA_UNLOCKED); 804bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.requestTakePicture(ShutterCallbackForward 805bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .getNewInstance(handler, AndroidCameraProxyImpl.this, shutter), 806bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong PictureCallbackForward 807bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .getNewInstance(handler, AndroidCameraProxyImpl.this, raw), 808bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong PictureCallbackForward 809bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .getNewInstance(handler, AndroidCameraProxyImpl.this, post), 810bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong jpegCallback); 811bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 812bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 813bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 814bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 815bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 816bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setDisplayOrientation(final int degrees) { 817bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 818bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 819bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 820cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.SET_DISPLAY_ORIENTATION, degrees, 0) 821bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 822bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 823bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 824bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 825bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 826bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 827bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setZoomChangeListener(final OnZoomChangeListener listener) { 828bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 829bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 830bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 831cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.SET_ZOOM_CHANGE_LISTENER, listener) 832cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher .sendToTarget(); 833bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 834bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 835bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 836bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 837bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 838bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setFaceDetectionCallback(final Handler handler, 839bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraFaceDetectionCallback cb) { 840bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 841bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 842bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 843cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.SET_FACE_DETECTION_LISTENER, 844bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong FaceDetectionCallbackForward 845bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .getNewInstance(handler, AndroidCameraProxyImpl.this, cb)) 846bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 847bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 848bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 849bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 850bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 851bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 852bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void startFaceDetection() { 853bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 854bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 855bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 856cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.sendEmptyMessage(CameraActions.START_FACE_DETECTION); 857bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 858bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 859bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 860bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 861bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 862bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void stopFaceDetection() { 863bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 864bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 865bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 866cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.sendEmptyMessage(CameraActions.STOP_FACE_DETECTION); 867bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 868bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 869bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 870bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 871bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 872bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setErrorCallback(final Handler handler, final CameraErrorCallback cb) { 873bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 874bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 875bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 876cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.SET_ERROR_CALLBACK, 877cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher ErrorCallbackForward.getNewInstance( 878cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher handler, AndroidCameraProxyImpl.this, cb)) 879cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher .sendToTarget(); 880bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 881bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 882bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 883bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 884bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 885bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setParameters(final Parameters params) { 886bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (params == null) { 887bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.v(TAG, "null parameters in setParameters()"); 888bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return; 889bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 890bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final String flattenedParameters = params.flatten(); 891bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 892bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 893bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 894cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraState.waitForStates( 895cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher CameraStateHolder.CAMERA_IDLE | CameraStateHolder.CAMERA_UNLOCKED); 896cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.SET_PARAMETERS, flattenedParameters) 897cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher .sendToTarget(); 898bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 899bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 900bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 901bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 902bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 903bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public Parameters getParameters() { 904bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final WaitDoneBundle bundle = new WaitDoneBundle(); 905bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJobSync(new Runnable() { 906bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 907bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 908cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.sendEmptyMessage(CameraActions.GET_PARAMETERS); 909bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.post(bundle.mUnlockRunnable); 910bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 911bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }, bundle.mWaitLock, CAMERA_OPERATION_TIMEOUT_MS, "get parameters"); 912bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return mParameters; 913bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 914bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 915bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 916bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void refreshParameters() { 917bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 918bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 919bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 920cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.sendEmptyMessage(CameraActions.REFRESH_PARAMETERS); 921bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 922bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 923bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 924bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 925bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 926bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void enableShutterSound(final boolean enable) { 927bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 928bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 929bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 930cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler 931cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher .obtainMessage(CameraActions.ENABLE_SHUTTER_SOUND, (enable ? 1 : 0), 0) 932bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 933bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 934bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 935bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 936bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 937bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 938bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class WaitDoneBundle { 939bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public Runnable mUnlockRunnable; 940bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Object mWaitLock; 941bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 942bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong WaitDoneBundle() { 943bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mWaitLock = new Object(); 944bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mUnlockRunnable = new Runnable() { 945bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 946bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 947bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong synchronized (mWaitLock) { 948bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mWaitLock.notifyAll(); 949bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 950bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 951bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }; 952bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 953bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 954bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 955bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 956bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A helper class to forward AutoFocusCallback to another thread. 957bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 958bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class AFCallbackForward implements AutoFocusCallback { 959bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 960bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 961bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraAFCallback mCallback; 962bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 963bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 964bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link AFCallbackForward}. 965bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 966bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 967bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 968bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 969bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link AFCallbackForward}, 970bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameter is null. 971bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 972bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static AFCallbackForward getNewInstance( 973bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraAFCallback cb) { 974bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 975bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 976bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 977bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new AFCallbackForward(handler, camera, cb); 978bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 979bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 980bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private AFCallbackForward( 981bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraAFCallback cb) { 982bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 983bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 984bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 985bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 986bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 987bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 988bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onAutoFocus(final boolean b, Camera camera) { 989bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 990bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 991bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 992bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onAutoFocus(b, mCamera); 993bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 994bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 995bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 996bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 997bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 998bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 999bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A helper class to forward ErrorCallback to another thread. 1000bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1001bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class ErrorCallbackForward implements Camera.ErrorCallback { 1002bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1003bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1004bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraErrorCallback mCallback; 1005bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1006bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1007bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link AFCallbackForward}. 1008bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1009bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1010bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1011bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1012bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link AFCallbackForward}, 1013bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameter is null. 1014bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1015bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static ErrorCallbackForward getNewInstance( 1016bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraErrorCallback cb) { 1017bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1018bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1019bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1020bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new ErrorCallbackForward(handler, camera, cb); 1021bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1022bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1023bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private ErrorCallbackForward( 1024bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraErrorCallback cb) { 1025bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1026bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1027bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1028bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1029bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1030bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1031bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onError(final int error, Camera camera) { 1032bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1033bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1034bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1035bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onError(error, mCamera); 1036bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1037bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1038bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1039bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1040bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1041bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** A helper class to forward AutoFocusMoveCallback to another thread. */ 1042bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 1043bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class AFMoveCallbackForward implements AutoFocusMoveCallback { 1044bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1045bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraAFMoveCallback mCallback; 1046bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1047bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1048bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1049bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link AFMoveCallbackForward}. 1050bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1051bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1052bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1053bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1054bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link AFMoveCallbackForward}, 1055bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameter is null. 1056bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1057bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static AFMoveCallbackForward getNewInstance( 1058bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraAFMoveCallback cb) { 1059bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1060bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1061bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1062bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new AFMoveCallbackForward(handler, camera, cb); 1063bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1064bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1065bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private AFMoveCallbackForward( 1066bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraAFMoveCallback cb) { 1067bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1068bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1069bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1070bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1071bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1072bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1073bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onAutoFocusMoving( 1074bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final boolean moving, android.hardware.Camera camera) { 1075bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1076bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1077bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1078bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onAutoFocusMoving(moving, mCamera); 1079bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1080bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1081bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1082bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1083bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1084bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1085bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A helper class to forward ShutterCallback to to another thread. 1086bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1087bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class ShutterCallbackForward implements ShutterCallback { 1088bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1089bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraShutterCallback mCallback; 1090bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1091bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1092bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1093bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link ShutterCallbackForward}. 1094bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1095bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1096bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1097bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1098bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link ShutterCallbackForward}, 1099bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameter is null. 1100bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1101bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static ShutterCallbackForward getNewInstance( 1102bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraShutterCallback cb) { 1103bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1104bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1105bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1106bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new ShutterCallbackForward(handler, camera, cb); 1107bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1108bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1109bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private ShutterCallbackForward( 1110bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraShutterCallback cb) { 1111bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1112bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1113bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1114bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1115bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1116bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1117bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onShutter() { 1118bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1119bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1120bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1121bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onShutter(mCamera); 1122bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1123bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1124bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1125bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1126bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1127bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1128bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A helper class to forward PictureCallback to another thread. 1129bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1130bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class PictureCallbackForward implements PictureCallback { 1131bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1132bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraPictureCallback mCallback; 1133bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1134bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1135bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1136bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link PictureCallbackForward}. 1137bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1138bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1139bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1140bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1141bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link PictureCallbackForward}, 1142bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameters is null. 1143bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1144bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static PictureCallbackForward getNewInstance( 1145bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraPictureCallback cb) { 1146bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1147bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1148bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1149bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new PictureCallbackForward(handler, camera, cb); 1150bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1151bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1152bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private PictureCallbackForward( 1153bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraPictureCallback cb) { 1154bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1155bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1156bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1157bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1158bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1159bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1160bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onPictureTaken( 1161bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final byte[] data, android.hardware.Camera camera) { 1162bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1163bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1164bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1165bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onPictureTaken(data, mCamera); 1166bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1167bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1168bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1169bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1170bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1171bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1172bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A helper class to forward PreviewCallback to another thread. 1173bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1174bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class PreviewCallbackForward implements PreviewCallback { 1175bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1176bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraPreviewDataCallback mCallback; 1177bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1178bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1179bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1180bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link PreviewCallbackForward}. 1181bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1182bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1183bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1184bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1185bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link PreviewCallbackForward}, 1186bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameters is null. 1187bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1188bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static PreviewCallbackForward getNewInstance( 1189bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraPreviewDataCallback cb) { 1190bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1191bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1192bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1193bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new PreviewCallbackForward(handler, camera, cb); 1194bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1195bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1196bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private PreviewCallbackForward( 1197bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraPreviewDataCallback cb) { 1198bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1199bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1200bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1201bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1202bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1203bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1204bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onPreviewFrame( 1205bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final byte[] data, android.hardware.Camera camera) { 1206bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1207bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1208bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1209bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onPreviewFrame(data, mCamera); 1210bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1211bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1212bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1213bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1214bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1215bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class FaceDetectionCallbackForward implements FaceDetectionListener { 1216bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1217bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraFaceDetectionCallback mCallback; 1218bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1219bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1220bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1221bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link FaceDetectionCallbackForward}. 1222bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1223bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1224bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1225bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1226bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link FaceDetectionCallbackForward}, 1227bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameter is null. 1228bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1229bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static FaceDetectionCallbackForward getNewInstance( 1230bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraFaceDetectionCallback cb) { 1231bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1232bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1233bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1234bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new FaceDetectionCallbackForward(handler, camera, cb); 1235bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1236bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1237bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private FaceDetectionCallbackForward( 1238bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraFaceDetectionCallback cb) { 1239bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1240bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1241bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1242bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1243bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1244bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1245bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onFaceDetection( 1246bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final Camera.Face[] faces, Camera camera) { 1247bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1248bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1249bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1250bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onFaceDetection(faces, mCamera); 1251bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1252bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1253bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1254bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1255bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong} 1256