AndroidCameraAgentImpl.java revision 2d01b8e2b5ad30ce3c442799cad4c3d26607fc6f
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; 419d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucherimport java.util.Collections; 429d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucherimport java.util.List; 4301e7c02174ef268b6d6daaa5a5bb4f752d55964cAngus Kongimport java.util.StringTokenizer; 44bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 45bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong/** 464f425ba476d62b4be7078f2084af37cf306b31c6Sol Boucher * A class to implement {@link CameraAgent} of the Android camera framework. 47bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 48a0842b40441db5332a5290f941021636b1182761Sol Boucherclass AndroidCameraAgentImpl extends CameraAgent { 49a0842b40441db5332a5290f941021636b1182761Sol Boucher private static final Log.Tag TAG = new Log.Tag("AndCamAgntImp"); 50bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 51b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher private CameraDeviceInfo.Characteristics mCharacteristics; 528097973089420749dcd1ab4974a629c2466b31ccAngus Kong private AndroidCameraCapabilities mCapabilities; 53bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 54bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraHandler mCameraHandler; 55bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final HandlerThread mCameraHandlerThread; 56bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraStateHolder mCameraState; 57bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final DispatchThread mDispatchThread; 582d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu private CameraExceptionHandler mExceptionHandler; 59bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 604f425ba476d62b4be7078f2084af37cf306b31c6Sol Boucher AndroidCameraAgentImpl() { 61bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandlerThread = new HandlerThread("Camera Handler Thread"); 62bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandlerThread.start(); 632d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mCameraHandler = new CameraHandler(this, mCameraHandlerThread.getLooper()); 642d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mExceptionHandler = new CameraExceptionHandler(mCameraHandler); 65a0842b40441db5332a5290f941021636b1182761Sol Boucher mCameraState = new AndroidCameraStateHolder(); 66cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mDispatchThread = new DispatchThread(mCameraHandler, mCameraHandlerThread); 67bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.start(); 68bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 69bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 70bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 71bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void recycle() { 7260520c4df78e595964605cf8acfa21bbafaeba84Angus Kong closeCamera(null, true); 73bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.end(); 742d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mCameraState.invalidate(); 75bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 767e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 777e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong @Override 787e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong public CameraDeviceInfo getCameraDeviceInfo() { 797e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return AndroidCameraDeviceInfo.create(); 807e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 817e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 82a0842b40441db5332a5290f941021636b1182761Sol Boucher @Override 83a0842b40441db5332a5290f941021636b1182761Sol Boucher protected Handler getCameraHandler() { 84a0842b40441db5332a5290f941021636b1182761Sol Boucher return mCameraHandler; 85a0842b40441db5332a5290f941021636b1182761Sol Boucher } 86a0842b40441db5332a5290f941021636b1182761Sol Boucher 87a0842b40441db5332a5290f941021636b1182761Sol Boucher @Override 88a0842b40441db5332a5290f941021636b1182761Sol Boucher protected DispatchThread getDispatchThread() { 89a0842b40441db5332a5290f941021636b1182761Sol Boucher return mDispatchThread; 90a0842b40441db5332a5290f941021636b1182761Sol Boucher } 91a0842b40441db5332a5290f941021636b1182761Sol Boucher 922d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu @Override 932d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu protected CameraStateHolder getCameraState() { 942d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu return mCameraState; 952d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 962d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu 972d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu @Override 982d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu protected CameraExceptionHandler getCameraExceptionHandler() { 992d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu return mExceptionHandler; 1002d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 1012d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu 1022d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu @Override 1032d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public void setCameraExceptionHandler(CameraExceptionHandler exceptionHandler) { 1042d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mExceptionHandler = exceptionHandler; 1052d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 1062d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu 1077e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong private static class AndroidCameraDeviceInfo implements CameraDeviceInfo { 1087e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong private final Camera.CameraInfo[] mCameraInfos; 1097e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong private final int mNumberOfCameras; 1107e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong private final int mFirstBackCameraId; 1117e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong private final int mFirstFrontCameraId; 1127e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1137e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong private AndroidCameraDeviceInfo(Camera.CameraInfo[] info, int numberOfCameras, 1147e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong int firstBackCameraId, int firstFrontCameraId) { 1157e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1167e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong mCameraInfos = info; 1177e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong mNumberOfCameras = numberOfCameras; 1187e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong mFirstBackCameraId = firstBackCameraId; 1197e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong mFirstFrontCameraId = firstFrontCameraId; 1207e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1217e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1227e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong public static AndroidCameraDeviceInfo create() { 1237e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong int numberOfCameras; 1247e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong Camera.CameraInfo[] cameraInfos; 1257e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong try { 1267e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong numberOfCameras = Camera.getNumberOfCameras(); 1277e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong cameraInfos = new Camera.CameraInfo[numberOfCameras]; 1287e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong for (int i = 0; i < numberOfCameras; i++) { 1297e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong cameraInfos[i] = new Camera.CameraInfo(); 1307e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong Camera.getCameraInfo(i, cameraInfos[i]); 1317e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1327e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } catch (RuntimeException ex) { 133eb07f0c4c693566f6f258e84426f518e90513c11Alan Newberger Log.e(TAG, "Exception while creating CameraDeviceInfo", ex); 1347e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return null; 1357e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1367e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1377e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong int firstFront = NO_DEVICE; 1387e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong int firstBack = NO_DEVICE; 1397e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong // Get the first (smallest) back and first front camera id. 1407e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong for (int i = numberOfCameras - 1; i >= 0; i--) { 1417e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong if (cameraInfos[i].facing == Camera.CameraInfo.CAMERA_FACING_BACK) { 1427e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong firstBack = i; 1437e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } else { 1447e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong if (cameraInfos[i].facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 1457e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong firstFront = i; 1467e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1477e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1487e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1497e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1507e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return new AndroidCameraDeviceInfo(cameraInfos, numberOfCameras, firstBack, firstFront); 1517e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1527e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1537e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong @Override 154b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher public Characteristics getCharacteristics(int cameraId) { 155b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher Camera.CameraInfo info = mCameraInfos[cameraId]; 156b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher if (info != null) { 157b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher return new AndroidCharacteristics(info); 158b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher } else { 159b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher return null; 160b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher } 1617e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1627e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1637e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong @Override 1647e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong public int getNumberOfCameras() { 1657e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return mNumberOfCameras; 1667e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1677e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1687e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong @Override 1697e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong public int getFirstBackCameraId() { 1707e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return mFirstBackCameraId; 1717e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1727e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1737e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong @Override 1747e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong public int getFirstFrontCameraId() { 1757e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return mFirstFrontCameraId; 1767e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 177b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher 178de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher private static class AndroidCharacteristics extends Characteristics { 179b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher private Camera.CameraInfo mCameraInfo; 180b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher 181b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher AndroidCharacteristics(Camera.CameraInfo cameraInfo) { 182b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher mCameraInfo = cameraInfo; 183b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher } 184b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher 185b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher @Override 186b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher public boolean isFacingBack() { 187b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher return mCameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK; 188b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher } 189b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher 190b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher @Override 191b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher public boolean isFacingFront() { 192b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher return mCameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT; 193b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher } 194b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher 195b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher @Override 196b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher public int getSensorOrientation() { 197b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher return mCameraInfo.orientation; 198b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher } 199b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher 200b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher @Override 201b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher public boolean canDisableShutterSound() { 202b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher return mCameraInfo.canDisableShutterSound; 203b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher } 204b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher } 2057e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 206bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 2078447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger private static class ParametersCache { 2088447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger private Parameters mParameters; 2098447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger private Camera mCamera; 2108447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger 2118447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger public ParametersCache(Camera camera) { 2128447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger mCamera = camera; 2138447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger } 2148447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger 2158447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger public synchronized void invalidate() { 2168447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger mParameters = null; 2178447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger } 2188447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger 2198447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger /** 2208447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger * Access parameters from the cache. If cache is empty, block by 2218447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger * retrieving parameters directly from Camera, but if cache is present, 2228447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger * returns immediately. 2238447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger */ 2248447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger public synchronized Parameters getBlocking() { 2258447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger if (mParameters == null) { 2268447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger mParameters = mCamera.getParameters(); 227e4094bd3b85ce20e81a1677319192ed2274d0525Alan Newberger if (mParameters == null) { 228e4094bd3b85ce20e81a1677319192ed2274d0525Alan Newberger Log.e(TAG, "Camera object returned null parameters!"); 229e4094bd3b85ce20e81a1677319192ed2274d0525Alan Newberger throw new IllegalStateException("camera.getParameters returned null"); 230e4094bd3b85ce20e81a1677319192ed2274d0525Alan Newberger } 2318447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger } 2328447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger return mParameters; 2338447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger } 2348447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger } 2358447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger 236bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 237bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * The handler on which the actual camera operations happen. 238bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 239cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher private class CameraHandler extends HistoryHandler { 2402d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu private CameraAgent mAgent; 241bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private Camera mCamera; 24260520c4df78e595964605cf8acfa21bbafaeba84Angus Kong private int mCameraId; 2438447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger private ParametersCache mParameterCache; 2446a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin private int mCancelAfPending = 0; 245bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 246bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private class CaptureCallbacks { 247bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public final ShutterCallback mShutter; 248bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public final PictureCallback mRaw; 249bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public final PictureCallback mPostView; 250bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public final PictureCallback mJpeg; 251bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 252bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong CaptureCallbacks(ShutterCallback shutter, PictureCallback raw, PictureCallback postView, 253bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong PictureCallback jpeg) { 254bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mShutter = shutter; 255bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mRaw = raw; 256bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mPostView = postView; 257bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mJpeg = jpeg; 258bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 259bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 260bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 2612d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu CameraHandler(CameraAgent agent, Looper looper) { 262bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong super(looper); 2632d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mAgent = agent; 264bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 265bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 266bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void startFaceDetection() { 267bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.startFaceDetection(); 268bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 269bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 270bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void stopFaceDetection() { 271bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.stopFaceDetection(); 272bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 273bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 274bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void setFaceDetectionListener(FaceDetectionListener listener) { 275bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setFaceDetectionListener(listener); 276bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 277bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 278bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void setPreviewTexture(Object surfaceTexture) { 279bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 280bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setPreviewTexture((SurfaceTexture) surfaceTexture); 281bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (IOException e) { 282bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.e(TAG, "Could not set preview texture", e); 283bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 284bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 285bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 286bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) 287bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void enableShutterSound(boolean enable) { 288bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.enableShutterSound(enable); 289bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 290bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 291bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 292bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void setAutoFocusMoveCallback( 293bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong android.hardware.Camera camera, Object cb) { 294bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 295bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong camera.setAutoFocusMoveCallback((AutoFocusMoveCallback) cb); 296bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (RuntimeException ex) { 297bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.w(TAG, ex.getMessage()); 298bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 299bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 300bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 301bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void requestTakePicture( 302bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final ShutterCallback shutter, 303bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final PictureCallback raw, 304bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final PictureCallback postView, 305bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final PictureCallback jpeg) { 306bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CaptureCallbacks callbacks = new CaptureCallbacks(shutter, raw, postView, jpeg); 307cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher obtainMessage(CameraActions.CAPTURE_PHOTO, callbacks).sendToTarget(); 308bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 309bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 310bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 311bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * This method does not deal with the API level check. Everyone should 312bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * check first for supported operations before sending message to this handler. 313bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 314bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 315bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void handleMessage(final Message msg) { 316cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher super.handleMessage(msg); 3172d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu 3182d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu if (getCameraState().isInvalid()) { 3192d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu Log.v(TAG, "Skip handleMessage - action = '" + CameraActions.stringify(msg.what) + "'"); 3202d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu return; 3212d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 3226a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin Log.v(TAG, "handleMessage - action = '" + CameraActions.stringify(msg.what) + "'"); 3232d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu 324bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 325bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong switch (msg.what) { 326cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.OPEN_CAMERA: { 327bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraOpenCallback openCallback = (CameraOpenCallback) msg.obj; 328bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final int cameraId = msg.arg1; 329a0842b40441db5332a5290f941021636b1182761Sol Boucher if (mCameraState.getState() != AndroidCameraStateHolder.CAMERA_UNOPENED) { 33060520c4df78e595964605cf8acfa21bbafaeba84Angus Kong openCallback.onDeviceOpenedAlready(cameraId, generateHistoryString(cameraId)); 331bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 332bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 333bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 33450f5b019ba3f333a09a1beb9667fd7290082dc31Sol Boucher Log.i(TAG, "Opening camera " + cameraId + " with camera1 API"); 335bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = android.hardware.Camera.open(cameraId); 336bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (mCamera != null) { 33760520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mCameraId = cameraId; 3388447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger mParameterCache = new ParametersCache(mCamera); 339bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 340b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher mCharacteristics = 341b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher AndroidCameraDeviceInfo.create().getCharacteristics(cameraId); 3428447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger mCapabilities = new AndroidCameraCapabilities( 3438447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger mParameterCache.getBlocking()); 344bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 345a0842b40441db5332a5290f941021636b1182761Sol Boucher mCameraState.setState(AndroidCameraStateHolder.CAMERA_IDLE); 346bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (openCallback != null) { 3472d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu CameraProxy cameraProxy = new AndroidCameraProxyImpl( 3482d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mAgent, cameraId, mCamera, mCharacteristics, mCapabilities); 3492d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu openCallback.onCameraOpened(cameraProxy); 350bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 351bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } else { 352bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (openCallback != null) { 353b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong openCallback.onDeviceOpenFailure(cameraId, generateHistoryString(cameraId)); 354bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 355bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 356bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 357bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 358bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 359cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.RELEASE: { 36060520c4df78e595964605cf8acfa21bbafaeba84Angus Kong if (mCamera != null) { 36160520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mCamera.release(); 362a0842b40441db5332a5290f941021636b1182761Sol Boucher mCameraState.setState(AndroidCameraStateHolder.CAMERA_UNOPENED); 36360520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mCamera = null; 36460520c4df78e595964605cf8acfa21bbafaeba84Angus Kong } else { 36560520c4df78e595964605cf8acfa21bbafaeba84Angus Kong Log.w(TAG, "Releasing camera without any camera opened."); 36660520c4df78e595964605cf8acfa21bbafaeba84Angus Kong } 367bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 368bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 369bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 370cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.RECONNECT: { 371bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraOpenCallbackForward cbForward = 372bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong (CameraOpenCallbackForward) msg.obj; 373bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final int cameraId = msg.arg1; 374bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 375bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.reconnect(); 376bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (IOException ex) { 377bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (cbForward != null) { 3782d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu cbForward.onReconnectionFailure(mAgent, generateHistoryString(mCameraId)); 379bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 380bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 381bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 382bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 383a0842b40441db5332a5290f941021636b1182761Sol Boucher mCameraState.setState(AndroidCameraStateHolder.CAMERA_IDLE); 384bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (cbForward != null) { 3858097973089420749dcd1ab4974a629c2466b31ccAngus Kong cbForward.onCameraOpened( 3862d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu new AndroidCameraProxyImpl(AndroidCameraAgentImpl.this, 3872d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu cameraId, mCamera, mCharacteristics, mCapabilities)); 388bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 389bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 390bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 391bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 392cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.UNLOCK: { 393bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.unlock(); 394a0842b40441db5332a5290f941021636b1182761Sol Boucher mCameraState.setState(AndroidCameraStateHolder.CAMERA_UNLOCKED); 395bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 396bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 397bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 398cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.LOCK: { 399bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.lock(); 400a0842b40441db5332a5290f941021636b1182761Sol Boucher mCameraState.setState(AndroidCameraStateHolder.CAMERA_IDLE); 401bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 402bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 403bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 4042569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher // TODO: Lock the CameraSettings object's sizes 405cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_PREVIEW_TEXTURE_ASYNC: { 406bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong setPreviewTexture(msg.obj); 407bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 408bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 409bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 410cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_PREVIEW_DISPLAY_ASYNC: { 411bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 412bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setPreviewDisplay((SurfaceHolder) msg.obj); 413bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (IOException e) { 414bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong throw new RuntimeException(e); 415bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 416bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 417bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 418bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 419cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.START_PREVIEW_ASYNC: { 420bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraStartPreviewCallbackForward cbForward = 421bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong (CameraStartPreviewCallbackForward) msg.obj; 422bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.startPreview(); 423bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (cbForward != null) { 424bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong cbForward.onPreviewStarted(); 425bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 426bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 427bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 428bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 4292569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher // TODO: Unlock the CameraSettings object's sizes 430cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.STOP_PREVIEW: { 431bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.stopPreview(); 432bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 433bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 434bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 435cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_PREVIEW_CALLBACK_WITH_BUFFER: { 436bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setPreviewCallbackWithBuffer((PreviewCallback) msg.obj); 437bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 438bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 439bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 440cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_ONE_SHOT_PREVIEW_CALLBACK: { 441bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setOneShotPreviewCallback((PreviewCallback) msg.obj); 442bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 443bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 444bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 445cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.ADD_CALLBACK_BUFFER: { 446bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.addCallbackBuffer((byte[]) msg.obj); 447bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 448bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 449bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 450cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.AUTO_FOCUS: { 4516a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin if (mCancelAfPending > 0) { 4526a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin Log.v(TAG, "handleMessage - Ignored AUTO_FOCUS because there was " 4536a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin + mCancelAfPending + " pending CANCEL_AUTO_FOCUS messages"); 4546a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin break; // ignore AF because a CANCEL_AF is queued after this 4556a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin } 456a0842b40441db5332a5290f941021636b1182761Sol Boucher mCameraState.setState(AndroidCameraStateHolder.CAMERA_FOCUSING); 457bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.autoFocus((AutoFocusCallback) msg.obj); 458bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 459bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 460bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 461cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.CANCEL_AUTO_FOCUS: { 4626a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin // Ignore all AFs that were already queued until we see 4636a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin // a CANCEL_AUTO_FOCUS_FINISH 4646a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin mCancelAfPending++; 465bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.cancelAutoFocus(); 466a0842b40441db5332a5290f941021636b1182761Sol Boucher mCameraState.setState(AndroidCameraStateHolder.CAMERA_IDLE); 467bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 468bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 469bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 4706a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin case CameraActions.CANCEL_AUTO_FOCUS_FINISH: { 4716a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin // Stop ignoring AUTO_FOCUS messages unless there are additional 4726a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin // CANCEL_AUTO_FOCUSes that were added 4736a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin mCancelAfPending--; 4746a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin break; 4756a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin } 4766a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin 477cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_AUTO_FOCUS_MOVE_CALLBACK: { 478bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong setAutoFocusMoveCallback(mCamera, msg.obj); 479bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 480bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 481bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 482cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_DISPLAY_ORIENTATION: { 483de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher // Update preview orientation 484de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mCamera.setDisplayOrientation( 485de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mCharacteristics.getPreviewOrientation(msg.arg1)); 486de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher // Only set the JPEG capture orientation if requested to do so; otherwise, 48725ee73acd2dbd6f60deef5306994fbf3a7997936Senpo Hu // capture in the sensor's physical orientation. (e.g., JPEG rotation is 48825ee73acd2dbd6f60deef5306994fbf3a7997936Senpo Hu // necessary in auto-rotate mode. 4898447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger Parameters parameters = mParameterCache.getBlocking(); 4908447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setRotation( 491de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher msg.arg2 > 0 ? mCharacteristics.getJpegOrientation(msg.arg1) : 0); 4928447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger mCamera.setParameters(parameters); 49325ee73acd2dbd6f60deef5306994fbf3a7997936Senpo Hu mParameterCache.invalidate(); 49425ee73acd2dbd6f60deef5306994fbf3a7997936Senpo Hu break; 49525ee73acd2dbd6f60deef5306994fbf3a7997936Senpo Hu } 49625ee73acd2dbd6f60deef5306994fbf3a7997936Senpo Hu 49725ee73acd2dbd6f60deef5306994fbf3a7997936Senpo Hu case CameraActions.SET_JPEG_ORIENTATION: { 49825ee73acd2dbd6f60deef5306994fbf3a7997936Senpo Hu Parameters parameters = mParameterCache.getBlocking(); 49925ee73acd2dbd6f60deef5306994fbf3a7997936Senpo Hu parameters.setRotation(msg.arg1); 50025ee73acd2dbd6f60deef5306994fbf3a7997936Senpo Hu mCamera.setParameters(parameters); 50125ee73acd2dbd6f60deef5306994fbf3a7997936Senpo Hu mParameterCache.invalidate(); 502bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 503bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 504bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 505cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_ZOOM_CHANGE_LISTENER: { 506bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setZoomChangeListener((OnZoomChangeListener) msg.obj); 507bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 508bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 509bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 510cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_FACE_DETECTION_LISTENER: { 511bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong setFaceDetectionListener((FaceDetectionListener) msg.obj); 512bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 513bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 514bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 515cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.START_FACE_DETECTION: { 516bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong startFaceDetection(); 517bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 518bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 519bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 520cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.STOP_FACE_DETECTION: { 521bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong stopFaceDetection(); 522bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 523bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 524bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 525cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_ERROR_CALLBACK: { 526bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setErrorCallback((ErrorCallback) msg.obj); 527bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 528bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 529bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 5308097973089420749dcd1ab4974a629c2466b31ccAngus Kong case CameraActions.APPLY_SETTINGS: { 5318447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger Parameters parameters = mParameterCache.getBlocking(); 5328097973089420749dcd1ab4974a629c2466b31ccAngus Kong CameraSettings settings = (CameraSettings) msg.obj; 5338447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger applySettingsToParameters(settings, parameters); 5348447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger mCamera.setParameters(parameters); 5358447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger mParameterCache.invalidate(); 5368097973089420749dcd1ab4974a629c2466b31ccAngus Kong break; 5378097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 5388097973089420749dcd1ab4974a629c2466b31ccAngus Kong 539cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_PARAMETERS: { 5408447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger Parameters parameters = mParameterCache.getBlocking(); 5418447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.unflatten((String) msg.obj); 5428447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger mCamera.setParameters(parameters); 5438447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger mParameterCache.invalidate(); 544bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 545bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 546bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 547cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.GET_PARAMETERS: { 5488447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger Parameters[] parametersHolder = (Parameters[]) msg.obj; 5498447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger Parameters parameters = mParameterCache.getBlocking(); 5508447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parametersHolder[0] = parameters; 551bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 552bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 553bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 554cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_PREVIEW_CALLBACK: { 555bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setPreviewCallback((PreviewCallback) msg.obj); 556bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 557bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 558bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 559cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.ENABLE_SHUTTER_SOUND: { 560bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong enableShutterSound((msg.arg1 == 1) ? true : false); 561bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 562bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 563bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 564cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.REFRESH_PARAMETERS: { 5658447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger mParameterCache.invalidate();; 566bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 567bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 568bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 569cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.CAPTURE_PHOTO: { 570a0842b40441db5332a5290f941021636b1182761Sol Boucher mCameraState.setState(AndroidCameraStateHolder.CAMERA_CAPTURING); 5712d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu CaptureCallbacks captureCallbacks = (CaptureCallbacks) msg.obj; 5722d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mCamera.takePicture( 5732d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu captureCallbacks.mShutter, 5742d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu captureCallbacks.mRaw, 5752d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu captureCallbacks.mPostView, 5762d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu captureCallbacks.mJpeg); 577bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 578bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 579bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 580bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong default: { 5812d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu Log.e(TAG, "Invalid CameraProxy message=" + msg.what); 582bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 583bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 5842d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } catch (final RuntimeException ex) { 5852d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu String cameraAction = CameraActions.stringify(msg.what); 5862d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu int cameraState = mCameraState.getState(); 5872d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu String errorContext = 5882d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu "CameraAction[" + cameraAction + "] at CameraState[" + cameraState + "]"; 5892d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu Log.e(TAG, "RuntimeException during " + errorContext, ex); 5902d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu 5912d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu // Be conservative by invalidating both CameraAgent and CameraProxy objects. 5922d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mCameraState.invalidate(); 5932d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu 5942d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu if (mCamera != null) { 5952d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu Log.i(TAG, "Release camera since mCamera is not null."); 596bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 597bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.release(); 5982d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } catch (Exception e) { 5992d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu Log.e(TAG, "Fail when calling Camera.release().", e); 6002d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } finally { 6012d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mCamera = null; 602bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 603bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 6042d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu 6052d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu // Invoke error callback. 6062d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu if (msg.what == CameraActions.OPEN_CAMERA && mCamera == null) { 6072d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu final int cameraId = msg.arg1; 6082d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu if (msg.obj != null) { 6092d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu ((CameraOpenCallback) msg.obj).onDeviceOpenFailure( 6102d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu msg.arg1, generateHistoryString(cameraId)); 6112d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 6122d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } else { 6132d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mAgent.getCameraExceptionHandler().onCameraException(ex); 614bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 6156a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin } finally { 6166a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin WaitDoneBundle.unblockSyncWaiters(msg); 617bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 618bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 6198097973089420749dcd1ab4974a629c2466b31ccAngus Kong 6208447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger private void applySettingsToParameters(final CameraSettings settings, 6218447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger final Parameters parameters) { 6228097973089420749dcd1ab4974a629c2466b31ccAngus Kong final CameraCapabilities.Stringifier stringifier = mCapabilities.getStringifier(); 6238097973089420749dcd1ab4974a629c2466b31ccAngus Kong Size photoSize = settings.getCurrentPhotoSize(); 6248447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setPictureSize(photoSize.width(), photoSize.height()); 6258097973089420749dcd1ab4974a629c2466b31ccAngus Kong Size previewSize = settings.getCurrentPreviewSize(); 6268447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setPreviewSize(previewSize.width(), previewSize.height()); 6278097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (settings.getPreviewFrameRate() == -1) { 6288447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setPreviewFpsRange(settings.getPreviewFpsRangeMin(), 6298097973089420749dcd1ab4974a629c2466b31ccAngus Kong settings.getPreviewFpsRangeMax()); 6308097973089420749dcd1ab4974a629c2466b31ccAngus Kong } else { 6318447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setPreviewFrameRate(settings.getPreviewFrameRate()); 6328097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 6338447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setPreviewFormat(settings.getCurrentPreviewFormat()); 6348447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setJpegQuality(settings.getPhotoJpegCompressionQuality()); 6358097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (mCapabilities.supports(CameraCapabilities.Feature.ZOOM)) { 6369d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher parameters.setZoom(zoomRatioToIndex(settings.getCurrentZoomRatio(), 6379d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher parameters.getZoomRatios())); 6388097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 6398447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setExposureCompensation(settings.getExposureCompensationIndex()); 6408097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (mCapabilities.supports(CameraCapabilities.Feature.AUTO_EXPOSURE_LOCK)) { 6418447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setAutoExposureLock(settings.isAutoExposureLocked()); 6428097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 6438447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setFocusMode(stringifier.stringify(settings.getCurrentFocusMode())); 6448097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (mCapabilities.supports(CameraCapabilities.Feature.AUTO_WHITE_BALANCE_LOCK)) { 6458447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setAutoWhiteBalanceLock(settings.isAutoWhiteBalanceLocked()); 6468097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 6478097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (mCapabilities.supports(CameraCapabilities.Feature.FOCUS_AREA)) { 648f07afbbde040b9578bc7f188016c3960e8616ab0Angus Kong if (settings.getFocusAreas().size() != 0) { 6498447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setFocusAreas(settings.getFocusAreas()); 650f73c6cf2f04451ba4517abccd36a114667c69ae3Andy Huibers } else { 651f73c6cf2f04451ba4517abccd36a114667c69ae3Andy Huibers parameters.setFocusAreas(null); 652f07afbbde040b9578bc7f188016c3960e8616ab0Angus Kong } 6538097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 6548097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (mCapabilities.supports(CameraCapabilities.Feature.METERING_AREA)) { 655f07afbbde040b9578bc7f188016c3960e8616ab0Angus Kong if (settings.getMeteringAreas().size() != 0) { 6568447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setMeteringAreas(settings.getMeteringAreas()); 657f73c6cf2f04451ba4517abccd36a114667c69ae3Andy Huibers } else { 658f73c6cf2f04451ba4517abccd36a114667c69ae3Andy Huibers parameters.setMeteringAreas(null); 659f07afbbde040b9578bc7f188016c3960e8616ab0Angus Kong } 6608097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 6618097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (settings.getCurrentFlashMode() != CameraCapabilities.FlashMode.NO_FLASH) { 6628447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setFlashMode(stringifier.stringify(settings.getCurrentFlashMode())); 6638097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 6648097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (settings.getCurrentSceneMode() != CameraCapabilities.SceneMode.NO_SCENE_MODE) { 665f07afbbde040b9578bc7f188016c3960e8616ab0Angus Kong if (settings.getCurrentSceneMode() != null) { 6668447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters 667f07afbbde040b9578bc7f188016c3960e8616ab0Angus Kong .setSceneMode(stringifier.stringify(settings.getCurrentSceneMode())); 668f07afbbde040b9578bc7f188016c3960e8616ab0Angus Kong } 6698097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 6708447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setRecordingHint(settings.isRecordingHintEnabled()); 67101e7c02174ef268b6d6daaa5a5bb4f752d55964cAngus Kong Size jpegThumbSize = settings.getExifThumbnailSize(); 6721c1d1afb5701b78fcdf09969bba1c20eb591bccfAlan Newberger if (jpegThumbSize != null) { 6731c1d1afb5701b78fcdf09969bba1c20eb591bccfAlan Newberger parameters.setJpegThumbnailSize(jpegThumbSize.width(), jpegThumbSize.height()); 6741c1d1afb5701b78fcdf09969bba1c20eb591bccfAlan Newberger } 6758447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setPictureFormat(settings.getCurrentPhotoFormat()); 6768097973089420749dcd1ab4974a629c2466b31ccAngus Kong 6778097973089420749dcd1ab4974a629c2466b31ccAngus Kong CameraSettings.GpsData gpsData = settings.getGpsData(); 6788097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (gpsData == null) { 6798447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.removeGpsData(); 6808097973089420749dcd1ab4974a629c2466b31ccAngus Kong } else { 6818447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setGpsTimestamp(gpsData.timeStamp); 6828097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (gpsData.processingMethod != null) { 6838097973089420749dcd1ab4974a629c2466b31ccAngus Kong // It's a hack since we always use GPS time stamp but does 6848097973089420749dcd1ab4974a629c2466b31ccAngus Kong // not use other fields sometimes. Setting processing 6858097973089420749dcd1ab4974a629c2466b31ccAngus Kong // method to null means the other fields should not be used. 6868447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setGpsAltitude(gpsData.altitude); 6878447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setGpsLatitude(gpsData.latitude); 6888447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setGpsLongitude(gpsData.longitude); 6898447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setGpsProcessingMethod(gpsData.processingMethod); 6908097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 6918097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 6928097973089420749dcd1ab4974a629c2466b31ccAngus Kong 6938097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 6949d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher 6959d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher /** 6969d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher * @param ratio Desired zoom ratio, in [1.0f,+Inf). 6979d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher * @param percentages Available zoom ratios, as percentages. 6989d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher * @return Index of the closest corresponding ratio, rounded up toward 6999d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher * that of the maximum available ratio. 7009d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher */ 7019d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher private int zoomRatioToIndex(float ratio, List<Integer> percentages) { 7029d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher int percent = (int) (ratio * AndroidCameraCapabilities.ZOOM_MULTIPLIER); 7039d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher int index = Collections.binarySearch(percentages, percent); 7049d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher if (index >= 0) { 7059d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher // Found the desired ratio in the supported list 7069d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher return index; 7079d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher } else { 7089d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher // Didn't find an exact match. Where would it have been? 7099d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher index = -(index + 1); 7109d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher if (index == percentages.size()) { 7119d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher // Put it back in bounds by setting to the maximum allowable zoom 7129d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher --index; 7139d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher } 7149d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher return index; 7159d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher } 7169d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher } 717bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 718bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 719bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 7204f425ba476d62b4be7078f2084af37cf306b31c6Sol Boucher * A class which implements {@link CameraAgent.CameraProxy} and 721bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * camera handler thread. 722bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 723a0842b40441db5332a5290f941021636b1182761Sol Boucher private class AndroidCameraProxyImpl extends CameraAgent.CameraProxy { 7242d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu private final CameraAgent mCameraAgent; 725bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final int mCameraId; 726bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /* TODO: remove this Camera instance. */ 727bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Camera mCamera; 728b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher private final CameraDeviceInfo.Characteristics mCharacteristics; 729c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong private final AndroidCameraCapabilities mCapabilities; 730bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 7312d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu private AndroidCameraProxyImpl( 7322d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu CameraAgent cameraAgent, 7332d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu int cameraId, 7342d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu Camera camera, 735b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher CameraDeviceInfo.Characteristics characteristics, 736c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong AndroidCameraCapabilities capabilities) { 7372d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mCameraAgent = cameraAgent; 738bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 739bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraId = cameraId; 740b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher mCharacteristics = characteristics; 741c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong mCapabilities = capabilities; 742bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 743bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 7448447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger @Deprecated 745bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 746bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public android.hardware.Camera getCamera() { 7472d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu if (getCameraState().isInvalid()) { 7482d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu return null; 7492d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 750bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return mCamera; 751bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 752bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 753bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 754bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public int getCameraId() { 755bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return mCameraId; 756bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 757bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 758bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 759b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher public CameraDeviceInfo.Characteristics getCharacteristics() { 760b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher return mCharacteristics; 761b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher } 762b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher 763b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher @Override 764c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong public CameraCapabilities getCapabilities() { 765c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong return new AndroidCameraCapabilities(mCapabilities); 766c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong } 767c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong 768c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong @Override 7692d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public CameraAgent getAgent() { 7702d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu return mCameraAgent; 7712d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 7722d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu 7732d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu @Override 774bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setPreviewDataCallback( 775bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final Handler handler, final CameraPreviewDataCallback cb) { 776bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 777bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 778bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 779cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.SET_PREVIEW_CALLBACK, 780cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher PreviewCallbackForward.getNewInstance( 781cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher handler, AndroidCameraProxyImpl.this, cb)) 782bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 783bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 784bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 785bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 786a0842b40441db5332a5290f941021636b1182761Sol Boucher 787bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 788bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setOneShotPreviewCallback(final Handler handler, 789bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraPreviewDataCallback cb) { 790bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 791bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 792bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 793cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.SET_ONE_SHOT_PREVIEW_CALLBACK, 794bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong PreviewCallbackForward 795bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .getNewInstance(handler, AndroidCameraProxyImpl.this, cb)) 796bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 797bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 798bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 799bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 800bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 801bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 802bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setPreviewDataCallbackWithBuffer( 803bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final Handler handler, final CameraPreviewDataCallback cb) { 804bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 805bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 806bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 807cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.SET_PREVIEW_CALLBACK_WITH_BUFFER, 808bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong PreviewCallbackForward 809bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .getNewInstance(handler, AndroidCameraProxyImpl.this, cb)) 810bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 811bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 812bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 813bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 814bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 815bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 816bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void autoFocus(final Handler handler, final CameraAFCallback cb) { 817bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final AutoFocusCallback afCallback = new AutoFocusCallback() { 818bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 819bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onAutoFocus(final boolean b, Camera camera) { 820a0842b40441db5332a5290f941021636b1182761Sol Boucher if (mCameraState.getState() != AndroidCameraStateHolder.CAMERA_FOCUSING) { 821bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.w(TAG, "onAutoFocus callback returning when not focusing"); 822bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } else { 823a0842b40441db5332a5290f941021636b1182761Sol Boucher mCameraState.setState(AndroidCameraStateHolder.CAMERA_IDLE); 824bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 825bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong handler.post(new Runnable() { 826bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 827bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 828bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong cb.onAutoFocus(b, AndroidCameraProxyImpl.this); 829bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 830bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 831bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 832bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }; 833bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 834bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 835bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 8362d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu // Don't bother to wait since camera is in bad state. 8372d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu if (getCameraState().isInvalid()) { 8382d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu return; 8392d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 840a0842b40441db5332a5290f941021636b1182761Sol Boucher mCameraState.waitForStates(AndroidCameraStateHolder.CAMERA_IDLE); 841cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.AUTO_FOCUS, afCallback) 842cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher .sendToTarget(); 843bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 844bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 845bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 846bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 847bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 848bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 849bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setAutoFocusMoveCallback( 850bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final Handler handler, final CameraAFMoveCallback cb) { 8512d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu try { 8522d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mDispatchThread.runJob(new Runnable() { 8532d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu @Override 8542d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public void run() { 8552d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mCameraHandler.obtainMessage(CameraActions.SET_AUTO_FOCUS_MOVE_CALLBACK, 8562d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu AFMoveCallbackForward.getNewInstance( 8572d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu handler, AndroidCameraProxyImpl.this, cb)) 8582d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu .sendToTarget(); 8592d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 8602d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu }); 8612d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } catch (final RuntimeException ex) { 8622d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mCameraAgent.getCameraExceptionHandler().onDispatchThreadException(ex); 8632d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 864bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 865bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 866bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 867bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void takePicture( 868bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final Handler handler, final CameraShutterCallback shutter, 869bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraPictureCallback raw, final CameraPictureCallback post, 870bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraPictureCallback jpeg) { 871bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final PictureCallback jpegCallback = new PictureCallback() { 872bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 873bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onPictureTaken(final byte[] data, Camera camera) { 874a0842b40441db5332a5290f941021636b1182761Sol Boucher if (mCameraState.getState() != AndroidCameraStateHolder.CAMERA_CAPTURING) { 87560520c4df78e595964605cf8acfa21bbafaeba84Angus Kong Log.w(TAG, "picture callback returning when not capturing"); 876bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } else { 877a0842b40441db5332a5290f941021636b1182761Sol Boucher mCameraState.setState(AndroidCameraStateHolder.CAMERA_IDLE); 878bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 879bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong handler.post(new Runnable() { 880bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 881bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 882bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong jpeg.onPictureTaken(data, AndroidCameraProxyImpl.this); 883bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 884bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 885bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 886bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }; 887bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 8882d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu try { 8892d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mDispatchThread.runJob(new Runnable() { 8902d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu @Override 8912d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public void run() { 8922d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu // Don't bother to wait since camera is in bad state. 8932d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu if (getCameraState().isInvalid()) { 8942d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu return; 8952d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 8962d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mCameraState.waitForStates(AndroidCameraStateHolder.CAMERA_IDLE | 8972d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu AndroidCameraStateHolder.CAMERA_UNLOCKED); 8982d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mCameraHandler.requestTakePicture(ShutterCallbackForward 8992d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu .getNewInstance(handler, AndroidCameraProxyImpl.this, shutter), 9002d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu PictureCallbackForward 9012d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu .getNewInstance(handler, AndroidCameraProxyImpl.this, raw), 9022d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu PictureCallbackForward 9032d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu .getNewInstance(handler, AndroidCameraProxyImpl.this, post), 9042d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu jpegCallback 9052d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu ); 9062d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 9072d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu }); 9082d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } catch (final RuntimeException ex) { 9092d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mCameraAgent.getCameraExceptionHandler().onDispatchThreadException(ex); 9102d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 911bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 912bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 913bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 914bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setZoomChangeListener(final OnZoomChangeListener listener) { 9152d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu try { 9162d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mDispatchThread.runJob(new Runnable() { 9172d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu @Override 9182d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public void run() { 9192d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mCameraHandler.obtainMessage(CameraActions.SET_ZOOM_CHANGE_LISTENER, listener) 9202d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu .sendToTarget(); 9212d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 9222d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu }); 9232d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } catch (final RuntimeException ex) { 9242d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mCameraAgent.getCameraExceptionHandler().onDispatchThreadException(ex); 9252d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 926bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 927bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 928bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 929bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setFaceDetectionCallback(final Handler handler, 930bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraFaceDetectionCallback cb) { 9312d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu try { 9322d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mDispatchThread.runJob(new Runnable() { 9332d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu @Override 9342d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public void run() { 9352d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mCameraHandler.obtainMessage(CameraActions.SET_FACE_DETECTION_LISTENER, 9362d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu FaceDetectionCallbackForward 9372d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu .getNewInstance(handler, AndroidCameraProxyImpl.this, cb)) 9382d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu .sendToTarget(); 9392d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 9402d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu }); 9412d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } catch (final RuntimeException ex) { 9422d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mCameraAgent.getCameraExceptionHandler().onDispatchThreadException(ex); 9432d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 944bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 945bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 946bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 947bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setErrorCallback(final Handler handler, final CameraErrorCallback cb) { 9482d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu try { 9492d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mDispatchThread.runJob(new Runnable() { 9502d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu @Override 9512d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public void run() { 9522d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mCameraHandler.obtainMessage(CameraActions.SET_ERROR_CALLBACK, 9532d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu ErrorCallbackForward.getNewInstance( 9542d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu handler, AndroidCameraProxyImpl.this, cb)) 9552d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu .sendToTarget(); 9562d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 9572d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu }); 9582d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } catch (final RuntimeException ex) { 9592d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mCameraAgent.getCameraExceptionHandler().onDispatchThreadException(ex); 9602d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 961bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 962bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 9638447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger @Deprecated 964bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 965bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setParameters(final Parameters params) { 966bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (params == null) { 967bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.v(TAG, "null parameters in setParameters()"); 968bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return; 969bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 970bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final String flattenedParameters = params.flatten(); 9712d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu try { 9722d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mDispatchThread.runJob(new Runnable() { 9732d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu @Override 9742d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public void run() { 9752d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mCameraState.waitForStates(AndroidCameraStateHolder.CAMERA_IDLE | 9762d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu AndroidCameraStateHolder.CAMERA_UNLOCKED); 9772d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mCameraHandler.obtainMessage(CameraActions.SET_PARAMETERS, flattenedParameters) 9782d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu .sendToTarget(); 9792d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 9802d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu }); 9812d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } catch (final RuntimeException ex) { 9822d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mCameraAgent.getCameraExceptionHandler().onDispatchThreadException(ex); 9832d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 984bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 985bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 9868447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger @Deprecated 987bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 988bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public Parameters getParameters() { 989bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final WaitDoneBundle bundle = new WaitDoneBundle(); 9908447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger final Parameters[] parametersHolder = new Parameters[1]; 9912d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu try { 9922d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mDispatchThread.runJobSync(new Runnable() { 9932d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu @Override 9942d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public void run() { 9952d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mCameraHandler.obtainMessage( 9962d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu CameraActions.GET_PARAMETERS, parametersHolder).sendToTarget(); 9972d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mCameraHandler.post(bundle.mUnlockRunnable); 9982d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 9992d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu }, bundle.mWaitLock, CAMERA_OPERATION_TIMEOUT_MS, "get parameters"); 10002d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } catch (final RuntimeException ex) { 10012d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu mCameraAgent.getCameraExceptionHandler().onDispatchThreadException(ex); 10022d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 10038447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger return parametersHolder[0]; 1004bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1005bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1006bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 10078097973089420749dcd1ab4974a629c2466b31ccAngus Kong public CameraSettings getSettings() { 10088097973089420749dcd1ab4974a629c2466b31ccAngus Kong return new AndroidCameraSettings(mCapabilities, getParameters()); 10098097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 10108097973089420749dcd1ab4974a629c2466b31ccAngus Kong 10118097973089420749dcd1ab4974a629c2466b31ccAngus Kong @Override 1012a0842b40441db5332a5290f941021636b1182761Sol Boucher public boolean applySettings(CameraSettings settings) { 1013a0842b40441db5332a5290f941021636b1182761Sol Boucher return applySettingsHelper(settings, AndroidCameraStateHolder.CAMERA_IDLE | 1014a0842b40441db5332a5290f941021636b1182761Sol Boucher AndroidCameraStateHolder.CAMERA_UNLOCKED); 1015bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 101601e7c02174ef268b6d6daaa5a5bb4f752d55964cAngus Kong 101701e7c02174ef268b6d6daaa5a5bb4f752d55964cAngus Kong @Override 101801e7c02174ef268b6d6daaa5a5bb4f752d55964cAngus Kong public String dumpDeviceSettings() { 10198447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger Parameters parameters = getParameters(); 10208447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger if (parameters != null) { 10218447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger String flattened = getParameters().flatten(); 10228447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger StringTokenizer tokenizer = new StringTokenizer(flattened, ";"); 10238447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger String dumpedSettings = new String(); 10248447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger while (tokenizer.hasMoreElements()) { 10258447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger dumpedSettings += tokenizer.nextToken() + '\n'; 10268447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger } 102701e7c02174ef268b6d6daaa5a5bb4f752d55964cAngus Kong 10288447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger return dumpedSettings; 10298447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger } else { 10308447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger return "[no parameters retrieved]"; 10318447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger } 103201e7c02174ef268b6d6daaa5a5bb4f752d55964cAngus Kong } 1033a0842b40441db5332a5290f941021636b1182761Sol Boucher 1034a0842b40441db5332a5290f941021636b1182761Sol Boucher @Override 1035a0842b40441db5332a5290f941021636b1182761Sol Boucher public Handler getCameraHandler() { 1036a0842b40441db5332a5290f941021636b1182761Sol Boucher return AndroidCameraAgentImpl.this.getCameraHandler(); 1037a0842b40441db5332a5290f941021636b1182761Sol Boucher } 1038a0842b40441db5332a5290f941021636b1182761Sol Boucher 1039a0842b40441db5332a5290f941021636b1182761Sol Boucher @Override 1040a0842b40441db5332a5290f941021636b1182761Sol Boucher public DispatchThread getDispatchThread() { 1041a0842b40441db5332a5290f941021636b1182761Sol Boucher return AndroidCameraAgentImpl.this.getDispatchThread(); 1042a0842b40441db5332a5290f941021636b1182761Sol Boucher } 1043a0842b40441db5332a5290f941021636b1182761Sol Boucher 1044a0842b40441db5332a5290f941021636b1182761Sol Boucher @Override 1045a0842b40441db5332a5290f941021636b1182761Sol Boucher public CameraStateHolder getCameraState() { 1046a0842b40441db5332a5290f941021636b1182761Sol Boucher return mCameraState; 1047a0842b40441db5332a5290f941021636b1182761Sol Boucher } 1048bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1049bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1050a0842b40441db5332a5290f941021636b1182761Sol Boucher private static class AndroidCameraStateHolder extends CameraStateHolder { 1051a0842b40441db5332a5290f941021636b1182761Sol Boucher /* Camera states */ 1052a0842b40441db5332a5290f941021636b1182761Sol Boucher // These states are defined bitwise so we can easily to specify a set of 1053a0842b40441db5332a5290f941021636b1182761Sol Boucher // states together. 1054a0842b40441db5332a5290f941021636b1182761Sol Boucher public static final int CAMERA_UNOPENED = 1; 1055a0842b40441db5332a5290f941021636b1182761Sol Boucher public static final int CAMERA_IDLE = 1 << 1; 1056a0842b40441db5332a5290f941021636b1182761Sol Boucher public static final int CAMERA_UNLOCKED = 1 << 2; 1057a0842b40441db5332a5290f941021636b1182761Sol Boucher public static final int CAMERA_CAPTURING = 1 << 3; 1058a0842b40441db5332a5290f941021636b1182761Sol Boucher public static final int CAMERA_FOCUSING = 1 << 4; 1059bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1060a0842b40441db5332a5290f941021636b1182761Sol Boucher public AndroidCameraStateHolder() { 1061a0842b40441db5332a5290f941021636b1182761Sol Boucher this(CAMERA_UNOPENED); 1062a0842b40441db5332a5290f941021636b1182761Sol Boucher } 1063a0842b40441db5332a5290f941021636b1182761Sol Boucher 1064a0842b40441db5332a5290f941021636b1182761Sol Boucher public AndroidCameraStateHolder(int state) { 10657e0d39bf7b6e0f0df606e3f6c15f673f70fed3f7Sol Boucher super(state); 1066bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1067bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1068bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1069bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1070bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A helper class to forward AutoFocusCallback to another thread. 1071bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1072bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class AFCallbackForward implements AutoFocusCallback { 1073bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1074bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1075bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraAFCallback mCallback; 1076bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1077bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1078bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link AFCallbackForward}. 1079bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1080bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1081bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1082bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1083bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link AFCallbackForward}, 1084bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameter is null. 1085bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1086bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static AFCallbackForward getNewInstance( 1087bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraAFCallback cb) { 1088bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1089bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1090bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1091bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new AFCallbackForward(handler, camera, cb); 1092bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1093bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1094bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private AFCallbackForward( 1095bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraAFCallback cb) { 1096bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1097bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1098bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1099bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1100bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1101bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1102bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onAutoFocus(final boolean b, Camera camera) { 1103bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1104bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1105bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1106bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onAutoFocus(b, mCamera); 1107bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1108bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1109bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1110bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1111bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1112bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1113bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A helper class to forward ErrorCallback to another thread. 1114bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1115bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class ErrorCallbackForward implements Camera.ErrorCallback { 1116bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1117bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1118bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraErrorCallback mCallback; 1119bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1120bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1121bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link AFCallbackForward}. 1122bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1123bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1124bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1125bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1126bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link AFCallbackForward}, 1127bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameter is null. 1128bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1129bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static ErrorCallbackForward getNewInstance( 1130bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraErrorCallback cb) { 1131bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1132bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1133bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1134bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new ErrorCallbackForward(handler, camera, cb); 1135bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1136bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1137bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private ErrorCallbackForward( 1138bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraErrorCallback cb) { 1139bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1140bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1141bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1142bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1143bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1144bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1145bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onError(final int error, Camera camera) { 1146bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1147bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1148bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1149bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onError(error, mCamera); 1150bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1151bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1152bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1153bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1154bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1155bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** A helper class to forward AutoFocusMoveCallback to another thread. */ 1156bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 1157bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class AFMoveCallbackForward implements AutoFocusMoveCallback { 1158bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1159bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraAFMoveCallback mCallback; 1160bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1161bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1162bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1163bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link AFMoveCallbackForward}. 1164bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1165bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1166bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1167bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1168bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link AFMoveCallbackForward}, 1169bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameter is null. 1170bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1171bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static AFMoveCallbackForward getNewInstance( 1172bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraAFMoveCallback cb) { 1173bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1174bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1175bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1176bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new AFMoveCallbackForward(handler, camera, cb); 1177bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1178bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1179bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private AFMoveCallbackForward( 1180bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraAFMoveCallback cb) { 1181bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1182bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1183bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1184bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1185bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1186bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1187bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onAutoFocusMoving( 1188bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final boolean moving, android.hardware.Camera camera) { 1189bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1190bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1191bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1192bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onAutoFocusMoving(moving, mCamera); 1193bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1194bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1195bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1196bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1197bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1198bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1199bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A helper class to forward ShutterCallback to to another thread. 1200bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1201bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class ShutterCallbackForward implements ShutterCallback { 1202bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1203bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraShutterCallback mCallback; 1204bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1205bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1206bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1207bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link ShutterCallbackForward}. 1208bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1209bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1210bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1211bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1212bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link ShutterCallbackForward}, 1213bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameter is null. 1214bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1215bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static ShutterCallbackForward getNewInstance( 1216bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraShutterCallback cb) { 1217bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1218bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1219bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1220bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new ShutterCallbackForward(handler, camera, cb); 1221bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1222bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1223bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private ShutterCallbackForward( 1224bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraShutterCallback cb) { 1225bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1226bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1227bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1228bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1229bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1230bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1231bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onShutter() { 1232bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1233bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1234bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1235bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onShutter(mCamera); 1236bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1237bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1238bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1239bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1240bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1241bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1242bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A helper class to forward PictureCallback to another thread. 1243bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1244bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class PictureCallbackForward implements PictureCallback { 1245bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1246bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraPictureCallback mCallback; 1247bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1248bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1249bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1250bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link PictureCallbackForward}. 1251bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1252bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1253bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1254bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1255bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link PictureCallbackForward}, 1256bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameters is null. 1257bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1258bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static PictureCallbackForward getNewInstance( 1259bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraPictureCallback cb) { 1260bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1261bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1262bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1263bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new PictureCallbackForward(handler, camera, cb); 1264bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1265bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1266bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private PictureCallbackForward( 1267bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraPictureCallback cb) { 1268bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1269bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1270bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1271bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1272bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1273bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1274bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onPictureTaken( 1275bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final byte[] data, android.hardware.Camera camera) { 1276bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1277bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1278bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1279bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onPictureTaken(data, mCamera); 1280bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1281bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1282bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1283bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1284bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1285bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1286bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A helper class to forward PreviewCallback to another thread. 1287bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1288bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class PreviewCallbackForward implements PreviewCallback { 1289bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1290bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraPreviewDataCallback mCallback; 1291bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1292bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1293bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1294bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link PreviewCallbackForward}. 1295bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1296bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1297bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1298bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1299bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link PreviewCallbackForward}, 1300bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameters is null. 1301bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1302bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static PreviewCallbackForward getNewInstance( 1303bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraPreviewDataCallback cb) { 1304bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1305bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1306bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1307bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new PreviewCallbackForward(handler, camera, cb); 1308bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1309bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1310bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private PreviewCallbackForward( 1311bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraPreviewDataCallback cb) { 1312bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1313bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1314bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1315bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1316bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1317bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1318bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onPreviewFrame( 1319bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final byte[] data, android.hardware.Camera camera) { 1320bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1321bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1322bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1323bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onPreviewFrame(data, mCamera); 1324bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1325bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1326bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1327bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1328bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1329bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class FaceDetectionCallbackForward implements FaceDetectionListener { 1330bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1331bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraFaceDetectionCallback mCallback; 1332bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1333bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1334bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1335bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link FaceDetectionCallbackForward}. 1336bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1337bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1338bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1339bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1340bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link FaceDetectionCallbackForward}, 1341bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameter is null. 1342bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1343bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static FaceDetectionCallbackForward getNewInstance( 1344bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraFaceDetectionCallback cb) { 1345bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1346bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1347bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1348bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new FaceDetectionCallbackForward(handler, camera, cb); 1349bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1350bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1351bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private FaceDetectionCallbackForward( 1352bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraFaceDetectionCallback cb) { 1353bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1354bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1355bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1356bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1357bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1358bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1359bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onFaceDetection( 1360bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final Camera.Face[] faces, Camera camera) { 1361bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1362bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1363bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1364bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onFaceDetection(faces, mCamera); 1365bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1366bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1367bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1368bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1369bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong} 1370