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