AndroidCameraAgentImpl.java revision f07afbbde040b9578bc7f188016c3960e8616ab0
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.view.SurfaceHolder; 37bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 38bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongimport com.android.ex.camera2.portability.debug.Log; 39bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 40bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongimport java.io.IOException; 41bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 42bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong/** 43bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A class to implement {@link CameraManager} of the Android camera framework. 44bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 45bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongclass AndroidCameraManagerImpl implements CameraManager { 46bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static final Log.Tag TAG = new Log.Tag("AndroidCamMgrImpl"); 47bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 48bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private Parameters mParameters; 49bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private boolean mParametersIsDirty; 508097973089420749dcd1ab4974a629c2466b31ccAngus Kong private AndroidCameraCapabilities mCapabilities; 51bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 52bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraHandler mCameraHandler; 53bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final HandlerThread mCameraHandlerThread; 54bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraStateHolder mCameraState; 55bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final DispatchThread mDispatchThread; 56bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 57bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private Handler mCameraExceptionCallbackHandler; 58bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private CameraExceptionCallback mCameraExceptionCallback = 59bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong new CameraExceptionCallback() { 60bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 61bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onCameraException(RuntimeException e) { 62bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong throw e; 63bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 64bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }; 65bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 66bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong AndroidCameraManagerImpl() { 67bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandlerThread = new HandlerThread("Camera Handler Thread"); 68bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandlerThread.start(); 69bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler = new CameraHandler(mCameraHandlerThread.getLooper()); 70bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraExceptionCallbackHandler = mCameraHandler; 71bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraState = new CameraStateHolder(); 72cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mDispatchThread = new DispatchThread(mCameraHandler, mCameraHandlerThread); 73bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.start(); 74bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 75bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 76bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 77bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setCameraDefaultExceptionCallback(CameraExceptionCallback callback, 78bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler) { 79bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong synchronized (mCameraExceptionCallback) { 80bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraExceptionCallback = callback; 81bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraExceptionCallbackHandler = handler; 82bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 83bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 84bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 8560520c4df78e595964605cf8acfa21bbafaeba84Angus Kong @Override 86bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void recycle() { 8760520c4df78e595964605cf8acfa21bbafaeba84Angus Kong closeCamera(null, true); 88bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.end(); 89bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 907e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 917e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong @Override 927e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong public CameraDeviceInfo getCameraDeviceInfo() { 937e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return AndroidCameraDeviceInfo.create(); 947e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 957e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 967e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong private static class AndroidCameraDeviceInfo implements CameraDeviceInfo { 977e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong private final Camera.CameraInfo[] mCameraInfos; 987e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong private final int mNumberOfCameras; 997e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong private final int mFirstBackCameraId; 1007e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong private final int mFirstFrontCameraId; 1017e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1027e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong private AndroidCameraDeviceInfo(Camera.CameraInfo[] info, int numberOfCameras, 1037e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong int firstBackCameraId, int firstFrontCameraId) { 1047e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1057e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong mCameraInfos = info; 1067e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong mNumberOfCameras = numberOfCameras; 1077e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong mFirstBackCameraId = firstBackCameraId; 1087e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong mFirstFrontCameraId = firstFrontCameraId; 1097e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1107e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1117e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong public static AndroidCameraDeviceInfo create() { 1127e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong int numberOfCameras; 1137e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong Camera.CameraInfo[] cameraInfos; 1147e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong try { 1157e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong numberOfCameras = Camera.getNumberOfCameras(); 1167e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong cameraInfos = new Camera.CameraInfo[numberOfCameras]; 1177e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong for (int i = 0; i < numberOfCameras; i++) { 1187e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong cameraInfos[i] = new Camera.CameraInfo(); 1197e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong Camera.getCameraInfo(i, cameraInfos[i]); 1207e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1217e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } catch (RuntimeException ex) { 1227e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return null; 1237e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1247e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1257e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong int firstFront = NO_DEVICE; 1267e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong int firstBack = NO_DEVICE; 1277e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong // Get the first (smallest) back and first front camera id. 1287e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong for (int i = numberOfCameras - 1; i >= 0; i--) { 1297e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong if (cameraInfos[i].facing == Camera.CameraInfo.CAMERA_FACING_BACK) { 1307e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong firstBack = i; 1317e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } else { 1327e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong if (cameraInfos[i].facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 1337e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong firstFront = i; 1347e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1357e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1367e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1377e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1387e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return new AndroidCameraDeviceInfo(cameraInfos, numberOfCameras, firstBack, firstFront); 1397e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1407e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1417e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong @Override 1427e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong public Camera.CameraInfo[] getCameraInfos() { 1437e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return mCameraInfos; 1447e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1457e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1467e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong @Override 1477e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong public int getNumberOfCameras() { 1487e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return mNumberOfCameras; 1497e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1507e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1517e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong @Override 1527e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong public int getFirstBackCameraId() { 1537e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return mFirstBackCameraId; 1547e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1557e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1567e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong @Override 1577e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong public int getFirstFrontCameraId() { 1587e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return mFirstFrontCameraId; 1597e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1607e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 161bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 162bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 163bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * The handler on which the actual camera operations happen. 164bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 165cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher private class CameraHandler extends HistoryHandler { 166b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong 1678097973089420749dcd1ab4974a629c2466b31ccAngus Kong // Used to retain a copy of Parameters for setting parameters. 1688097973089420749dcd1ab4974a629c2466b31ccAngus Kong private Parameters mParamsToSet; 169bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private Camera mCamera; 17060520c4df78e595964605cf8acfa21bbafaeba84Angus Kong private int mCameraId; 171bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 172bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private class CaptureCallbacks { 173bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public final ShutterCallback mShutter; 174bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public final PictureCallback mRaw; 175bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public final PictureCallback mPostView; 176bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public final PictureCallback mJpeg; 177bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 178bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong CaptureCallbacks(ShutterCallback shutter, PictureCallback raw, PictureCallback postView, 179bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong PictureCallback jpeg) { 180bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mShutter = shutter; 181bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mRaw = raw; 182bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mPostView = postView; 183bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mJpeg = jpeg; 184bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 185bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 186bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 187bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong CameraHandler(Looper looper) { 188bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong super(looper); 189bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 190bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 191bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void startFaceDetection() { 192bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.startFaceDetection(); 193bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 194bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 195bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void stopFaceDetection() { 196bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.stopFaceDetection(); 197bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 198bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 199bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void setFaceDetectionListener(FaceDetectionListener listener) { 200bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setFaceDetectionListener(listener); 201bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 202bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 203bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void setPreviewTexture(Object surfaceTexture) { 204bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 205bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setPreviewTexture((SurfaceTexture) surfaceTexture); 206bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (IOException e) { 207bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.e(TAG, "Could not set preview texture", e); 208bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 209bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 210bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 211bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) 212bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void enableShutterSound(boolean enable) { 213bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.enableShutterSound(enable); 214bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 215bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 216bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 217bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void setAutoFocusMoveCallback( 218bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong android.hardware.Camera camera, Object cb) { 219bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 220bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong camera.setAutoFocusMoveCallback((AutoFocusMoveCallback) cb); 221bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (RuntimeException ex) { 222bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.w(TAG, ex.getMessage()); 223bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 224bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 225bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 226bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void capture(final CaptureCallbacks cb) { 227bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 228bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.takePicture(cb.mShutter, cb.mRaw, cb.mPostView, cb.mJpeg); 229bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (RuntimeException e) { 230bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong // TODO: output camera state and focus state for debugging. 231bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.e(TAG, "take picture failed."); 232bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong throw e; 233bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 234bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 235bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 236bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void requestTakePicture( 237bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final ShutterCallback shutter, 238bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final PictureCallback raw, 239bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final PictureCallback postView, 240bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final PictureCallback jpeg) { 241bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CaptureCallbacks callbacks = new CaptureCallbacks(shutter, raw, postView, jpeg); 242cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher obtainMessage(CameraActions.CAPTURE_PHOTO, callbacks).sendToTarget(); 243bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 244bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 245bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 246bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * This method does not deal with the API level check. Everyone should 247bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * check first for supported operations before sending message to this handler. 248bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 249bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 250bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void handleMessage(final Message msg) { 251cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher super.handleMessage(msg); 252bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 253bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong switch (msg.what) { 254cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.OPEN_CAMERA: { 255bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraOpenCallback openCallback = (CameraOpenCallback) msg.obj; 256bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final int cameraId = msg.arg1; 257cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher if (mCameraState.getState() != CameraStateHolder.CAMERA_UNOPENED) { 25860520c4df78e595964605cf8acfa21bbafaeba84Angus Kong openCallback.onDeviceOpenedAlready(cameraId, generateHistoryString(cameraId)); 259bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 260bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 261bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 262bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = android.hardware.Camera.open(cameraId); 263bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (mCamera != null) { 26460520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mCameraId = cameraId; 265bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mParametersIsDirty = true; 266bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 267bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong // Get a instance of Camera.Parameters for later use. 268742beb4e81cfcdfa9d4f7d3252be7be797a1e462Sascha Haeberling mParamsToSet = mCamera.getParameters(); 2698097973089420749dcd1ab4974a629c2466b31ccAngus Kong mCapabilities = new AndroidCameraCapabilities(mParamsToSet); 270bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 271cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraState.setState(CameraStateHolder.CAMERA_IDLE); 272bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (openCallback != null) { 273bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong openCallback.onCameraOpened( 274c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong new AndroidCameraProxyImpl(cameraId, mCamera, 2758097973089420749dcd1ab4974a629c2466b31ccAngus Kong mCapabilities)); 276bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 277bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } else { 278bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (openCallback != null) { 279b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong openCallback.onDeviceOpenFailure(cameraId, generateHistoryString(cameraId)); 280bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 281bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 282bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 283bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 284bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 285cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.RELEASE: { 28660520c4df78e595964605cf8acfa21bbafaeba84Angus Kong if (mCamera != null) { 28760520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mCamera.release(); 288cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraState.setState(CameraStateHolder.CAMERA_UNOPENED); 28960520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mCamera = null; 29060520c4df78e595964605cf8acfa21bbafaeba84Angus Kong } else { 29160520c4df78e595964605cf8acfa21bbafaeba84Angus Kong Log.w(TAG, "Releasing camera without any camera opened."); 29260520c4df78e595964605cf8acfa21bbafaeba84Angus Kong } 293bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 294bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 295bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 296cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.RECONNECT: { 297bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraOpenCallbackForward cbForward = 298bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong (CameraOpenCallbackForward) msg.obj; 299bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final int cameraId = msg.arg1; 300bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 301bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.reconnect(); 302bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (IOException ex) { 303bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (cbForward != null) { 30460520c4df78e595964605cf8acfa21bbafaeba84Angus Kong cbForward.onReconnectionFailure(AndroidCameraManagerImpl.this, 30560520c4df78e595964605cf8acfa21bbafaeba84Angus Kong generateHistoryString(mCameraId)); 306bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 307bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 308bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 309bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 310cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraState.setState(CameraStateHolder.CAMERA_IDLE); 311bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (cbForward != null) { 3128097973089420749dcd1ab4974a629c2466b31ccAngus Kong cbForward.onCameraOpened( 3138097973089420749dcd1ab4974a629c2466b31ccAngus Kong new AndroidCameraProxyImpl(cameraId, mCamera, mCapabilities)); 314bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 315bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 316bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 317bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 318cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.UNLOCK: { 319bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.unlock(); 320cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraState.setState(CameraStateHolder.CAMERA_UNLOCKED); 321bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 322bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 323bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 324cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.LOCK: { 325bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.lock(); 326cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraState.setState(CameraStateHolder.CAMERA_IDLE); 327bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 328bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 329bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 330cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_PREVIEW_TEXTURE_ASYNC: { 331bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong setPreviewTexture(msg.obj); 332bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 333bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 334bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 335cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_PREVIEW_DISPLAY_ASYNC: { 336bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 337bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setPreviewDisplay((SurfaceHolder) msg.obj); 338bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (IOException e) { 339bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong throw new RuntimeException(e); 340bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 341bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 342bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 343bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 344cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.START_PREVIEW_ASYNC: { 345bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraStartPreviewCallbackForward cbForward = 346bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong (CameraStartPreviewCallbackForward) msg.obj; 347bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.startPreview(); 348bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (cbForward != null) { 349bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong cbForward.onPreviewStarted(); 350bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 351bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 352bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 353bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 354cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.STOP_PREVIEW: { 355bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.stopPreview(); 356bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 357bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 358bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 359cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_PREVIEW_CALLBACK_WITH_BUFFER: { 360bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setPreviewCallbackWithBuffer((PreviewCallback) msg.obj); 361bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 362bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 363bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 364cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_ONE_SHOT_PREVIEW_CALLBACK: { 365bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setOneShotPreviewCallback((PreviewCallback) msg.obj); 366bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 367bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 368bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 369cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.ADD_CALLBACK_BUFFER: { 370bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.addCallbackBuffer((byte[]) msg.obj); 371bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 372bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 373bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 374cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.AUTO_FOCUS: { 375cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraState.setState(CameraStateHolder.CAMERA_FOCUSING); 376bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.autoFocus((AutoFocusCallback) msg.obj); 377bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 378bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 379bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 380cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.CANCEL_AUTO_FOCUS: { 381bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.cancelAutoFocus(); 382cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraState.setState(CameraStateHolder.CAMERA_IDLE); 383bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 384bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 385bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 386cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_AUTO_FOCUS_MOVE_CALLBACK: { 387bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong setAutoFocusMoveCallback(mCamera, msg.obj); 388bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 389bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 390bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 391cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_DISPLAY_ORIENTATION: { 392bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setDisplayOrientation(msg.arg1); 393bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 394bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 395bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 396cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_ZOOM_CHANGE_LISTENER: { 397bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setZoomChangeListener((OnZoomChangeListener) msg.obj); 398bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 399bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 400bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 401cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_FACE_DETECTION_LISTENER: { 402bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong setFaceDetectionListener((FaceDetectionListener) msg.obj); 403bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 404bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 405bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 406cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.START_FACE_DETECTION: { 407bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong startFaceDetection(); 408bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 409bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 410bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 411cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.STOP_FACE_DETECTION: { 412bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong stopFaceDetection(); 413bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 414bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 415bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 416cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_ERROR_CALLBACK: { 417bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setErrorCallback((ErrorCallback) msg.obj); 418bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 419bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 420bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 4218097973089420749dcd1ab4974a629c2466b31ccAngus Kong case CameraActions.APPLY_SETTINGS: { 4228097973089420749dcd1ab4974a629c2466b31ccAngus Kong mParametersIsDirty = true; 4238097973089420749dcd1ab4974a629c2466b31ccAngus Kong CameraSettings settings = (CameraSettings) msg.obj; 4248097973089420749dcd1ab4974a629c2466b31ccAngus Kong applyToParameters(settings); 4258097973089420749dcd1ab4974a629c2466b31ccAngus Kong mCamera.setParameters(mParamsToSet); 4268097973089420749dcd1ab4974a629c2466b31ccAngus Kong break; 4278097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 4288097973089420749dcd1ab4974a629c2466b31ccAngus Kong 429cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_PARAMETERS: { 430bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mParametersIsDirty = true; 431bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mParamsToSet.unflatten((String) msg.obj); 432bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setParameters(mParamsToSet); 433bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 434bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 435bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 436cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.GET_PARAMETERS: { 437bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (mParametersIsDirty) { 438bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mParameters = mCamera.getParameters(); 439bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mParametersIsDirty = false; 440bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 441bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 442bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 443bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 444cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_PREVIEW_CALLBACK: { 445bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setPreviewCallback((PreviewCallback) msg.obj); 446bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 447bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 448bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 449cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.ENABLE_SHUTTER_SOUND: { 450bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong enableShutterSound((msg.arg1 == 1) ? true : false); 451bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 452bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 453bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 454cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.REFRESH_PARAMETERS: { 455bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mParametersIsDirty = true; 456bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 457bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 458bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 459cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.CAPTURE_PHOTO: { 460cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraState.setState(CameraStateHolder.CAMERA_CAPTURING); 461bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong capture((CaptureCallbacks) msg.obj); 462bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 463bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 464bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 465bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong default: { 466bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong throw new RuntimeException("Invalid CameraProxy message=" + msg.what); 467bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 468bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 469bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (final RuntimeException e) { 470cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher if (msg.what != CameraActions.RELEASE && mCamera != null) { 471bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 472bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.release(); 473cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraState.setState(CameraStateHolder.CAMERA_UNOPENED); 474bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (Exception ex) { 475bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.e(TAG, "Fail to release the camera."); 476bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 477bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = null; 478bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } else { 479bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (mCamera == null) { 480cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher if (msg.what == CameraActions.OPEN_CAMERA) { 481b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong final int cameraId = msg.arg1; 482bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (msg.obj != null) { 483b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong ((CameraOpenCallback) msg.obj).onDeviceOpenFailure( 484b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong msg.arg1, generateHistoryString(cameraId)); 485bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 486bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } else { 487bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.w(TAG, "Cannot handle message " + msg.what + ", mCamera is null."); 488bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 489bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return; 490bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 491bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 492bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong synchronized (mCameraExceptionCallback) { 493bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraExceptionCallbackHandler.post(new Runnable() { 494bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 495bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 496bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraExceptionCallback.onCameraException(e); 497bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 498bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 499bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 500bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 501bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 5028097973089420749dcd1ab4974a629c2466b31ccAngus Kong 5038097973089420749dcd1ab4974a629c2466b31ccAngus Kong private void applyToParameters(final CameraSettings settings) { 5048097973089420749dcd1ab4974a629c2466b31ccAngus Kong final CameraCapabilities.Stringifier stringifier = mCapabilities.getStringifier(); 5058097973089420749dcd1ab4974a629c2466b31ccAngus Kong Size photoSize = settings.getCurrentPhotoSize(); 5068097973089420749dcd1ab4974a629c2466b31ccAngus Kong mParamsToSet.setPictureSize(photoSize.width(), photoSize.height()); 5078097973089420749dcd1ab4974a629c2466b31ccAngus Kong Size previewSize = settings.getCurrentPreviewSize(); 5088097973089420749dcd1ab4974a629c2466b31ccAngus Kong mParamsToSet.setPreviewSize(previewSize.width(), previewSize.height()); 5098097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (settings.getPreviewFrameRate() == -1) { 5108097973089420749dcd1ab4974a629c2466b31ccAngus Kong mParamsToSet.setPreviewFpsRange(settings.getPreviewFpsRangeMin(), 5118097973089420749dcd1ab4974a629c2466b31ccAngus Kong settings.getPreviewFpsRangeMax()); 5128097973089420749dcd1ab4974a629c2466b31ccAngus Kong } else { 5138097973089420749dcd1ab4974a629c2466b31ccAngus Kong mParamsToSet.setPreviewFrameRate(settings.getPreviewFrameRate()); 5148097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 5158097973089420749dcd1ab4974a629c2466b31ccAngus Kong mParamsToSet.setJpegQuality(settings.getPhotoJpegCompressionQuality()); 5168097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (mCapabilities.supports(CameraCapabilities.Feature.ZOOM)) { 5178097973089420749dcd1ab4974a629c2466b31ccAngus Kong // Should use settings.getCurrentZoomRatio() instead here. 5188097973089420749dcd1ab4974a629c2466b31ccAngus Kong mParamsToSet.setZoom(settings.getCurrentZoomIndex()); 5198097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 5208097973089420749dcd1ab4974a629c2466b31ccAngus Kong mParamsToSet.setRotation((int) settings.getCurrentPhotoRotationDegrees()); 5218097973089420749dcd1ab4974a629c2466b31ccAngus Kong mParamsToSet.setExposureCompensation(settings.getExposureCompensationIndex()); 5228097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (mCapabilities.supports(CameraCapabilities.Feature.AUTO_EXPOSURE_LOCK)) { 5238097973089420749dcd1ab4974a629c2466b31ccAngus Kong mParamsToSet.setAutoExposureLock(settings.isAutoExposureLocked()); 5248097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 5258097973089420749dcd1ab4974a629c2466b31ccAngus Kong mParamsToSet.setFocusMode(stringifier.stringify(settings.getCurrentFocusMode())); 5268097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (mCapabilities.supports(CameraCapabilities.Feature.AUTO_WHITE_BALANCE_LOCK)) { 5278097973089420749dcd1ab4974a629c2466b31ccAngus Kong mParamsToSet.setAutoWhiteBalanceLock(settings.isAutoWhiteBalanceLocked()); 5288097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 5298097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (mCapabilities.supports(CameraCapabilities.Feature.FOCUS_AREA)) { 530f07afbbde040b9578bc7f188016c3960e8616ab0Angus Kong if (settings.getFocusAreas().size() != 0) { 531f07afbbde040b9578bc7f188016c3960e8616ab0Angus Kong mParamsToSet.setFocusAreas(settings.getFocusAreas()); 532f07afbbde040b9578bc7f188016c3960e8616ab0Angus Kong } 5338097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 5348097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (mCapabilities.supports(CameraCapabilities.Feature.METERING_AREA)) { 535f07afbbde040b9578bc7f188016c3960e8616ab0Angus Kong if (settings.getMeteringAreas().size() != 0) { 536f07afbbde040b9578bc7f188016c3960e8616ab0Angus Kong mParamsToSet.setMeteringAreas(settings.getMeteringAreas()); 537f07afbbde040b9578bc7f188016c3960e8616ab0Angus Kong } 5388097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 5398097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (settings.getCurrentFlashMode() != CameraCapabilities.FlashMode.NO_FLASH) { 5408097973089420749dcd1ab4974a629c2466b31ccAngus Kong mParamsToSet.setFlashMode(stringifier.stringify(settings.getCurrentFlashMode())); 5418097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 5428097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (settings.getCurrentSceneMode() != CameraCapabilities.SceneMode.NO_SCENE_MODE) { 543f07afbbde040b9578bc7f188016c3960e8616ab0Angus Kong if (settings.getCurrentSceneMode() != null) { 544f07afbbde040b9578bc7f188016c3960e8616ab0Angus Kong mParamsToSet 545f07afbbde040b9578bc7f188016c3960e8616ab0Angus Kong .setSceneMode(stringifier.stringify(settings.getCurrentSceneMode())); 546f07afbbde040b9578bc7f188016c3960e8616ab0Angus Kong } 5478097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 5488097973089420749dcd1ab4974a629c2466b31ccAngus Kong 5498097973089420749dcd1ab4974a629c2466b31ccAngus Kong CameraSettings.GpsData gpsData = settings.getGpsData(); 5508097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (gpsData == null) { 5518097973089420749dcd1ab4974a629c2466b31ccAngus Kong mParamsToSet.removeGpsData(); 5528097973089420749dcd1ab4974a629c2466b31ccAngus Kong } else { 5538097973089420749dcd1ab4974a629c2466b31ccAngus Kong mParamsToSet.setGpsTimestamp(gpsData.timeStamp); 5548097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (gpsData.processingMethod != null) { 5558097973089420749dcd1ab4974a629c2466b31ccAngus Kong // It's a hack since we always use GPS time stamp but does 5568097973089420749dcd1ab4974a629c2466b31ccAngus Kong // not use other fields sometimes. Setting processing 5578097973089420749dcd1ab4974a629c2466b31ccAngus Kong // method to null means the other fields should not be used. 5588097973089420749dcd1ab4974a629c2466b31ccAngus Kong mParamsToSet.setGpsAltitude(gpsData.altitude); 5598097973089420749dcd1ab4974a629c2466b31ccAngus Kong mParamsToSet.setGpsLatitude(gpsData.latitude); 5608097973089420749dcd1ab4974a629c2466b31ccAngus Kong mParamsToSet.setGpsLongitude(gpsData.longitude); 5618097973089420749dcd1ab4974a629c2466b31ccAngus Kong mParamsToSet.setGpsProcessingMethod(gpsData.processingMethod); 5628097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 5638097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 5648097973089420749dcd1ab4974a629c2466b31ccAngus Kong 5658097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 566bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 567bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 568bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 56960520c4df78e595964605cf8acfa21bbafaeba84Angus Kong public void openCamera(final Handler handler, final int cameraId, 57060520c4df78e595964605cf8acfa21bbafaeba84Angus Kong final CameraOpenCallback callback) { 571bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 572bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 573bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 574cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.OPEN_CAMERA, cameraId, 0, 575bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong CameraOpenCallbackForward.getNewInstance(handler, callback)).sendToTarget(); 576bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 577bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 578bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 579bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 58060520c4df78e595964605cf8acfa21bbafaeba84Angus Kong @Override 58160520c4df78e595964605cf8acfa21bbafaeba84Angus Kong public void closeCamera(CameraProxy camera, boolean synced) { 58260520c4df78e595964605cf8acfa21bbafaeba84Angus Kong if (synced) { 58360520c4df78e595964605cf8acfa21bbafaeba84Angus Kong final WaitDoneBundle bundle = new WaitDoneBundle(); 58460520c4df78e595964605cf8acfa21bbafaeba84Angus Kong 58560520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mDispatchThread.runJobSync(new Runnable() { 58660520c4df78e595964605cf8acfa21bbafaeba84Angus Kong @Override 58760520c4df78e595964605cf8acfa21bbafaeba84Angus Kong public void run() { 588cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.RELEASE).sendToTarget(); 58960520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mCameraHandler.post(bundle.mUnlockRunnable); 59060520c4df78e595964605cf8acfa21bbafaeba84Angus Kong } 59160520c4df78e595964605cf8acfa21bbafaeba84Angus Kong }, bundle.mWaitLock, CAMERA_OPERATION_TIMEOUT_MS, "camera release"); 59260520c4df78e595964605cf8acfa21bbafaeba84Angus Kong } else { 59360520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mDispatchThread.runJob(new Runnable() { 59460520c4df78e595964605cf8acfa21bbafaeba84Angus Kong @Override 59560520c4df78e595964605cf8acfa21bbafaeba84Angus Kong public void run() { 59660520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mCameraHandler.removeCallbacksAndMessages(null); 597cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.RELEASE).sendToTarget(); 59860520c4df78e595964605cf8acfa21bbafaeba84Angus Kong } 59960520c4df78e595964605cf8acfa21bbafaeba84Angus Kong }); 60060520c4df78e595964605cf8acfa21bbafaeba84Angus Kong } 60160520c4df78e595964605cf8acfa21bbafaeba84Angus Kong } 60260520c4df78e595964605cf8acfa21bbafaeba84Angus Kong 603bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 604bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A class which implements {@link CameraManager.CameraProxy} and 605bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * camera handler thread. 606bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 607bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private class AndroidCameraProxyImpl implements CameraManager.CameraProxy { 608bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final int mCameraId; 609bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /* TODO: remove this Camera instance. */ 610bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Camera mCamera; 611c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong private final AndroidCameraCapabilities mCapabilities; 612bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 613c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong private AndroidCameraProxyImpl(int cameraId, Camera camera, 614c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong AndroidCameraCapabilities capabilities) { 615bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 616bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraId = cameraId; 617c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong mCapabilities = capabilities; 618bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 619bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 620bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 621bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public android.hardware.Camera getCamera() { 622bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return mCamera; 623bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 624bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 625bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 626bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public int getCameraId() { 627bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return mCameraId; 628bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 629bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 630bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 631c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong public CameraCapabilities getCapabilities() { 632c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong return new AndroidCameraCapabilities(mCapabilities); 633c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong } 634c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong 635c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong @Override 636bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void reconnect(final Handler handler, final CameraOpenCallback cb) { 637bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 638bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 639bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 640cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.RECONNECT, mCameraId, 0, 641bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong CameraOpenCallbackForward.getNewInstance(handler, cb)).sendToTarget(); 642bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 643bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 644bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 645bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 646bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 647bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void unlock() { 648bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final WaitDoneBundle bundle = new WaitDoneBundle(); 649bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJobSync(new Runnable() { 650bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 651bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 652cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.sendEmptyMessage(CameraActions.UNLOCK); 653bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.post(bundle.mUnlockRunnable); 654bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 655bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }, bundle.mWaitLock, CAMERA_OPERATION_TIMEOUT_MS, "camera unlock"); 656bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 657bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 658bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 659bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void lock() { 660bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 661bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 662bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 663cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.sendEmptyMessage(CameraActions.LOCK); 664bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 665bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 666bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 667bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 668bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 669bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setPreviewTexture(final SurfaceTexture surfaceTexture) { 670bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 671bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 672bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 673cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler 674cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher .obtainMessage(CameraActions.SET_PREVIEW_TEXTURE_ASYNC, surfaceTexture) 675bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 676bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 677bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 678bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 679bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 680bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 681bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setPreviewTextureSync(final SurfaceTexture surfaceTexture) { 682bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final WaitDoneBundle bundle = new WaitDoneBundle(); 683bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJobSync(new Runnable() { 684bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 685bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 686cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler 687cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher .obtainMessage(CameraActions.SET_PREVIEW_TEXTURE_ASYNC, surfaceTexture) 688bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 689bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.post(bundle.mUnlockRunnable); 690bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 691bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }, bundle.mWaitLock, CAMERA_OPERATION_TIMEOUT_MS, "set preview texture"); 692bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 693bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 694bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 695bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setPreviewDisplay(final SurfaceHolder surfaceHolder) { 696bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 697bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 698bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 699cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler 700cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher .obtainMessage(CameraActions.SET_PREVIEW_DISPLAY_ASYNC, surfaceHolder) 701bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 702bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 703bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 704bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 705bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 706bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 707bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void startPreview() { 708bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 709bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 710bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 711cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler 712cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher .obtainMessage(CameraActions.START_PREVIEW_ASYNC, null).sendToTarget(); 713bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 714bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 715bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 716bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 717bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 718bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void startPreviewWithCallback(final Handler handler, 719bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraStartPreviewCallback cb) { 720bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 721bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 722bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 723cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.START_PREVIEW_ASYNC, 724bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong CameraStartPreviewCallbackForward.getNewInstance(handler, cb)).sendToTarget(); 725bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 726bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 727bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 728bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 729bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 730bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void stopPreview() { 731bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final WaitDoneBundle bundle = new WaitDoneBundle(); 732bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJobSync(new Runnable() { 733bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 734bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 735cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.sendEmptyMessage(CameraActions.STOP_PREVIEW); 736bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.post(bundle.mUnlockRunnable); 737bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 738bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }, bundle.mWaitLock, CAMERA_OPERATION_TIMEOUT_MS, "stop preview"); 739bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 740bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 741bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 742bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setPreviewDataCallback( 743bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final Handler handler, final CameraPreviewDataCallback cb) { 744bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 745bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 746bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 747cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.SET_PREVIEW_CALLBACK, 748cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher PreviewCallbackForward.getNewInstance( 749cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher handler, AndroidCameraProxyImpl.this, cb)) 750bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 751bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 752bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 753bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 754bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 755bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setOneShotPreviewCallback(final Handler handler, 756bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraPreviewDataCallback cb) { 757bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 758bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 759bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 760cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.SET_ONE_SHOT_PREVIEW_CALLBACK, 761bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong PreviewCallbackForward 762bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .getNewInstance(handler, AndroidCameraProxyImpl.this, cb)) 763bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 764bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 765bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 766bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 767bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 768bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 769bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setPreviewDataCallbackWithBuffer( 770bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final Handler handler, final CameraPreviewDataCallback cb) { 771bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 772bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 773bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 774cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.SET_PREVIEW_CALLBACK_WITH_BUFFER, 775bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong PreviewCallbackForward 776bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .getNewInstance(handler, AndroidCameraProxyImpl.this, cb)) 777bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 778bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 779bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 780bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 781bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 782bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 783bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void addCallbackBuffer(final byte[] callbackBuffer) { 784bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 785bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 786bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 787cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.ADD_CALLBACK_BUFFER, callbackBuffer) 788bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 789bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 790bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 791bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 792bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 793bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 794bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void autoFocus(final Handler handler, final CameraAFCallback cb) { 795bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final AutoFocusCallback afCallback = new AutoFocusCallback() { 796bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 797bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onAutoFocus(final boolean b, Camera camera) { 798cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher if (mCameraState.getState() != CameraStateHolder.CAMERA_FOCUSING) { 799bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.w(TAG, "onAutoFocus callback returning when not focusing"); 800bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } else { 801cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraState.setState(CameraStateHolder.CAMERA_IDLE); 802bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 803bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong handler.post(new Runnable() { 804bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 805bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 806bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong cb.onAutoFocus(b, AndroidCameraProxyImpl.this); 807bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 808bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 809bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 810bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }; 811bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 812bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 813bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 814cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraState.waitForStates(CameraStateHolder.CAMERA_IDLE); 815cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.AUTO_FOCUS, afCallback) 816cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher .sendToTarget(); 817bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 818bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 819bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 820bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 821bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 822bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void cancelAutoFocus() { 823bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 824bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 825bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 826cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.removeMessages(CameraActions.AUTO_FOCUS); 827cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.sendEmptyMessage(CameraActions.CANCEL_AUTO_FOCUS); 828bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 829bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 830bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 831bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 832bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 833bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 834bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setAutoFocusMoveCallback( 835bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final Handler handler, final CameraAFMoveCallback cb) { 836bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 837bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 838bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 839cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.SET_AUTO_FOCUS_MOVE_CALLBACK, 840cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher AFMoveCallbackForward.getNewInstance( 841cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher handler, AndroidCameraProxyImpl.this, cb)) 842bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 843bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 844bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 845bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 846bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 847bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 848bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void takePicture( 849bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final Handler handler, final CameraShutterCallback shutter, 850bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraPictureCallback raw, final CameraPictureCallback post, 851bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraPictureCallback jpeg) { 852bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final PictureCallback jpegCallback = new PictureCallback() { 853bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 854bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onPictureTaken(final byte[] data, Camera camera) { 855cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher if (mCameraState.getState() != CameraStateHolder.CAMERA_CAPTURING) { 85660520c4df78e595964605cf8acfa21bbafaeba84Angus Kong Log.w(TAG, "picture callback returning when not capturing"); 857bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } else { 858cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraState.setState(CameraStateHolder.CAMERA_IDLE); 859bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 860bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong handler.post(new Runnable() { 861bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 862bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 863bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong jpeg.onPictureTaken(data, AndroidCameraProxyImpl.this); 864bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 865bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 866bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 867bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }; 868bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 869bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 870bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 871bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 872cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraState.waitForStates( 873cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher CameraStateHolder.CAMERA_IDLE | CameraStateHolder.CAMERA_UNLOCKED); 874bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.requestTakePicture(ShutterCallbackForward 8758097973089420749dcd1ab4974a629c2466b31ccAngus Kong .getNewInstance(handler, AndroidCameraProxyImpl.this, shutter), 876bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong PictureCallbackForward 877bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .getNewInstance(handler, AndroidCameraProxyImpl.this, raw), 878bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong PictureCallbackForward 879bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .getNewInstance(handler, AndroidCameraProxyImpl.this, post), 8808097973089420749dcd1ab4974a629c2466b31ccAngus Kong jpegCallback 8818097973089420749dcd1ab4974a629c2466b31ccAngus Kong ); 882bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 883bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 884bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 885bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 886bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 887bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setDisplayOrientation(final int degrees) { 888bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 889bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 890bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 891cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.SET_DISPLAY_ORIENTATION, degrees, 0) 892bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 893bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 894bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 895bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 896bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 897bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 898bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setZoomChangeListener(final OnZoomChangeListener listener) { 899bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 900bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 901bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 902cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.SET_ZOOM_CHANGE_LISTENER, listener) 903cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher .sendToTarget(); 904bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 905bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 906bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 907bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 908bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 909bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setFaceDetectionCallback(final Handler handler, 910bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraFaceDetectionCallback cb) { 911bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 912bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 913bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 914cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.SET_FACE_DETECTION_LISTENER, 915bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong FaceDetectionCallbackForward 916bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .getNewInstance(handler, AndroidCameraProxyImpl.this, cb)) 917bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 918bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 919bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 920bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 921bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 922bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 923bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void startFaceDetection() { 924bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 925bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 926bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 927cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.sendEmptyMessage(CameraActions.START_FACE_DETECTION); 928bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 929bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 930bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 931bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 932bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 933bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void stopFaceDetection() { 934bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 935bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 936bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 937cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.sendEmptyMessage(CameraActions.STOP_FACE_DETECTION); 938bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 939bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 940bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 941bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 942bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 943bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setErrorCallback(final Handler handler, final CameraErrorCallback cb) { 944bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 945bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 946bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 947cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.SET_ERROR_CALLBACK, 948cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher ErrorCallbackForward.getNewInstance( 949cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher handler, AndroidCameraProxyImpl.this, cb)) 950cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher .sendToTarget(); 951bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 952bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 953bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 954bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 955bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 956bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setParameters(final Parameters params) { 957bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (params == null) { 958bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.v(TAG, "null parameters in setParameters()"); 959bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return; 960bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 961bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final String flattenedParameters = params.flatten(); 962bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 963bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 964bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 965cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraState.waitForStates( 966cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher CameraStateHolder.CAMERA_IDLE | CameraStateHolder.CAMERA_UNLOCKED); 967cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.SET_PARAMETERS, flattenedParameters) 968cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher .sendToTarget(); 969bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 970bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 971bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 972bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 973bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 974bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public Parameters getParameters() { 975bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final WaitDoneBundle bundle = new WaitDoneBundle(); 976bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJobSync(new Runnable() { 977bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 978bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 979cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.sendEmptyMessage(CameraActions.GET_PARAMETERS); 980bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.post(bundle.mUnlockRunnable); 981bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 982bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }, bundle.mWaitLock, CAMERA_OPERATION_TIMEOUT_MS, "get parameters"); 983bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return mParameters; 984bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 985bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 986bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 9878097973089420749dcd1ab4974a629c2466b31ccAngus Kong public CameraSettings getSettings() { 9888097973089420749dcd1ab4974a629c2466b31ccAngus Kong return new AndroidCameraSettings(mCapabilities, getParameters()); 9898097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 9908097973089420749dcd1ab4974a629c2466b31ccAngus Kong 9918097973089420749dcd1ab4974a629c2466b31ccAngus Kong @Override 9928097973089420749dcd1ab4974a629c2466b31ccAngus Kong public boolean applySettings(final CameraSettings settings) { 9938097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (settings == null) { 9948097973089420749dcd1ab4974a629c2466b31ccAngus Kong Log.v(TAG, "null parameters in applySettings()"); 9958097973089420749dcd1ab4974a629c2466b31ccAngus Kong return false; 9968097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 9978097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (!mCapabilities.supports(settings)) { 9988097973089420749dcd1ab4974a629c2466b31ccAngus Kong return false; 9998097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 10008097973089420749dcd1ab4974a629c2466b31ccAngus Kong 10018097973089420749dcd1ab4974a629c2466b31ccAngus Kong final CameraSettings copyOfSettings = new CameraSettings(settings); 10028097973089420749dcd1ab4974a629c2466b31ccAngus Kong mDispatchThread.runJob(new Runnable() { 10038097973089420749dcd1ab4974a629c2466b31ccAngus Kong @Override 10048097973089420749dcd1ab4974a629c2466b31ccAngus Kong public void run() { 10058097973089420749dcd1ab4974a629c2466b31ccAngus Kong mCameraState.waitForStates( 10068097973089420749dcd1ab4974a629c2466b31ccAngus Kong CameraStateHolder.CAMERA_IDLE | CameraStateHolder.CAMERA_UNLOCKED); 10078097973089420749dcd1ab4974a629c2466b31ccAngus Kong mCameraHandler.obtainMessage(CameraActions.APPLY_SETTINGS, copyOfSettings) 10088097973089420749dcd1ab4974a629c2466b31ccAngus Kong .sendToTarget(); 10098097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 10108097973089420749dcd1ab4974a629c2466b31ccAngus Kong }); 10118097973089420749dcd1ab4974a629c2466b31ccAngus Kong return true; 10128097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 10138097973089420749dcd1ab4974a629c2466b31ccAngus Kong 10148097973089420749dcd1ab4974a629c2466b31ccAngus Kong @Override 10158097973089420749dcd1ab4974a629c2466b31ccAngus Kong public void refreshSettings() { 1016bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 1017bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1018bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1019cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.sendEmptyMessage(CameraActions.REFRESH_PARAMETERS); 1020bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1021bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1022bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1023bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1024bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1025bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void enableShutterSound(final boolean enable) { 1026bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 1027bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1028bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1029cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler 1030cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher .obtainMessage(CameraActions.ENABLE_SHUTTER_SOUND, (enable ? 1 : 0), 0) 1031bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 1032bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1033bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1034bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1035bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1036bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1037bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class WaitDoneBundle { 1038bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public Runnable mUnlockRunnable; 1039bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Object mWaitLock; 1040bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1041bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong WaitDoneBundle() { 1042bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mWaitLock = new Object(); 1043bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mUnlockRunnable = new Runnable() { 1044bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1045bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1046bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong synchronized (mWaitLock) { 1047bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mWaitLock.notifyAll(); 1048bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1049bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1050bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }; 1051bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1052bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1053bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1054bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1055bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A helper class to forward AutoFocusCallback to another thread. 1056bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1057bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class AFCallbackForward implements AutoFocusCallback { 1058bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1059bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1060bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraAFCallback mCallback; 1061bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1062bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1063bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link AFCallbackForward}. 1064bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1065bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1066bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1067bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1068bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link AFCallbackForward}, 1069bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameter is null. 1070bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1071bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static AFCallbackForward getNewInstance( 1072bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraAFCallback cb) { 1073bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1074bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1075bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1076bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new AFCallbackForward(handler, camera, cb); 1077bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1078bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1079bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private AFCallbackForward( 1080bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraAFCallback cb) { 1081bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1082bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1083bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1084bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1085bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1086bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1087bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onAutoFocus(final boolean b, Camera camera) { 1088bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1089bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1090bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1091bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onAutoFocus(b, mCamera); 1092bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1093bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1094bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1095bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1096bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1097bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1098bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A helper class to forward ErrorCallback to another thread. 1099bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1100bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class ErrorCallbackForward implements Camera.ErrorCallback { 1101bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1102bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1103bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraErrorCallback mCallback; 1104bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1105bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1106bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link AFCallbackForward}. 1107bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1108bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1109bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1110bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1111bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link AFCallbackForward}, 1112bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameter is null. 1113bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1114bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static ErrorCallbackForward getNewInstance( 1115bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraErrorCallback cb) { 1116bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1117bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1118bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1119bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new ErrorCallbackForward(handler, camera, cb); 1120bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1121bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1122bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private ErrorCallbackForward( 1123bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraErrorCallback cb) { 1124bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1125bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1126bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1127bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1128bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1129bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1130bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onError(final int error, Camera camera) { 1131bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1132bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1133bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1134bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onError(error, mCamera); 1135bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1136bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1137bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1138bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1139bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1140bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** A helper class to forward AutoFocusMoveCallback to another thread. */ 1141bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 1142bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class AFMoveCallbackForward implements AutoFocusMoveCallback { 1143bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1144bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraAFMoveCallback mCallback; 1145bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1146bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1147bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1148bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link AFMoveCallbackForward}. 1149bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1150bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1151bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1152bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1153bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link AFMoveCallbackForward}, 1154bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameter is null. 1155bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1156bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static AFMoveCallbackForward getNewInstance( 1157bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraAFMoveCallback cb) { 1158bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1159bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1160bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1161bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new AFMoveCallbackForward(handler, camera, cb); 1162bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1163bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1164bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private AFMoveCallbackForward( 1165bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraAFMoveCallback cb) { 1166bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1167bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1168bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1169bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1170bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1171bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1172bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onAutoFocusMoving( 1173bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final boolean moving, android.hardware.Camera camera) { 1174bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1175bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1176bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1177bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onAutoFocusMoving(moving, mCamera); 1178bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1179bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1180bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1181bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1182bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1183bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1184bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A helper class to forward ShutterCallback to to another thread. 1185bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1186bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class ShutterCallbackForward implements ShutterCallback { 1187bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1188bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraShutterCallback mCallback; 1189bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1190bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1191bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1192bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link ShutterCallbackForward}. 1193bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1194bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1195bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1196bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1197bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link ShutterCallbackForward}, 1198bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameter is null. 1199bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1200bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static ShutterCallbackForward getNewInstance( 1201bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraShutterCallback cb) { 1202bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1203bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1204bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1205bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new ShutterCallbackForward(handler, camera, cb); 1206bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1207bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1208bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private ShutterCallbackForward( 1209bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraShutterCallback cb) { 1210bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1211bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1212bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1213bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1214bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1215bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1216bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onShutter() { 1217bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1218bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1219bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1220bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onShutter(mCamera); 1221bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1222bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1223bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1224bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1225bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1226bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1227bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A helper class to forward PictureCallback to another thread. 1228bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1229bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class PictureCallbackForward implements PictureCallback { 1230bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1231bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraPictureCallback mCallback; 1232bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1233bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1234bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1235bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link PictureCallbackForward}. 1236bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1237bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1238bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1239bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1240bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link PictureCallbackForward}, 1241bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameters is null. 1242bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1243bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static PictureCallbackForward getNewInstance( 1244bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraPictureCallback cb) { 1245bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1246bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1247bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1248bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new PictureCallbackForward(handler, camera, cb); 1249bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1250bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1251bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private PictureCallbackForward( 1252bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraPictureCallback cb) { 1253bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1254bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1255bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1256bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1257bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1258bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1259bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onPictureTaken( 1260bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final byte[] data, android.hardware.Camera camera) { 1261bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1262bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1263bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1264bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onPictureTaken(data, mCamera); 1265bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1266bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1267bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1268bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1269bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1270bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1271bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A helper class to forward PreviewCallback to another thread. 1272bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1273bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class PreviewCallbackForward implements PreviewCallback { 1274bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1275bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraPreviewDataCallback mCallback; 1276bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1277bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1278bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1279bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link PreviewCallbackForward}. 1280bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1281bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1282bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1283bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1284bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link PreviewCallbackForward}, 1285bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameters is null. 1286bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1287bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static PreviewCallbackForward getNewInstance( 1288bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraPreviewDataCallback cb) { 1289bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1290bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1291bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1292bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new PreviewCallbackForward(handler, camera, cb); 1293bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1294bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1295bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private PreviewCallbackForward( 1296bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraPreviewDataCallback cb) { 1297bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1298bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1299bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1300bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1301bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1302bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1303bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onPreviewFrame( 1304bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final byte[] data, android.hardware.Camera camera) { 1305bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1306bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1307bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1308bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onPreviewFrame(data, mCamera); 1309bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1310bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1311bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1312bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1313bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1314bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class FaceDetectionCallbackForward implements FaceDetectionListener { 1315bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1316bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraFaceDetectionCallback mCallback; 1317bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1318bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1319bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1320bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link FaceDetectionCallbackForward}. 1321bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1322bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1323bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1324bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1325bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link FaceDetectionCallbackForward}, 1326bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameter is null. 1327bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1328bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static FaceDetectionCallbackForward getNewInstance( 1329bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraFaceDetectionCallback cb) { 1330bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1331bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1332bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1333bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new FaceDetectionCallbackForward(handler, camera, cb); 1334bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1335bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1336bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private FaceDetectionCallbackForward( 1337bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraFaceDetectionCallback cb) { 1338bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1339bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1340bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1341bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1342bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1343bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1344bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onFaceDetection( 1345bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final Camera.Face[] faces, Camera camera) { 1346bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1347bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1348bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1349bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onFaceDetection(faces, mCamera); 1350bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1351bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1352bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1353bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1354bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong} 1355