AndroidCameraAgentImpl.java revision 2569329d6cff25bfe9941df539df14a0aeb4c4f4
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; 58bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 59bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private Handler mCameraExceptionCallbackHandler; 60bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private CameraExceptionCallback mCameraExceptionCallback = 61bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong new CameraExceptionCallback() { 62bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 63bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onCameraException(RuntimeException e) { 64bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong throw e; 65bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 66bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }; 67bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 684f425ba476d62b4be7078f2084af37cf306b31c6Sol Boucher AndroidCameraAgentImpl() { 69bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandlerThread = new HandlerThread("Camera Handler Thread"); 70bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandlerThread.start(); 71bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler = new CameraHandler(mCameraHandlerThread.getLooper()); 72bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraExceptionCallbackHandler = mCameraHandler; 73a0842b40441db5332a5290f941021636b1182761Sol Boucher mCameraState = new AndroidCameraStateHolder(); 74cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mDispatchThread = new DispatchThread(mCameraHandler, mCameraHandlerThread); 75bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.start(); 76bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 77bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 78bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 79bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setCameraDefaultExceptionCallback(CameraExceptionCallback callback, 80bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler) { 81bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong synchronized (mCameraExceptionCallback) { 82bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraExceptionCallback = callback; 83bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraExceptionCallbackHandler = handler; 84bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 85bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 86bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 8760520c4df78e595964605cf8acfa21bbafaeba84Angus Kong @Override 88bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void recycle() { 8960520c4df78e595964605cf8acfa21bbafaeba84Angus Kong closeCamera(null, true); 90bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.end(); 91bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 927e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 937e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong @Override 947e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong public CameraDeviceInfo getCameraDeviceInfo() { 957e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return AndroidCameraDeviceInfo.create(); 967e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 977e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 98a0842b40441db5332a5290f941021636b1182761Sol Boucher @Override 99a0842b40441db5332a5290f941021636b1182761Sol Boucher protected Handler getCameraHandler() { 100a0842b40441db5332a5290f941021636b1182761Sol Boucher return mCameraHandler; 101a0842b40441db5332a5290f941021636b1182761Sol Boucher } 102a0842b40441db5332a5290f941021636b1182761Sol Boucher 103a0842b40441db5332a5290f941021636b1182761Sol Boucher @Override 104a0842b40441db5332a5290f941021636b1182761Sol Boucher protected DispatchThread getDispatchThread() { 105a0842b40441db5332a5290f941021636b1182761Sol Boucher return mDispatchThread; 106a0842b40441db5332a5290f941021636b1182761Sol Boucher } 107a0842b40441db5332a5290f941021636b1182761Sol Boucher 1087e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong private static class AndroidCameraDeviceInfo implements CameraDeviceInfo { 1097e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong private final Camera.CameraInfo[] mCameraInfos; 1107e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong private final int mNumberOfCameras; 1117e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong private final int mFirstBackCameraId; 1127e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong private final int mFirstFrontCameraId; 1137e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1147e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong private AndroidCameraDeviceInfo(Camera.CameraInfo[] info, int numberOfCameras, 1157e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong int firstBackCameraId, int firstFrontCameraId) { 1167e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1177e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong mCameraInfos = info; 1187e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong mNumberOfCameras = numberOfCameras; 1197e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong mFirstBackCameraId = firstBackCameraId; 1207e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong mFirstFrontCameraId = firstFrontCameraId; 1217e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1227e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1237e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong public static AndroidCameraDeviceInfo create() { 1247e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong int numberOfCameras; 1257e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong Camera.CameraInfo[] cameraInfos; 1267e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong try { 1277e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong numberOfCameras = Camera.getNumberOfCameras(); 1287e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong cameraInfos = new Camera.CameraInfo[numberOfCameras]; 1297e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong for (int i = 0; i < numberOfCameras; i++) { 1307e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong cameraInfos[i] = new Camera.CameraInfo(); 1317e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong Camera.getCameraInfo(i, cameraInfos[i]); 1327e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1337e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } catch (RuntimeException ex) { 134eb07f0c4c693566f6f258e84426f518e90513c11Alan Newberger Log.e(TAG, "Exception while creating CameraDeviceInfo", ex); 1357e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return null; 1367e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1377e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1387e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong int firstFront = NO_DEVICE; 1397e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong int firstBack = NO_DEVICE; 1407e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong // Get the first (smallest) back and first front camera id. 1417e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong for (int i = numberOfCameras - 1; i >= 0; i--) { 1427e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong if (cameraInfos[i].facing == Camera.CameraInfo.CAMERA_FACING_BACK) { 1437e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong firstBack = i; 1447e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } else { 1457e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong if (cameraInfos[i].facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 1467e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong firstFront = i; 1477e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1487e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1497e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1507e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1517e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return new AndroidCameraDeviceInfo(cameraInfos, numberOfCameras, firstBack, firstFront); 1527e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1537e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1547e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong @Override 155b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher public Characteristics getCharacteristics(int cameraId) { 156b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher Camera.CameraInfo info = mCameraInfos[cameraId]; 157b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher if (info != null) { 158b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher return new AndroidCharacteristics(info); 159b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher } else { 160b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher return null; 161b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher } 1627e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1637e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1647e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong @Override 1657e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong public int getNumberOfCameras() { 1667e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return mNumberOfCameras; 1677e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1687e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1697e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong @Override 1707e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong public int getFirstBackCameraId() { 1717e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return mFirstBackCameraId; 1727e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 1737e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 1747e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong @Override 1757e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong public int getFirstFrontCameraId() { 1767e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong return mFirstFrontCameraId; 1777e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 178b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher 179de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher private static class AndroidCharacteristics extends Characteristics { 180b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher private Camera.CameraInfo mCameraInfo; 181b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher 182b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher AndroidCharacteristics(Camera.CameraInfo cameraInfo) { 183b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher mCameraInfo = cameraInfo; 184b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher } 185b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher 186b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher @Override 187b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher public boolean isFacingBack() { 188b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher return mCameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK; 189b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher } 190b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher 191b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher @Override 192b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher public boolean isFacingFront() { 193b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher return mCameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT; 194b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher } 195b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher 196b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher @Override 197b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher public int getSensorOrientation() { 198b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher return mCameraInfo.orientation; 199b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher } 200b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher 201b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher @Override 202b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher public boolean canDisableShutterSound() { 203b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher return mCameraInfo.canDisableShutterSound; 204b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher } 205b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher } 2067e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 207bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 2088447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger private static class ParametersCache { 2098447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger private Parameters mParameters; 2108447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger private Camera mCamera; 2118447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger 2128447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger public ParametersCache(Camera camera) { 2138447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger mCamera = camera; 2148447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger } 2158447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger 2168447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger public synchronized void invalidate() { 2178447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger mParameters = null; 2188447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger } 2198447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger 2208447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger /** 2218447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger * Access parameters from the cache. If cache is empty, block by 2228447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger * retrieving parameters directly from Camera, but if cache is present, 2238447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger * returns immediately. 2248447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger */ 2258447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger public synchronized Parameters getBlocking() { 2268447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger if (mParameters == null) { 2278447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger mParameters = mCamera.getParameters(); 2288447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger } 2298447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger return mParameters; 2308447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger } 2318447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger } 2328447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger 233bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 234bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * The handler on which the actual camera operations happen. 235bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 236cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher private class CameraHandler extends HistoryHandler { 237b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong 238bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private Camera mCamera; 23960520c4df78e595964605cf8acfa21bbafaeba84Angus Kong private int mCameraId; 2408447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger private ParametersCache mParameterCache; 241bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 242bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private class CaptureCallbacks { 243bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public final ShutterCallback mShutter; 244bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public final PictureCallback mRaw; 245bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public final PictureCallback mPostView; 246bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public final PictureCallback mJpeg; 247bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 248bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong CaptureCallbacks(ShutterCallback shutter, PictureCallback raw, PictureCallback postView, 249bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong PictureCallback jpeg) { 250bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mShutter = shutter; 251bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mRaw = raw; 252bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mPostView = postView; 253bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mJpeg = jpeg; 254bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 255bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 256bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 257bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong CameraHandler(Looper looper) { 258bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong super(looper); 259bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 260bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 261bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void startFaceDetection() { 262bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.startFaceDetection(); 263bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 264bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 265bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void stopFaceDetection() { 266bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.stopFaceDetection(); 267bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 268bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 269bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void setFaceDetectionListener(FaceDetectionListener listener) { 270bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setFaceDetectionListener(listener); 271bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 272bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 273bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void setPreviewTexture(Object surfaceTexture) { 274bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 275bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setPreviewTexture((SurfaceTexture) surfaceTexture); 276bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (IOException e) { 277bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.e(TAG, "Could not set preview texture", e); 278bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 279bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 280bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 281bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) 282bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void enableShutterSound(boolean enable) { 283bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.enableShutterSound(enable); 284bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 285bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 286bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 287bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void setAutoFocusMoveCallback( 288bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong android.hardware.Camera camera, Object cb) { 289bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 290bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong camera.setAutoFocusMoveCallback((AutoFocusMoveCallback) cb); 291bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (RuntimeException ex) { 292bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.w(TAG, ex.getMessage()); 293bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 294bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 295bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 296bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private void capture(final CaptureCallbacks cb) { 297bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 298bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.takePicture(cb.mShutter, cb.mRaw, cb.mPostView, cb.mJpeg); 299bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (RuntimeException e) { 300bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong // TODO: output camera state and focus state for debugging. 301bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.e(TAG, "take picture failed."); 302bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong throw e; 303bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 304bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 305bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 306bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void requestTakePicture( 307bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final ShutterCallback shutter, 308bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final PictureCallback raw, 309bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final PictureCallback postView, 310bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final PictureCallback jpeg) { 311bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CaptureCallbacks callbacks = new CaptureCallbacks(shutter, raw, postView, jpeg); 312cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher obtainMessage(CameraActions.CAPTURE_PHOTO, callbacks).sendToTarget(); 313bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 314bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 315bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 316bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * This method does not deal with the API level check. Everyone should 317bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * check first for supported operations before sending message to this handler. 318bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 319bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 320bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void handleMessage(final Message msg) { 321cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher super.handleMessage(msg); 322bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 323bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong switch (msg.what) { 324cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.OPEN_CAMERA: { 325bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraOpenCallback openCallback = (CameraOpenCallback) msg.obj; 326bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final int cameraId = msg.arg1; 327a0842b40441db5332a5290f941021636b1182761Sol Boucher if (mCameraState.getState() != AndroidCameraStateHolder.CAMERA_UNOPENED) { 32860520c4df78e595964605cf8acfa21bbafaeba84Angus Kong openCallback.onDeviceOpenedAlready(cameraId, generateHistoryString(cameraId)); 329bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 330bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 331bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 33250f5b019ba3f333a09a1beb9667fd7290082dc31Sol Boucher Log.i(TAG, "Opening camera " + cameraId + " with camera1 API"); 333bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = android.hardware.Camera.open(cameraId); 334bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (mCamera != null) { 33560520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mCameraId = cameraId; 3368447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger mParameterCache = new ParametersCache(mCamera); 337bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 338b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher mCharacteristics = 339b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher AndroidCameraDeviceInfo.create().getCharacteristics(cameraId); 3408447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger mCapabilities = new AndroidCameraCapabilities( 3418447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger mParameterCache.getBlocking()); 342bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 343a0842b40441db5332a5290f941021636b1182761Sol Boucher mCameraState.setState(AndroidCameraStateHolder.CAMERA_IDLE); 344bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (openCallback != null) { 345bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong openCallback.onCameraOpened( 346c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong new AndroidCameraProxyImpl(cameraId, mCamera, 347b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher mCharacteristics, mCapabilities)); 348bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 349bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } else { 350bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (openCallback != null) { 351b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong openCallback.onDeviceOpenFailure(cameraId, generateHistoryString(cameraId)); 352bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 353bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 354bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 355bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 356bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 357cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.RELEASE: { 35860520c4df78e595964605cf8acfa21bbafaeba84Angus Kong if (mCamera != null) { 35960520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mCamera.release(); 360a0842b40441db5332a5290f941021636b1182761Sol Boucher mCameraState.setState(AndroidCameraStateHolder.CAMERA_UNOPENED); 36160520c4df78e595964605cf8acfa21bbafaeba84Angus Kong mCamera = null; 36260520c4df78e595964605cf8acfa21bbafaeba84Angus Kong } else { 36360520c4df78e595964605cf8acfa21bbafaeba84Angus Kong Log.w(TAG, "Releasing camera without any camera opened."); 36460520c4df78e595964605cf8acfa21bbafaeba84Angus Kong } 365bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 366bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 367bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 368cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.RECONNECT: { 369bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraOpenCallbackForward cbForward = 370bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong (CameraOpenCallbackForward) msg.obj; 371bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final int cameraId = msg.arg1; 372bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 373bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.reconnect(); 374bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (IOException ex) { 375bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (cbForward != null) { 3764f425ba476d62b4be7078f2084af37cf306b31c6Sol Boucher cbForward.onReconnectionFailure(AndroidCameraAgentImpl.this, 37760520c4df78e595964605cf8acfa21bbafaeba84Angus Kong generateHistoryString(mCameraId)); 378bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 379bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 380bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 381bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 382a0842b40441db5332a5290f941021636b1182761Sol Boucher mCameraState.setState(AndroidCameraStateHolder.CAMERA_IDLE); 383bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (cbForward != null) { 3848097973089420749dcd1ab4974a629c2466b31ccAngus Kong cbForward.onCameraOpened( 385b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher new AndroidCameraProxyImpl(cameraId, mCamera, mCharacteristics, 386b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher mCapabilities)); 387bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 388bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 389bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 390bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 391cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.UNLOCK: { 392bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.unlock(); 393a0842b40441db5332a5290f941021636b1182761Sol Boucher mCameraState.setState(AndroidCameraStateHolder.CAMERA_UNLOCKED); 394bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 395bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 396bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 397cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.LOCK: { 398bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.lock(); 399a0842b40441db5332a5290f941021636b1182761Sol Boucher mCameraState.setState(AndroidCameraStateHolder.CAMERA_IDLE); 400bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 401bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 402bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 4032569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher // TODO: Lock the CameraSettings object's sizes 404cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_PREVIEW_TEXTURE_ASYNC: { 405bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong setPreviewTexture(msg.obj); 406bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 407bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 408bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 409cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_PREVIEW_DISPLAY_ASYNC: { 410bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 411bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setPreviewDisplay((SurfaceHolder) msg.obj); 412bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (IOException e) { 413bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong throw new RuntimeException(e); 414bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 415bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 416bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 417bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 418cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.START_PREVIEW_ASYNC: { 419bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraStartPreviewCallbackForward cbForward = 420bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong (CameraStartPreviewCallbackForward) msg.obj; 421bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.startPreview(); 422bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (cbForward != null) { 423bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong cbForward.onPreviewStarted(); 424bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 425bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 426bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 427bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 4282569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher // TODO: Unlock the CameraSettings object's sizes 429cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.STOP_PREVIEW: { 430bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.stopPreview(); 431bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 432bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 433bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 434cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_PREVIEW_CALLBACK_WITH_BUFFER: { 435bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setPreviewCallbackWithBuffer((PreviewCallback) msg.obj); 436bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 437bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 438bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 439cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_ONE_SHOT_PREVIEW_CALLBACK: { 440bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setOneShotPreviewCallback((PreviewCallback) msg.obj); 441bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 442bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 443bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 444cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.ADD_CALLBACK_BUFFER: { 445bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.addCallbackBuffer((byte[]) msg.obj); 446bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 447bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 448bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 449cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.AUTO_FOCUS: { 450a0842b40441db5332a5290f941021636b1182761Sol Boucher mCameraState.setState(AndroidCameraStateHolder.CAMERA_FOCUSING); 451bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.autoFocus((AutoFocusCallback) msg.obj); 452bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 453bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 454bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 455cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.CANCEL_AUTO_FOCUS: { 456bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.cancelAutoFocus(); 457a0842b40441db5332a5290f941021636b1182761Sol Boucher mCameraState.setState(AndroidCameraStateHolder.CAMERA_IDLE); 458bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 459bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 460bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 461cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_AUTO_FOCUS_MOVE_CALLBACK: { 462bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong setAutoFocusMoveCallback(mCamera, msg.obj); 463bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 464bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 465bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 466cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_DISPLAY_ORIENTATION: { 467de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher // Update preview orientation 468de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mCamera.setDisplayOrientation( 469de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mCharacteristics.getPreviewOrientation(msg.arg1)); 470de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher // Only set the JPEG capture orientation if requested to do so; otherwise, 471de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher // capture in the sensor's physical orientation 4728447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger Parameters parameters = mParameterCache.getBlocking(); 4738447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setRotation( 474de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher msg.arg2 > 0 ? mCharacteristics.getJpegOrientation(msg.arg1) : 0); 4758447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger mCamera.setParameters(parameters); 476bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 477bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 478bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 479cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_ZOOM_CHANGE_LISTENER: { 480bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setZoomChangeListener((OnZoomChangeListener) msg.obj); 481bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 482bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 483bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 484cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_FACE_DETECTION_LISTENER: { 485bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong setFaceDetectionListener((FaceDetectionListener) msg.obj); 486bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 487bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 488bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 489cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.START_FACE_DETECTION: { 490bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong startFaceDetection(); 491bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 492bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 493bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 494cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.STOP_FACE_DETECTION: { 495bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong stopFaceDetection(); 496bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 497bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 498bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 499cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_ERROR_CALLBACK: { 500bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setErrorCallback((ErrorCallback) msg.obj); 501bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 502bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 503bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 5048097973089420749dcd1ab4974a629c2466b31ccAngus Kong case CameraActions.APPLY_SETTINGS: { 5058447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger Parameters parameters = mParameterCache.getBlocking(); 5068097973089420749dcd1ab4974a629c2466b31ccAngus Kong CameraSettings settings = (CameraSettings) msg.obj; 5078447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger applySettingsToParameters(settings, parameters); 5088447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger mCamera.setParameters(parameters); 5098447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger mParameterCache.invalidate(); 5108097973089420749dcd1ab4974a629c2466b31ccAngus Kong break; 5118097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 5128097973089420749dcd1ab4974a629c2466b31ccAngus Kong 513cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_PARAMETERS: { 5148447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger Parameters parameters = mParameterCache.getBlocking(); 5158447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.unflatten((String) msg.obj); 5168447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger mCamera.setParameters(parameters); 5178447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger mParameterCache.invalidate(); 518bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 519bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 520bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 521cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.GET_PARAMETERS: { 5228447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger Parameters[] parametersHolder = (Parameters[]) msg.obj; 5238447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger Parameters parameters = mParameterCache.getBlocking(); 5248447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parametersHolder[0] = parameters; 525bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 526bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 527bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 528cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.SET_PREVIEW_CALLBACK: { 529bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.setPreviewCallback((PreviewCallback) msg.obj); 530bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 531bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 532bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 533cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.ENABLE_SHUTTER_SOUND: { 534bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong enableShutterSound((msg.arg1 == 1) ? true : false); 535bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 536bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 537bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 538cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.REFRESH_PARAMETERS: { 5398447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger mParameterCache.invalidate();; 540bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 541bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 542bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 543cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher case CameraActions.CAPTURE_PHOTO: { 544a0842b40441db5332a5290f941021636b1182761Sol Boucher mCameraState.setState(AndroidCameraStateHolder.CAMERA_CAPTURING); 545bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong capture((CaptureCallbacks) msg.obj); 546bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong break; 547bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 548bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 549bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong default: { 550bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong throw new RuntimeException("Invalid CameraProxy message=" + msg.what); 551bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 552bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 553bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (final RuntimeException e) { 554cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher if (msg.what != CameraActions.RELEASE && mCamera != null) { 555bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong try { 556bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera.release(); 557a0842b40441db5332a5290f941021636b1182761Sol Boucher mCameraState.setState(AndroidCameraStateHolder.CAMERA_UNOPENED); 558bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } catch (Exception ex) { 559bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.e(TAG, "Fail to release the camera."); 560bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 561bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = null; 562bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } else { 563bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (mCamera == null) { 564cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher if (msg.what == CameraActions.OPEN_CAMERA) { 565b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong final int cameraId = msg.arg1; 566bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (msg.obj != null) { 567b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong ((CameraOpenCallback) msg.obj).onDeviceOpenFailure( 568b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong msg.arg1, generateHistoryString(cameraId)); 569bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 570bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } else { 571bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.w(TAG, "Cannot handle message " + msg.what + ", mCamera is null."); 572bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 573bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return; 574bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 575bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 576bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong synchronized (mCameraExceptionCallback) { 577bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraExceptionCallbackHandler.post(new Runnable() { 578bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 579bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 580bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraExceptionCallback.onCameraException(e); 581bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 582bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 583bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 584bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 585bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 5868097973089420749dcd1ab4974a629c2466b31ccAngus Kong 5878447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger private void applySettingsToParameters(final CameraSettings settings, 5888447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger final Parameters parameters) { 5898097973089420749dcd1ab4974a629c2466b31ccAngus Kong final CameraCapabilities.Stringifier stringifier = mCapabilities.getStringifier(); 5908097973089420749dcd1ab4974a629c2466b31ccAngus Kong Size photoSize = settings.getCurrentPhotoSize(); 5918447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setPictureSize(photoSize.width(), photoSize.height()); 5928097973089420749dcd1ab4974a629c2466b31ccAngus Kong Size previewSize = settings.getCurrentPreviewSize(); 5938447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setPreviewSize(previewSize.width(), previewSize.height()); 5948097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (settings.getPreviewFrameRate() == -1) { 5958447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setPreviewFpsRange(settings.getPreviewFpsRangeMin(), 5968097973089420749dcd1ab4974a629c2466b31ccAngus Kong settings.getPreviewFpsRangeMax()); 5978097973089420749dcd1ab4974a629c2466b31ccAngus Kong } else { 5988447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setPreviewFrameRate(settings.getPreviewFrameRate()); 5998097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 6008447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setPreviewFormat(settings.getCurrentPreviewFormat()); 6018447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setJpegQuality(settings.getPhotoJpegCompressionQuality()); 6028097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (mCapabilities.supports(CameraCapabilities.Feature.ZOOM)) { 6039d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher parameters.setZoom(zoomRatioToIndex(settings.getCurrentZoomRatio(), 6049d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher parameters.getZoomRatios())); 6058097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 6068447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setExposureCompensation(settings.getExposureCompensationIndex()); 6078097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (mCapabilities.supports(CameraCapabilities.Feature.AUTO_EXPOSURE_LOCK)) { 6088447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setAutoExposureLock(settings.isAutoExposureLocked()); 6098097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 6108447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setFocusMode(stringifier.stringify(settings.getCurrentFocusMode())); 6118097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (mCapabilities.supports(CameraCapabilities.Feature.AUTO_WHITE_BALANCE_LOCK)) { 6128447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setAutoWhiteBalanceLock(settings.isAutoWhiteBalanceLocked()); 6138097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 6148097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (mCapabilities.supports(CameraCapabilities.Feature.FOCUS_AREA)) { 615f07afbbde040b9578bc7f188016c3960e8616ab0Angus Kong if (settings.getFocusAreas().size() != 0) { 6168447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setFocusAreas(settings.getFocusAreas()); 617f07afbbde040b9578bc7f188016c3960e8616ab0Angus Kong } 6188097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 6198097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (mCapabilities.supports(CameraCapabilities.Feature.METERING_AREA)) { 620f07afbbde040b9578bc7f188016c3960e8616ab0Angus Kong if (settings.getMeteringAreas().size() != 0) { 6218447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setMeteringAreas(settings.getMeteringAreas()); 622f07afbbde040b9578bc7f188016c3960e8616ab0Angus Kong } 6238097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 6248097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (settings.getCurrentFlashMode() != CameraCapabilities.FlashMode.NO_FLASH) { 6258447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setFlashMode(stringifier.stringify(settings.getCurrentFlashMode())); 6268097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 6278097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (settings.getCurrentSceneMode() != CameraCapabilities.SceneMode.NO_SCENE_MODE) { 628f07afbbde040b9578bc7f188016c3960e8616ab0Angus Kong if (settings.getCurrentSceneMode() != null) { 6298447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters 630f07afbbde040b9578bc7f188016c3960e8616ab0Angus Kong .setSceneMode(stringifier.stringify(settings.getCurrentSceneMode())); 631f07afbbde040b9578bc7f188016c3960e8616ab0Angus Kong } 6328097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 6338447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setRecordingHint(settings.isRecordingHintEnabled()); 63401e7c02174ef268b6d6daaa5a5bb4f752d55964cAngus Kong Size jpegThumbSize = settings.getExifThumbnailSize(); 6358447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setJpegThumbnailSize(jpegThumbSize.width(), jpegThumbSize.height()); 6368447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setPictureFormat(settings.getCurrentPhotoFormat()); 6378097973089420749dcd1ab4974a629c2466b31ccAngus Kong 6388097973089420749dcd1ab4974a629c2466b31ccAngus Kong CameraSettings.GpsData gpsData = settings.getGpsData(); 6398097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (gpsData == null) { 6408447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.removeGpsData(); 6418097973089420749dcd1ab4974a629c2466b31ccAngus Kong } else { 6428447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setGpsTimestamp(gpsData.timeStamp); 6438097973089420749dcd1ab4974a629c2466b31ccAngus Kong if (gpsData.processingMethod != null) { 6448097973089420749dcd1ab4974a629c2466b31ccAngus Kong // It's a hack since we always use GPS time stamp but does 6458097973089420749dcd1ab4974a629c2466b31ccAngus Kong // not use other fields sometimes. Setting processing 6468097973089420749dcd1ab4974a629c2466b31ccAngus Kong // method to null means the other fields should not be used. 6478447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setGpsAltitude(gpsData.altitude); 6488447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setGpsLatitude(gpsData.latitude); 6498447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setGpsLongitude(gpsData.longitude); 6508447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger parameters.setGpsProcessingMethod(gpsData.processingMethod); 6518097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 6528097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 6538097973089420749dcd1ab4974a629c2466b31ccAngus Kong 6548097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 6559d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher 6569d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher /** 6579d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher * @param ratio Desired zoom ratio, in [1.0f,+Inf). 6589d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher * @param percentages Available zoom ratios, as percentages. 6599d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher * @return Index of the closest corresponding ratio, rounded up toward 6609d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher * that of the maximum available ratio. 6619d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher */ 6629d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher private int zoomRatioToIndex(float ratio, List<Integer> percentages) { 6639d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher int percent = (int) (ratio * AndroidCameraCapabilities.ZOOM_MULTIPLIER); 6649d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher int index = Collections.binarySearch(percentages, percent); 6659d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher if (index >= 0) { 6669d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher // Found the desired ratio in the supported list 6679d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher return index; 6689d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher } else { 6699d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher // Didn't find an exact match. Where would it have been? 6709d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher index = -(index + 1); 6719d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher if (index == percentages.size()) { 6729d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher // Put it back in bounds by setting to the maximum allowable zoom 6739d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher --index; 6749d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher } 6759d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher return index; 6769d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher } 6779d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher } 678bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 679bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 680bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 6814f425ba476d62b4be7078f2084af37cf306b31c6Sol Boucher * A class which implements {@link CameraAgent.CameraProxy} and 682bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * camera handler thread. 683bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 684a0842b40441db5332a5290f941021636b1182761Sol Boucher private class AndroidCameraProxyImpl extends CameraAgent.CameraProxy { 685bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final int mCameraId; 686bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /* TODO: remove this Camera instance. */ 687bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Camera mCamera; 688b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher private final CameraDeviceInfo.Characteristics mCharacteristics; 689c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong private final AndroidCameraCapabilities mCapabilities; 690bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 691c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong private AndroidCameraProxyImpl(int cameraId, Camera camera, 692b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher CameraDeviceInfo.Characteristics characteristics, 693c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong AndroidCameraCapabilities capabilities) { 694bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 695bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraId = cameraId; 696b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher mCharacteristics = characteristics; 697c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong mCapabilities = capabilities; 698bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 699bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 7008447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger @Deprecated 701bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 702bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public android.hardware.Camera getCamera() { 703bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return mCamera; 704bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 705bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 706bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 707bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public int getCameraId() { 708bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return mCameraId; 709bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 710bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 711bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 712b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher public CameraDeviceInfo.Characteristics getCharacteristics() { 713b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher return mCharacteristics; 714b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher } 715b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher 716b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher @Override 717c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong public CameraCapabilities getCapabilities() { 718c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong return new AndroidCameraCapabilities(mCapabilities); 719c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong } 720c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong 721c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong @Override 722bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setPreviewDataCallback( 723bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final Handler handler, final CameraPreviewDataCallback cb) { 724bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 725bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 726bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 727cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.SET_PREVIEW_CALLBACK, 728cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher PreviewCallbackForward.getNewInstance( 729cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher handler, AndroidCameraProxyImpl.this, cb)) 730bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 731bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 732bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 733bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 734a0842b40441db5332a5290f941021636b1182761Sol Boucher 735bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 736bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setOneShotPreviewCallback(final Handler handler, 737bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraPreviewDataCallback cb) { 738bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 739bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 740bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 741cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.SET_ONE_SHOT_PREVIEW_CALLBACK, 742bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong PreviewCallbackForward 743bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .getNewInstance(handler, AndroidCameraProxyImpl.this, cb)) 744bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 745bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 746bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 747bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 748bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 749bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 750bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setPreviewDataCallbackWithBuffer( 751bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final Handler handler, final CameraPreviewDataCallback cb) { 752bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 753bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 754bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 755cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.SET_PREVIEW_CALLBACK_WITH_BUFFER, 756bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong PreviewCallbackForward 757bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .getNewInstance(handler, AndroidCameraProxyImpl.this, cb)) 758bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 759bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 760bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 761bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 762bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 763bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 764bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void autoFocus(final Handler handler, final CameraAFCallback cb) { 765bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final AutoFocusCallback afCallback = new AutoFocusCallback() { 766bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 767bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onAutoFocus(final boolean b, Camera camera) { 768a0842b40441db5332a5290f941021636b1182761Sol Boucher if (mCameraState.getState() != AndroidCameraStateHolder.CAMERA_FOCUSING) { 769bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.w(TAG, "onAutoFocus callback returning when not focusing"); 770bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } else { 771a0842b40441db5332a5290f941021636b1182761Sol Boucher mCameraState.setState(AndroidCameraStateHolder.CAMERA_IDLE); 772bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 773bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong handler.post(new Runnable() { 774bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 775bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 776bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong cb.onAutoFocus(b, AndroidCameraProxyImpl.this); 777bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 778bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 779bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 780bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }; 781bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 782bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 783bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 784a0842b40441db5332a5290f941021636b1182761Sol Boucher mCameraState.waitForStates(AndroidCameraStateHolder.CAMERA_IDLE); 785cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.AUTO_FOCUS, afCallback) 786cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher .sendToTarget(); 787bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 788bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 789bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 790bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 791bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 792bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 793bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setAutoFocusMoveCallback( 794bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final Handler handler, final CameraAFMoveCallback cb) { 795bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 796bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 797bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 798cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.SET_AUTO_FOCUS_MOVE_CALLBACK, 799cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher AFMoveCallbackForward.getNewInstance( 800cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher handler, AndroidCameraProxyImpl.this, cb)) 801bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 802bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 803bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 804bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 805bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 806bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 807bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void takePicture( 808bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final Handler handler, final CameraShutterCallback shutter, 809bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraPictureCallback raw, final CameraPictureCallback post, 810bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraPictureCallback jpeg) { 811bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final PictureCallback jpegCallback = new PictureCallback() { 812bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 813bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onPictureTaken(final byte[] data, Camera camera) { 814a0842b40441db5332a5290f941021636b1182761Sol Boucher if (mCameraState.getState() != AndroidCameraStateHolder.CAMERA_CAPTURING) { 81560520c4df78e595964605cf8acfa21bbafaeba84Angus Kong Log.w(TAG, "picture callback returning when not capturing"); 816bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } else { 817a0842b40441db5332a5290f941021636b1182761Sol Boucher mCameraState.setState(AndroidCameraStateHolder.CAMERA_IDLE); 818bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 819bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong handler.post(new Runnable() { 820bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 821bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 822bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong jpeg.onPictureTaken(data, AndroidCameraProxyImpl.this); 823bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 824bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 825bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 826bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }; 827bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 828bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 829bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 830bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 8317e0d39bf7b6e0f0df606e3f6c15f673f70fed3f7Sol Boucher mCameraState.waitForStates(AndroidCameraStateHolder.CAMERA_IDLE | 832a0842b40441db5332a5290f941021636b1182761Sol Boucher AndroidCameraStateHolder.CAMERA_UNLOCKED); 833bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.requestTakePicture(ShutterCallbackForward 8348097973089420749dcd1ab4974a629c2466b31ccAngus Kong .getNewInstance(handler, AndroidCameraProxyImpl.this, shutter), 835bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong PictureCallbackForward 836bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .getNewInstance(handler, AndroidCameraProxyImpl.this, raw), 837bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong PictureCallbackForward 838bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .getNewInstance(handler, AndroidCameraProxyImpl.this, post), 8398097973089420749dcd1ab4974a629c2466b31ccAngus Kong jpegCallback 8408097973089420749dcd1ab4974a629c2466b31ccAngus Kong ); 841bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 842bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 843bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 844bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 845bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 846bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setZoomChangeListener(final OnZoomChangeListener listener) { 847bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 848bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 849bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 850cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.SET_ZOOM_CHANGE_LISTENER, listener) 851cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher .sendToTarget(); 852bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 853bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 854bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 855bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 856bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 857bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setFaceDetectionCallback(final Handler handler, 858bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final CameraFaceDetectionCallback cb) { 859bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 860bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 861bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 862cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.SET_FACE_DETECTION_LISTENER, 863bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong FaceDetectionCallbackForward 864bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .getNewInstance(handler, AndroidCameraProxyImpl.this, cb)) 865bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong .sendToTarget(); 866bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 867bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 868bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 869bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 870bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 871bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setErrorCallback(final Handler handler, final CameraErrorCallback cb) { 872bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 873bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 874bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 875cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.SET_ERROR_CALLBACK, 876cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher ErrorCallbackForward.getNewInstance( 877cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher handler, AndroidCameraProxyImpl.this, cb)) 878cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher .sendToTarget(); 879bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 880bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 881bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 882bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 8838447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger @Deprecated 884bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 885bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void setParameters(final Parameters params) { 886bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (params == null) { 887bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Log.v(TAG, "null parameters in setParameters()"); 888bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return; 889bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 890bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final String flattenedParameters = params.flatten(); 891bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJob(new Runnable() { 892bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 893bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 894a0842b40441db5332a5290f941021636b1182761Sol Boucher mCameraState.waitForStates(AndroidCameraStateHolder.CAMERA_IDLE | 895a0842b40441db5332a5290f941021636b1182761Sol Boucher AndroidCameraStateHolder.CAMERA_UNLOCKED); 896cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCameraHandler.obtainMessage(CameraActions.SET_PARAMETERS, flattenedParameters) 897cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher .sendToTarget(); 898bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 899bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 900bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 901bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 9028447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger @Deprecated 903bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 904bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public Parameters getParameters() { 905bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final WaitDoneBundle bundle = new WaitDoneBundle(); 9068447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger final Parameters[] parametersHolder = new Parameters[1]; 907bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mDispatchThread.runJobSync(new Runnable() { 908bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 909bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 9108447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger Message getParametersMessage = mCameraHandler.obtainMessage( 9118447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger CameraActions.GET_PARAMETERS, parametersHolder); 9128447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger mCameraHandler.sendMessage(getParametersMessage); 913bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCameraHandler.post(bundle.mUnlockRunnable); 914bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 915bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }, bundle.mWaitLock, CAMERA_OPERATION_TIMEOUT_MS, "get parameters"); 9168447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger return parametersHolder[0]; 917bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 918bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 919bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 9208097973089420749dcd1ab4974a629c2466b31ccAngus Kong public CameraSettings getSettings() { 9218097973089420749dcd1ab4974a629c2466b31ccAngus Kong return new AndroidCameraSettings(mCapabilities, getParameters()); 9228097973089420749dcd1ab4974a629c2466b31ccAngus Kong } 9238097973089420749dcd1ab4974a629c2466b31ccAngus Kong 9248097973089420749dcd1ab4974a629c2466b31ccAngus Kong @Override 925a0842b40441db5332a5290f941021636b1182761Sol Boucher public boolean applySettings(CameraSettings settings) { 926a0842b40441db5332a5290f941021636b1182761Sol Boucher return applySettingsHelper(settings, AndroidCameraStateHolder.CAMERA_IDLE | 927a0842b40441db5332a5290f941021636b1182761Sol Boucher AndroidCameraStateHolder.CAMERA_UNLOCKED); 928bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 92901e7c02174ef268b6d6daaa5a5bb4f752d55964cAngus Kong 93001e7c02174ef268b6d6daaa5a5bb4f752d55964cAngus Kong @Override 93101e7c02174ef268b6d6daaa5a5bb4f752d55964cAngus Kong public String dumpDeviceSettings() { 9328447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger Parameters parameters = getParameters(); 9338447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger if (parameters != null) { 9348447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger String flattened = getParameters().flatten(); 9358447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger StringTokenizer tokenizer = new StringTokenizer(flattened, ";"); 9368447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger String dumpedSettings = new String(); 9378447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger while (tokenizer.hasMoreElements()) { 9388447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger dumpedSettings += tokenizer.nextToken() + '\n'; 9398447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger } 94001e7c02174ef268b6d6daaa5a5bb4f752d55964cAngus Kong 9418447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger return dumpedSettings; 9428447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger } else { 9438447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger return "[no parameters retrieved]"; 9448447d2276441983d88e8315ffa79a16a90b3d4bbAlan Newberger } 94501e7c02174ef268b6d6daaa5a5bb4f752d55964cAngus Kong } 946a0842b40441db5332a5290f941021636b1182761Sol Boucher 947a0842b40441db5332a5290f941021636b1182761Sol Boucher @Override 948a0842b40441db5332a5290f941021636b1182761Sol Boucher public Handler getCameraHandler() { 949a0842b40441db5332a5290f941021636b1182761Sol Boucher return AndroidCameraAgentImpl.this.getCameraHandler(); 950a0842b40441db5332a5290f941021636b1182761Sol Boucher } 951a0842b40441db5332a5290f941021636b1182761Sol Boucher 952a0842b40441db5332a5290f941021636b1182761Sol Boucher @Override 953a0842b40441db5332a5290f941021636b1182761Sol Boucher public DispatchThread getDispatchThread() { 954a0842b40441db5332a5290f941021636b1182761Sol Boucher return AndroidCameraAgentImpl.this.getDispatchThread(); 955a0842b40441db5332a5290f941021636b1182761Sol Boucher } 956a0842b40441db5332a5290f941021636b1182761Sol Boucher 957a0842b40441db5332a5290f941021636b1182761Sol Boucher @Override 958a0842b40441db5332a5290f941021636b1182761Sol Boucher public CameraStateHolder getCameraState() { 959a0842b40441db5332a5290f941021636b1182761Sol Boucher return mCameraState; 960a0842b40441db5332a5290f941021636b1182761Sol Boucher } 961bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 962bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 963a0842b40441db5332a5290f941021636b1182761Sol Boucher private static class AndroidCameraStateHolder extends CameraStateHolder { 964a0842b40441db5332a5290f941021636b1182761Sol Boucher /* Camera states */ 965a0842b40441db5332a5290f941021636b1182761Sol Boucher // These states are defined bitwise so we can easily to specify a set of 966a0842b40441db5332a5290f941021636b1182761Sol Boucher // states together. 967a0842b40441db5332a5290f941021636b1182761Sol Boucher public static final int CAMERA_UNOPENED = 1; 968a0842b40441db5332a5290f941021636b1182761Sol Boucher public static final int CAMERA_IDLE = 1 << 1; 969a0842b40441db5332a5290f941021636b1182761Sol Boucher public static final int CAMERA_UNLOCKED = 1 << 2; 970a0842b40441db5332a5290f941021636b1182761Sol Boucher public static final int CAMERA_CAPTURING = 1 << 3; 971a0842b40441db5332a5290f941021636b1182761Sol Boucher public static final int CAMERA_FOCUSING = 1 << 4; 972bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 973a0842b40441db5332a5290f941021636b1182761Sol Boucher public AndroidCameraStateHolder() { 974a0842b40441db5332a5290f941021636b1182761Sol Boucher this(CAMERA_UNOPENED); 975a0842b40441db5332a5290f941021636b1182761Sol Boucher } 976a0842b40441db5332a5290f941021636b1182761Sol Boucher 977a0842b40441db5332a5290f941021636b1182761Sol Boucher public AndroidCameraStateHolder(int state) { 9787e0d39bf7b6e0f0df606e3f6c15f673f70fed3f7Sol Boucher super(state); 979bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 980bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 981bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 982bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 983bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A helper class to forward AutoFocusCallback to another thread. 984bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 985bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class AFCallbackForward implements AutoFocusCallback { 986bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 987bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 988bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraAFCallback mCallback; 989bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 990bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 991bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link AFCallbackForward}. 992bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 993bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 994bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 995bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 996bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link AFCallbackForward}, 997bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameter is null. 998bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 999bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static AFCallbackForward getNewInstance( 1000bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraAFCallback cb) { 1001bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1002bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1003bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1004bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new AFCallbackForward(handler, camera, cb); 1005bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1006bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1007bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private AFCallbackForward( 1008bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraAFCallback cb) { 1009bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1010bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1011bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1012bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1013bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1014bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1015bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onAutoFocus(final boolean b, Camera camera) { 1016bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1017bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1018bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1019bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onAutoFocus(b, mCamera); 1020bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1021bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1022bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1023bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1024bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1025bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1026bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A helper class to forward ErrorCallback to another thread. 1027bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1028bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class ErrorCallbackForward implements Camera.ErrorCallback { 1029bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1030bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1031bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraErrorCallback mCallback; 1032bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1033bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1034bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link AFCallbackForward}. 1035bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1036bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1037bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1038bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1039bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link AFCallbackForward}, 1040bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameter is null. 1041bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1042bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static ErrorCallbackForward getNewInstance( 1043bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraErrorCallback cb) { 1044bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1045bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1046bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1047bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new ErrorCallbackForward(handler, camera, cb); 1048bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1049bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1050bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private ErrorCallbackForward( 1051bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraErrorCallback cb) { 1052bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1053bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1054bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1055bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1056bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1057bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1058bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onError(final int error, Camera camera) { 1059bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1060bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1061bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1062bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onError(error, mCamera); 1063bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1064bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1065bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1066bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1067bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1068bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** A helper class to forward AutoFocusMoveCallback to another thread. */ 1069bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 1070bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class AFMoveCallbackForward implements AutoFocusMoveCallback { 1071bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1072bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraAFMoveCallback mCallback; 1073bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1074bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1075bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1076bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link AFMoveCallbackForward}. 1077bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1078bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1079bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1080bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1081bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link AFMoveCallbackForward}, 1082bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameter is null. 1083bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1084bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static AFMoveCallbackForward getNewInstance( 1085bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraAFMoveCallback cb) { 1086bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1087bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1088bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1089bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new AFMoveCallbackForward(handler, camera, cb); 1090bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1091bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1092bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private AFMoveCallbackForward( 1093bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraAFMoveCallback cb) { 1094bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1095bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1096bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1097bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1098bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1099bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1100bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onAutoFocusMoving( 1101bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final boolean moving, android.hardware.Camera camera) { 1102bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1103bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1104bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1105bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onAutoFocusMoving(moving, mCamera); 1106bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1107bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1108bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1109bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1110bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1111bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1112bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A helper class to forward ShutterCallback to to another thread. 1113bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1114bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class ShutterCallbackForward implements ShutterCallback { 1115bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1116bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraShutterCallback mCallback; 1117bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1118bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1119bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1120bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link ShutterCallbackForward}. 1121bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1122bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1123bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1124bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1125bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link ShutterCallbackForward}, 1126bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameter is null. 1127bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1128bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static ShutterCallbackForward getNewInstance( 1129bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraShutterCallback cb) { 1130bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1131bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1132bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1133bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new ShutterCallbackForward(handler, camera, cb); 1134bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1135bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1136bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private ShutterCallbackForward( 1137bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraShutterCallback cb) { 1138bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1139bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1140bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1141bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1142bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1143bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1144bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onShutter() { 1145bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1146bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1147bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1148bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onShutter(mCamera); 1149bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1150bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1151bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1152bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1153bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1154bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1155bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A helper class to forward PictureCallback to another thread. 1156bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1157bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class PictureCallbackForward implements PictureCallback { 1158bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1159bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraPictureCallback mCallback; 1160bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1161bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1162bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1163bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link PictureCallbackForward}. 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 PictureCallbackForward}, 1169bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameters is null. 1170bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1171bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static PictureCallbackForward getNewInstance( 1172bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraPictureCallback cb) { 1173bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1174bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1175bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1176bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new PictureCallbackForward(handler, camera, cb); 1177bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1178bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1179bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private PictureCallbackForward( 1180bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraPictureCallback cb) { 1181bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1182bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1183bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1184bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1185bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1186bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1187bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onPictureTaken( 1188bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final byte[] data, android.hardware.Camera camera) { 1189bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1190bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1191bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1192bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onPictureTaken(data, mCamera); 1193bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1194bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1195bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1196bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1197bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1198bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1199bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * A helper class to forward PreviewCallback to another thread. 1200bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1201bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class PreviewCallbackForward implements PreviewCallback { 1202bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1203bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraPreviewDataCallback mCallback; 1204bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1205bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1206bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1207bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link PreviewCallbackForward}. 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 PreviewCallbackForward}, 1213bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameters is null. 1214bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1215bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static PreviewCallbackForward getNewInstance( 1216bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraPreviewDataCallback cb) { 1217bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1218bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1219bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1220bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new PreviewCallbackForward(handler, camera, cb); 1221bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1222bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1223bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private PreviewCallbackForward( 1224bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraPreviewDataCallback cb) { 1225bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1226bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1227bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1228bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1229bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1230bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1231bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onPreviewFrame( 1232bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final byte[] data, android.hardware.Camera camera) { 1233bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1234bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1235bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1236bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onPreviewFrame(data, mCamera); 1237bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1238bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1239bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1240bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1241bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1242bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private static class FaceDetectionCallbackForward implements FaceDetectionListener { 1243bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final Handler mHandler; 1244bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraFaceDetectionCallback mCallback; 1245bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private final CameraProxy mCamera; 1246bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1247bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 1248bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns a new instance of {@link FaceDetectionCallbackForward}. 1249bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 1250bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked in. 1251bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The {@link CameraProxy} which the callback is from. 1252bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked. 1253bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @return The instance of the {@link FaceDetectionCallbackForward}, 1254bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * or null if any parameter is null. 1255bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 1256bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public static FaceDetectionCallbackForward getNewInstance( 1257bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, CameraProxy camera, CameraFaceDetectionCallback cb) { 1258bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong if (handler == null || camera == null || cb == null) { 1259bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return null; 1260bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1261bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong return new FaceDetectionCallbackForward(handler, camera, cb); 1262bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1263bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1264bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong private FaceDetectionCallbackForward( 1265bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler h, CameraProxy camera, CameraFaceDetectionCallback cb) { 1266bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler = h; 1267bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCamera = camera; 1268bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback = cb; 1269bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1270bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 1271bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1272bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onFaceDetection( 1273bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong final Camera.Face[] faces, Camera camera) { 1274bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mHandler.post(new Runnable() { 1275bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Override 1276bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void run() { 1277bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong mCallback.onFaceDetection(faces, mCamera); 1278bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1279bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong }); 1280bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1281bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 1282bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong} 1283