1bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong/* 2bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Copyright (C) 2012 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.OnZoomChangeListener; 23bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongimport android.os.Build; 24bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongimport android.os.Handler; 25cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucherimport android.os.Looper; 266a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkinimport android.os.Message; 27bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kongimport android.view.SurfaceHolder; 28bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 29a0842b40441db5332a5290f941021636b1182761Sol Boucherimport com.android.ex.camera2.portability.debug.Log; 30a0842b40441db5332a5290f941021636b1182761Sol Boucher 31bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong/** 32bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * An interface which provides possible camera device operations. 33bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 344f425ba476d62b4be7078f2084af37cf306b31c6Sol Boucher * The client should call {@code CameraAgent.openCamera} to get an instance 354f425ba476d62b4be7078f2084af37cf306b31c6Sol Boucher * of {@link CameraAgent.CameraProxy} to control the camera. Classes 36bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * implementing this interface should have its own one unique {@code Thread} 37bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * other than the main thread for camera operations. Camera device callbacks 38bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * are wrapped since the client should not deal with 39bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * {@code android.hardware.Camera} directly. 40bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 41bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * TODO: provide callback interfaces for: 42bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * {@code android.hardware.Camera.ErrorCallback}, 43bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * {@code android.hardware.Camera.OnZoomChangeListener}, and 44bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 45a0842b40441db5332a5290f941021636b1182761Sol Boucherpublic abstract class CameraAgent { 462d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public static final long CAMERA_OPERATION_TIMEOUT_MS = 3500; 47cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher 48a0842b40441db5332a5290f941021636b1182761Sol Boucher private static final Log.Tag TAG = new Log.Tag("CamAgnt"); 49a0842b40441db5332a5290f941021636b1182761Sol Boucher 50cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher public static class CameraStartPreviewCallbackForward 51cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher implements CameraStartPreviewCallback { 52cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher private final Handler mHandler; 53cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher private final CameraStartPreviewCallback mCallback; 54cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher 55cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher public static CameraStartPreviewCallbackForward getNewInstance( 56cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher Handler handler, CameraStartPreviewCallback cb) { 57cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher if (handler == null || cb == null) { 58cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher return null; 59cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher } 60cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher return new CameraStartPreviewCallbackForward(handler, cb); 61cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher } 62cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher 63cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher private CameraStartPreviewCallbackForward(Handler h, 64cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher CameraStartPreviewCallback cb) { 65cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mHandler = h; 66cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCallback = cb; 67cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher } 68cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher 69cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher @Override 70cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher public void onPreviewStarted() { 71cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mHandler.post(new Runnable() { 72cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher @Override 73cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher public void run() { 74cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCallback.onPreviewStarted(); 75a0842b40441db5332a5290f941021636b1182761Sol Boucher }}); 76cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher } 77cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher } 78cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher 79cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher /** 80cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher * A callback helps to invoke the original callback on another 81cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher * {@link android.os.Handler}. 82cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher */ 83cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher public static class CameraOpenCallbackForward implements CameraOpenCallback { 84cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher private final Handler mHandler; 85cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher private final CameraOpenCallback mCallback; 86cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher 87cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher /** 88cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher * Returns a new instance of {@link FaceDetectionCallbackForward}. 89cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher * 90cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher * @param handler The handler in which the callback will be invoked in. 91cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher * @param cb The callback to be invoked. 92cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher * @return The instance of the {@link FaceDetectionCallbackForward}, or 93cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher * null if any parameter is null. 94cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher */ 95cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher public static CameraOpenCallbackForward getNewInstance( 96cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher Handler handler, CameraOpenCallback cb) { 97cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher if (handler == null || cb == null) { 98cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher return null; 99cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher } 100cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher return new CameraOpenCallbackForward(handler, cb); 101cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher } 102cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher 103cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher private CameraOpenCallbackForward(Handler h, CameraOpenCallback cb) { 104cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher // Given that we are using the main thread handler, we can create it 105cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher // here instead of holding onto the PhotoModule objects. In this 106cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher // way, we can avoid memory leak. 107cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mHandler = new Handler(Looper.getMainLooper()); 108cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCallback = cb; 109cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher } 110cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher 111cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher @Override 112cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher public void onCameraOpened(final CameraProxy camera) { 113cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mHandler.post(new Runnable() { 114cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher @Override 115cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher public void run() { 116cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCallback.onCameraOpened(camera); 117a0842b40441db5332a5290f941021636b1182761Sol Boucher }}); 118cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher } 119cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher 120cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher @Override 121cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher public void onCameraDisabled(final int cameraId) { 122cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mHandler.post(new Runnable() { 123cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher @Override 124cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher public void run() { 125cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCallback.onCameraDisabled(cameraId); 126a0842b40441db5332a5290f941021636b1182761Sol Boucher }}); 127cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher } 128cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher 129cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher @Override 130cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher public void onDeviceOpenFailure(final int cameraId, final String info) { 131cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mHandler.post(new Runnable() { 132cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher @Override 133cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher public void run() { 134cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCallback.onDeviceOpenFailure(cameraId, info); 135a0842b40441db5332a5290f941021636b1182761Sol Boucher }}); 136cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher } 137cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher 138cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher @Override 139cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher public void onDeviceOpenedAlready(final int cameraId, final String info) { 140cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mHandler.post(new Runnable() { 141cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher @Override 142cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher public void run() { 143cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCallback.onDeviceOpenedAlready(cameraId, info); 144a0842b40441db5332a5290f941021636b1182761Sol Boucher }}); 145cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher } 146cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher 147cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher @Override 1484f425ba476d62b4be7078f2084af37cf306b31c6Sol Boucher public void onReconnectionFailure(final CameraAgent mgr, final String info) { 149cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mHandler.post(new Runnable() { 150cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher @Override 151cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher public void run() { 152cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher mCallback.onReconnectionFailure(mgr, info); 153a0842b40441db5332a5290f941021636b1182761Sol Boucher }}); 154cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher } 155cef46862d6937bc98bf1a6b087c5daa22b5239f3Sol Boucher } 156bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 157bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 158bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * An interface which wraps 159bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * {@link android.hardware.Camera.ErrorCallback} 160bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 161a0842b40441db5332a5290f941021636b1182761Sol Boucher public static interface CameraErrorCallback { 162bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onError(int error, CameraProxy camera); 163bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 164bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 165bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 166bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * An interface which wraps 167bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * {@link android.hardware.Camera.AutoFocusCallback}. 168bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 169a0842b40441db5332a5290f941021636b1182761Sol Boucher public static interface CameraAFCallback { 170bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onAutoFocus(boolean focused, CameraProxy camera); 171bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 172bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 173bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 174bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * An interface which wraps 175bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * {@link android.hardware.Camera.AutoFocusMoveCallback}. 176bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 177a0842b40441db5332a5290f941021636b1182761Sol Boucher public static interface CameraAFMoveCallback { 178bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onAutoFocusMoving(boolean moving, CameraProxy camera); 179bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 180bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 181bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 182bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * An interface which wraps 183bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * {@link android.hardware.Camera.ShutterCallback}. 184bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 185a0842b40441db5332a5290f941021636b1182761Sol Boucher public static interface CameraShutterCallback { 186bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onShutter(CameraProxy camera); 187bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 188bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 189bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 190bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * An interface which wraps 191bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * {@link android.hardware.Camera.PictureCallback}. 192bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 193a0842b40441db5332a5290f941021636b1182761Sol Boucher public static interface CameraPictureCallback { 194bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onPictureTaken(byte[] data, CameraProxy camera); 195bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 196bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 197bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 198bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * An interface which wraps 199bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * {@link android.hardware.Camera.PreviewCallback}. 200bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 201a0842b40441db5332a5290f941021636b1182761Sol Boucher public static interface CameraPreviewDataCallback { 202bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onPreviewFrame(byte[] data, CameraProxy camera); 203bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 204bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 205bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 206bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * An interface which wraps 207bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * {@link android.hardware.Camera.FaceDetectionListener}. 208bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 209a0842b40441db5332a5290f941021636b1182761Sol Boucher public static interface CameraFaceDetectionCallback { 210bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 211bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Callback for face detection. 212bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 213bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param faces Recognized face in the preview. 214bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param camera The camera which the preview image comes from. 215bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 216bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onFaceDetection(Camera.Face[] faces, CameraProxy camera); 217bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 218bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 219bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 2207e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong * An interface to be called when the camera preview has started. 2217e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong */ 222a0842b40441db5332a5290f941021636b1182761Sol Boucher public static interface CameraStartPreviewCallback { 2237e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong /** 2247e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong * Callback when the preview starts. 2257e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong */ 2267e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong public void onPreviewStarted(); 2277e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong } 2287e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 2297e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong /** 23060520c4df78e595964605cf8acfa21bbafaeba84Angus Kong * An interface to be called for any events when opening or closing the 231bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * camera device. This error callback is different from the one defined 232bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * in the framework, {@link android.hardware.Camera.ErrorCallback}, which 233bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * is used after the camera is opened. 234bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 235a0842b40441db5332a5290f941021636b1182761Sol Boucher public static interface CameraOpenCallback { 236bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 237bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Callback when camera open succeeds. 238bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 239bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onCameraOpened(CameraProxy camera); 240bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 241bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 242bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Callback when {@link com.android.camera.CameraDisabledException} is 243bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * caught. 244bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 245bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cameraId The disabled camera. 246bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 247bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong public void onCameraDisabled(int cameraId); 248bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 249bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 250bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Callback when {@link com.android.camera.CameraHardwareException} is 251bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * caught. 252bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 253bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cameraId The camera with the hardware failure. 254b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong * @param info The extra info regarding this failure. 255bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 256b00b7a67213ee6868eb792b2a63ba0dca888a01fAngus Kong public void onDeviceOpenFailure(int cameraId, String info); 257bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 258bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 259bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Callback when trying to open the camera which is already opened. 260bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 261bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cameraId The camera which is causing the open error. 262bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 26360520c4df78e595964605cf8acfa21bbafaeba84Angus Kong public void onDeviceOpenedAlready(int cameraId, String info); 264bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 265bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 266bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Callback when {@link java.io.IOException} is caught during 267bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * {@link android.hardware.Camera#reconnect()}. 268bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 2694f425ba476d62b4be7078f2084af37cf306b31c6Sol Boucher * @param mgr The {@link CameraAgent} 270bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * with the reconnect failure. 271bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 2724f425ba476d62b4be7078f2084af37cf306b31c6Sol Boucher public void onReconnectionFailure(CameraAgent mgr, String info); 273bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 274bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 275bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 276bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Opens the camera of the specified ID asynchronously. The camera device 277bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * will be opened in the camera handler thread and will be returned through 2784f425ba476d62b4be7078f2084af37cf306b31c6Sol Boucher * the {@link CameraAgent.CameraOpenCallback# 2794f425ba476d62b4be7078f2084af37cf306b31c6Sol Boucher * onCameraOpened(com.android.camera.cameradevice.CameraAgent.CameraProxy)}. 280bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 281bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The {@link android.os.Handler} in which the callback 282bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * was handled. 28360520c4df78e595964605cf8acfa21bbafaeba84Angus Kong * @param callback The callback for the result. 284bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cameraId The camera ID to open. 285bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 286a0842b40441db5332a5290f941021636b1182761Sol Boucher public void openCamera(final Handler handler, final int cameraId, 287a0842b40441db5332a5290f941021636b1182761Sol Boucher final CameraOpenCallback callback) { 2882d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu try { 2892d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getDispatchThread().runJob(new Runnable() { 2902d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu @Override 2912d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public void run() { 2922d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getCameraHandler().obtainMessage(CameraActions.OPEN_CAMERA, cameraId, 0, 2932d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu CameraOpenCallbackForward.getNewInstance(handler, callback)).sendToTarget(); 2942d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 2952d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu }); 2962d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } catch (final RuntimeException ex) { 2972d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getCameraExceptionHandler().onDispatchThreadException(ex); 2982d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 299a0842b40441db5332a5290f941021636b1182761Sol Boucher } 30060520c4df78e595964605cf8acfa21bbafaeba84Angus Kong 30160520c4df78e595964605cf8acfa21bbafaeba84Angus Kong /** 30260520c4df78e595964605cf8acfa21bbafaeba84Angus Kong * Closes the camera device. 30360520c4df78e595964605cf8acfa21bbafaeba84Angus Kong * 30460520c4df78e595964605cf8acfa21bbafaeba84Angus Kong * @param camera The camera to close. {@code null} means all. 30560520c4df78e595964605cf8acfa21bbafaeba84Angus Kong * @param synced Whether this call should be synchronous. 30660520c4df78e595964605cf8acfa21bbafaeba84Angus Kong */ 307a0842b40441db5332a5290f941021636b1182761Sol Boucher public void closeCamera(CameraProxy camera, boolean synced) { 3082d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu try { 3092d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu if (synced) { 3102d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu // Don't bother to wait since camera is in bad state. 3112d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu if (getCameraState().isInvalid()) { 3122d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu return; 3132d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 3142d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu final WaitDoneBundle bundle = new WaitDoneBundle(); 3152d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu 3162d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getDispatchThread().runJobSync(new Runnable() { 3172d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu @Override 3182d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public void run() { 3192d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getCameraHandler().obtainMessage(CameraActions.RELEASE).sendToTarget(); 3202d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getCameraHandler().post(bundle.mUnlockRunnable); 3212d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu }}, bundle.mWaitLock, CAMERA_OPERATION_TIMEOUT_MS, "camera release"); 3222d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } else { 3232d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getDispatchThread().runJob(new Runnable() { 3242d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu @Override 3252d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public void run() { 3262d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getCameraHandler().removeCallbacksAndMessages(null); 3272d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getCameraHandler().obtainMessage(CameraActions.RELEASE).sendToTarget(); 3282d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu }}); 3292d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 3302d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } catch (final RuntimeException ex) { 3312d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getCameraExceptionHandler().onDispatchThreadException(ex); 332a0842b40441db5332a5290f941021636b1182761Sol Boucher } 333a0842b40441db5332a5290f941021636b1182761Sol Boucher } 334bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 335bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 3367e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong * Sets a callback for handling camera api runtime exceptions on 3377e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong * a handler. 3387e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong */ 3392d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public abstract void setCameraExceptionHandler(CameraExceptionHandler exceptionHandler); 3407e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 3417e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong /** 3424f425ba476d62b4be7078f2084af37cf306b31c6Sol Boucher * Recycles the resources used by this instance. CameraAgent will be in 3437e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong * an unusable state after calling this. 3447e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong */ 345a0842b40441db5332a5290f941021636b1182761Sol Boucher public abstract void recycle(); 3467e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 3477e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong /** 3487e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong * @return The camera devices info. 3497e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong */ 350a0842b40441db5332a5290f941021636b1182761Sol Boucher public abstract CameraDeviceInfo getCameraDeviceInfo(); 351a0842b40441db5332a5290f941021636b1182761Sol Boucher 352a0842b40441db5332a5290f941021636b1182761Sol Boucher /** 353a0842b40441db5332a5290f941021636b1182761Sol Boucher * @return The handler to which camera tasks should be posted. 354a0842b40441db5332a5290f941021636b1182761Sol Boucher */ 355a0842b40441db5332a5290f941021636b1182761Sol Boucher protected abstract Handler getCameraHandler(); 356a0842b40441db5332a5290f941021636b1182761Sol Boucher 357a0842b40441db5332a5290f941021636b1182761Sol Boucher /** 358a0842b40441db5332a5290f941021636b1182761Sol Boucher * @return The thread used on which client callbacks are served. 359a0842b40441db5332a5290f941021636b1182761Sol Boucher */ 360a0842b40441db5332a5290f941021636b1182761Sol Boucher protected abstract DispatchThread getDispatchThread(); 3617e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong 3627e6c76ef7faf26aa1060b4abc1c65934b4e45338Angus Kong /** 3632d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu * @return The state machine tracking the camera API's current status. 3642d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu */ 3652d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu protected abstract CameraStateHolder getCameraState(); 3662d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu 3672d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu /** 3682d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu * @return The exception handler. 3692d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu */ 3702d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu protected abstract CameraExceptionHandler getCameraExceptionHandler(); 3712d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu 3722d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu /** 373bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * An interface that takes camera operation requests and post messages to the 374bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * camera handler thread. All camera operations made through this interface is 375bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * asynchronous by default except those mentioned specifically. 376bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 3772d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public abstract static class CameraProxy { 378bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 379bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 380bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Returns the underlying {@link android.hardware.Camera} object used 381bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * by this proxy. This method should only be used when handing the 382bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * camera device over to {@link android.media.MediaRecorder} for 383bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * recording. 384bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 385bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @Deprecated 386a0842b40441db5332a5290f941021636b1182761Sol Boucher public abstract android.hardware.Camera getCamera(); 387bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 388bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 389c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong * @return The camera ID associated to by this 3904f425ba476d62b4be7078f2084af37cf306b31c6Sol Boucher * {@link CameraAgent.CameraProxy}. 391bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 392a0842b40441db5332a5290f941021636b1182761Sol Boucher public abstract int getCameraId(); 393bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 394bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 395b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher * @return The camera characteristics. 396b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher */ 397a0842b40441db5332a5290f941021636b1182761Sol Boucher public abstract CameraDeviceInfo.Characteristics getCharacteristics(); 398b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher 399b30d2c670f1262f0d60181e40dad33f2151fee4aSol Boucher /** 400c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong * @return The camera capabilities. 401c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong */ 402a0842b40441db5332a5290f941021636b1182761Sol Boucher public abstract CameraCapabilities getCapabilities(); 403c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong 404c36e3c983c232dc45ed31f3d8e98d8cdd7ac14baAngus Kong /** 4052d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu * @return The camera agent which creates this proxy. 4062d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu */ 4072d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public abstract CameraAgent getAgent(); 4082d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu 4092d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu /** 410bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Reconnects to the camera device. On success, the camera device will 4114f425ba476d62b4be7078f2084af37cf306b31c6Sol Boucher * be returned through {@link CameraAgent 4124f425ba476d62b4be7078f2084af37cf306b31c6Sol Boucher * .CameraOpenCallback#onCameraOpened(com.android.camera.cameradevice.CameraAgent 413bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * .CameraProxy)}. 414bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @see android.hardware.Camera#reconnect() 415bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 416bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The {@link android.os.Handler} in which the callback 417bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * was handled. 418bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback when any error happens. 419bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 420a0842b40441db5332a5290f941021636b1182761Sol Boucher public void reconnect(final Handler handler, final CameraOpenCallback cb) { 4212d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu try { 4222d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getDispatchThread().runJob(new Runnable() { 4232d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu @Override 4242d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public void run() { 4252d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getCameraHandler().obtainMessage(CameraActions.RECONNECT, getCameraId(), 0, 4262d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu CameraOpenCallbackForward.getNewInstance(handler, cb)).sendToTarget(); 4272d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu }}); 4282d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } catch (final RuntimeException ex) { 4292d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getAgent().getCameraExceptionHandler().onDispatchThreadException(ex); 4302d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 431a0842b40441db5332a5290f941021636b1182761Sol Boucher } 432bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 433bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 434bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Unlocks the camera device. 435bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 436bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @see android.hardware.Camera#unlock() 437bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 438a0842b40441db5332a5290f941021636b1182761Sol Boucher public void unlock() { 4392d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu // Don't bother to wait since camera is in bad state. 4402d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu if (getCameraState().isInvalid()) { 4412d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu return; 4422d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 443a0842b40441db5332a5290f941021636b1182761Sol Boucher final WaitDoneBundle bundle = new WaitDoneBundle(); 4442d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu try { 4452d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getDispatchThread().runJobSync(new Runnable() { 4462d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu @Override 4472d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public void run() { 4482d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getCameraHandler().sendEmptyMessage(CameraActions.UNLOCK); 4492d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getCameraHandler().post(bundle.mUnlockRunnable); 4502d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 4512d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu }, bundle.mWaitLock, CAMERA_OPERATION_TIMEOUT_MS, "camera unlock"); 4522d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } catch (final RuntimeException ex) { 4532d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getAgent().getCameraExceptionHandler().onDispatchThreadException(ex); 4542d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 455a0842b40441db5332a5290f941021636b1182761Sol Boucher } 456bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 457bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 458bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Locks the camera device. 459bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @see android.hardware.Camera#lock() 460bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 461a0842b40441db5332a5290f941021636b1182761Sol Boucher public void lock() { 4622d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu try { 4632d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getDispatchThread().runJob(new Runnable() { 4642d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu @Override 4652d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public void run() { 4662d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getCameraHandler().sendEmptyMessage(CameraActions.LOCK); 4672d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu }}); 4682d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } catch (final RuntimeException ex) { 4692d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getAgent().getCameraExceptionHandler().onDispatchThreadException(ex); 4702d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 471a0842b40441db5332a5290f941021636b1182761Sol Boucher } 472bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 473bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 474bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Sets the {@link android.graphics.SurfaceTexture} for preview. 475bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 4762569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher * <p>Note that, once this operation has been performed, it is no longer 4772569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher * possible to change the preview or photo sizes in the 4782569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher * {@link CameraSettings} instance for this camera, and the mutators for 4792569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher * these fields are allowed to ignore all further invocations until the 4802569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher * preview is stopped with {@link #stopPreview}.</p> 4812569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher * 482bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param surfaceTexture The {@link SurfaceTexture} for preview. 4832569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher * 4842569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher * @see CameraSettings#setPhotoSize 4852569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher * @see CameraSettings#setPreviewSize 486bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 4872569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher // XXX: Despite the above documentation about locking the sizes, the API 4882569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher // 1 implementation doesn't currently enforce this at all, although the 4892569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher // Camera class warns that preview sizes shouldn't be changed while a 4902569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher // preview is running. Furthermore, the API 2 implementation doesn't yet 4912569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher // unlock the sizes when stopPreview() is invoked (see related FIXME on 4922569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher // the STOP_PREVIEW case in its handler; in the meantime, changing API 2 4932569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher // sizes would require closing and reopening the camera. 494a0842b40441db5332a5290f941021636b1182761Sol Boucher public void setPreviewTexture(final SurfaceTexture surfaceTexture) { 4952d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu try { 4962d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getDispatchThread().runJob(new Runnable() { 4972d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu @Override 4982d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public void run() { 4992d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getCameraHandler() 5002d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu .obtainMessage(CameraActions.SET_PREVIEW_TEXTURE_ASYNC, surfaceTexture) 5012d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu .sendToTarget(); 5022d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu }}); 5032d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } catch (final RuntimeException ex) { 5042d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getAgent().getCameraExceptionHandler().onDispatchThreadException(ex); 5052d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 506a0842b40441db5332a5290f941021636b1182761Sol Boucher } 507bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 508bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 509bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Blocks until a {@link android.graphics.SurfaceTexture} has been set 510bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * for preview. 511bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 5122569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher * <p>Note that, once this operation has been performed, it is no longer 5132569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher * possible to change the preview or photo sizes in the 5142569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher * {@link CameraSettings} instance for this camera, and the mutators for 5152569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher * these fields are allowed to ignore all further invocations.</p> 5162569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher * 517bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param surfaceTexture The {@link SurfaceTexture} for preview. 5182569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher * 5192569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher * @see CameraSettings#setPhotoSize 5202569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher * @see CameraSettings#setPreviewSize 521bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 522a0842b40441db5332a5290f941021636b1182761Sol Boucher public void setPreviewTextureSync(final SurfaceTexture surfaceTexture) { 5232d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu // Don't bother to wait since camera is in bad state. 5242d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu if (getCameraState().isInvalid()) { 5252d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu return; 5262d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 527a0842b40441db5332a5290f941021636b1182761Sol Boucher final WaitDoneBundle bundle = new WaitDoneBundle(); 5282d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu try { 5292d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getDispatchThread().runJobSync(new Runnable() { 5302d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu @Override 5312d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public void run() { 5322d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getCameraHandler() 5332d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu .obtainMessage(CameraActions.SET_PREVIEW_TEXTURE_ASYNC, surfaceTexture) 5342d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu .sendToTarget(); 5352d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getCameraHandler().post(bundle.mUnlockRunnable); 5362d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu }}, bundle.mWaitLock, CAMERA_OPERATION_TIMEOUT_MS, "set preview texture"); 5372d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } catch (final RuntimeException ex) { 5382d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getAgent().getCameraExceptionHandler().onDispatchThreadException(ex); 5392d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 540a0842b40441db5332a5290f941021636b1182761Sol Boucher } 541bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 542bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 543bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Sets the {@link android.view.SurfaceHolder} for preview. 544bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 545bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param surfaceHolder The {@link SurfaceHolder} for preview. 546bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 547a0842b40441db5332a5290f941021636b1182761Sol Boucher public void setPreviewDisplay(final SurfaceHolder surfaceHolder) { 5482d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu try { 5492d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getDispatchThread().runJob(new Runnable() { 5502d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu @Override 5512d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public void run() { 5522d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getCameraHandler() 5532d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu .obtainMessage(CameraActions.SET_PREVIEW_DISPLAY_ASYNC, surfaceHolder) 5542d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu .sendToTarget(); 5552d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu }}); 5562d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } catch (final RuntimeException ex) { 5572d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getAgent().getCameraExceptionHandler().onDispatchThreadException(ex); 5582d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 559a0842b40441db5332a5290f941021636b1182761Sol Boucher } 560bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 561bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 562bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Starts the camera preview. 563bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 564a0842b40441db5332a5290f941021636b1182761Sol Boucher public void startPreview() { 5652d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu try { 566a0842b40441db5332a5290f941021636b1182761Sol Boucher getDispatchThread().runJob(new Runnable() { 567a0842b40441db5332a5290f941021636b1182761Sol Boucher @Override 568a0842b40441db5332a5290f941021636b1182761Sol Boucher public void run() { 569a0842b40441db5332a5290f941021636b1182761Sol Boucher getCameraHandler() 570a0842b40441db5332a5290f941021636b1182761Sol Boucher .obtainMessage(CameraActions.START_PREVIEW_ASYNC, null).sendToTarget(); 571a0842b40441db5332a5290f941021636b1182761Sol Boucher }}); 5722d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } catch (final RuntimeException ex) { 5732d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getAgent().getCameraExceptionHandler().onDispatchThreadException(ex); 5742d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 575a0842b40441db5332a5290f941021636b1182761Sol Boucher } 576bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 577bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 578bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Starts the camera preview and executes a callback on a handler once 579bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * the preview starts. 580bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 581a0842b40441db5332a5290f941021636b1182761Sol Boucher public void startPreviewWithCallback(final Handler h, final CameraStartPreviewCallback cb) { 5822d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu try { 583a0842b40441db5332a5290f941021636b1182761Sol Boucher getDispatchThread().runJob(new Runnable() { 584a0842b40441db5332a5290f941021636b1182761Sol Boucher @Override 585a0842b40441db5332a5290f941021636b1182761Sol Boucher public void run() { 586a0842b40441db5332a5290f941021636b1182761Sol Boucher getCameraHandler().obtainMessage(CameraActions.START_PREVIEW_ASYNC, 587a0842b40441db5332a5290f941021636b1182761Sol Boucher CameraStartPreviewCallbackForward.getNewInstance(h, cb)) 588a0842b40441db5332a5290f941021636b1182761Sol Boucher .sendToTarget(); 589a0842b40441db5332a5290f941021636b1182761Sol Boucher }}); 5902d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } catch (final RuntimeException ex) { 5912d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getAgent().getCameraExceptionHandler().onDispatchThreadException(ex); 5922d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 593a0842b40441db5332a5290f941021636b1182761Sol Boucher } 594bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 595bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 596bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Stops the camera preview synchronously. 597bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * {@code stopPreview()} must be synchronous to ensure that the caller can 598bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * continues to release resources related to camera preview. 599bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 600a0842b40441db5332a5290f941021636b1182761Sol Boucher public void stopPreview() { 6012d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu // Don't bother to wait since camera is in bad state. 6022d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu if (getCameraState().isInvalid()) { 6032d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu return; 6042d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 605a0842b40441db5332a5290f941021636b1182761Sol Boucher final WaitDoneBundle bundle = new WaitDoneBundle(); 6062d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu try { 6072d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getDispatchThread().runJobSync(new Runnable() { 6082d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu @Override 6092d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public void run() { 6102d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getCameraHandler().obtainMessage(CameraActions.STOP_PREVIEW, bundle) 6112d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu .sendToTarget(); 6122d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu }}, bundle.mWaitLock, CAMERA_OPERATION_TIMEOUT_MS, "stop preview"); 6132d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } catch (final RuntimeException ex) { 6142d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getAgent().getCameraExceptionHandler().onDispatchThreadException(ex); 6152d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 616a0842b40441db5332a5290f941021636b1182761Sol Boucher } 617bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 618bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 619bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Sets the callback for preview data. 620bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 621bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The {@link android.os.Handler} in which the callback was handled. 622bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked when the preview data is available. 623bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @see android.hardware.Camera#setPreviewCallback(android.hardware.Camera.PreviewCallback) 624bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 625a0842b40441db5332a5290f941021636b1182761Sol Boucher public abstract void setPreviewDataCallback(Handler handler, CameraPreviewDataCallback cb); 626bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 627bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 628bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Sets the one-time callback for preview data. 629bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 630bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The {@link android.os.Handler} in which the callback was handled. 631bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked when the preview data for 632bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * next frame is available. 633bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @see android.hardware.Camera#setPreviewCallback(android.hardware.Camera.PreviewCallback) 634bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 635a0842b40441db5332a5290f941021636b1182761Sol Boucher public abstract void setOneShotPreviewCallback(Handler handler, 636a0842b40441db5332a5290f941021636b1182761Sol Boucher CameraPreviewDataCallback cb); 637bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 638bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 639bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Sets the callback for preview data. 640bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 641bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked. 642bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked when the preview data is available. 643bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @see android.hardware.Camera#setPreviewCallbackWithBuffer(android.hardware.Camera.PreviewCallback) 644bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 645a0842b40441db5332a5290f941021636b1182761Sol Boucher public abstract void setPreviewDataCallbackWithBuffer(Handler handler, 646a0842b40441db5332a5290f941021636b1182761Sol Boucher CameraPreviewDataCallback cb); 647bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 648bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 649bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Adds buffer for the preview callback. 650bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 651bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param callbackBuffer The buffer allocated for the preview data. 652bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 653a0842b40441db5332a5290f941021636b1182761Sol Boucher public void addCallbackBuffer(final byte[] callbackBuffer) { 6542d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu try { 6552d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getDispatchThread().runJob(new Runnable() { 6562d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu @Override 6572d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public void run() { 6582d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getCameraHandler() 6592d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu .obtainMessage(CameraActions.ADD_CALLBACK_BUFFER, callbackBuffer) 6602d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu .sendToTarget(); 6612d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 6622d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu }); 6632d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } catch (final RuntimeException ex) { 6642d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getAgent().getCameraExceptionHandler().onDispatchThreadException(ex); 6652d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 666a0842b40441db5332a5290f941021636b1182761Sol Boucher } 667bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 668bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 669bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Starts the auto-focus process. The result will be returned through the callback. 670bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 671bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked. 672bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The auto-focus callback. 673bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 674a0842b40441db5332a5290f941021636b1182761Sol Boucher public abstract void autoFocus(Handler handler, CameraAFCallback cb); 675bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 676bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 677bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Cancels the auto-focus process. 6786a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin * 6796a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin * <p>This action has the highest priority and will get processed before anything 6806a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin * else that is pending. Moreover, any pending auto-focuses that haven't yet 6816a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin * began will also be ignored.</p> 682bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 683a0842b40441db5332a5290f941021636b1182761Sol Boucher public void cancelAutoFocus() { 6846a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin // Do not use the dispatch thread since we want to avoid a wait-cycle 6856a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin // between applySettingsHelper which waits until the state is not FOCUSING. 6866a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin // cancelAutoFocus should get executed asap, set the state back to idle. 6876a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin getCameraHandler().sendMessageAtFrontOfQueue( 6886a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin getCameraHandler().obtainMessage(CameraActions.CANCEL_AUTO_FOCUS)); 6896a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin getCameraHandler().sendEmptyMessage(CameraActions.CANCEL_AUTO_FOCUS_FINISH); 690a0842b40441db5332a5290f941021636b1182761Sol Boucher } 691bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 692bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 693bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Sets the auto-focus callback 694bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 695bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked. 696bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param cb The callback to be invoked when the preview data is available. 697bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 698bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 699a0842b40441db5332a5290f941021636b1182761Sol Boucher public abstract void setAutoFocusMoveCallback(Handler handler, CameraAFMoveCallback cb); 700bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 701bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 702bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Instrument the camera to take a picture. 703bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 704bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked. 705bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param shutter The callback for shutter action, may be null. 706bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param raw The callback for uncompressed data, may be null. 707bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param postview The callback for postview image data, may be null. 708bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param jpeg The callback for jpeg image data, may be null. 709bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @see android.hardware.Camera#takePicture( 710bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * android.hardware.Camera.ShutterCallback, 711bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * android.hardware.Camera.PictureCallback, 712bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * android.hardware.Camera.PictureCallback) 713bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 714a0842b40441db5332a5290f941021636b1182761Sol Boucher public abstract void takePicture( 715bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong Handler handler, 716bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong CameraShutterCallback shutter, 717bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong CameraPictureCallback raw, 718bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong CameraPictureCallback postview, 719bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong CameraPictureCallback jpeg); 720bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 721bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 722de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher * Sets the display orientation for camera to adjust the preview and JPEG orientation. 723bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 724de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher * @param degrees The counterclockwise rotation in degrees, relative to the device's natural 725de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher * orientation. Should be 0, 90, 180 or 270. 726bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 727a0842b40441db5332a5290f941021636b1182761Sol Boucher public void setDisplayOrientation(final int degrees) { 728de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher setDisplayOrientation(degrees, true); 729de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 730de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher 731de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher /** 732de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher * Sets the display orientation for camera to adjust the preview—and, optionally, 733de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher * JPEG—orientations. 734de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher * <p>If capture rotation is not requested, future captures will be returned in the sensor's 735de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher * physical rotation, which does not necessarily match the device's natural orientation.</p> 736de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher * 737de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher * @param degrees The counterclockwise rotation in degrees, relative to the device's natural 738de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher * orientation. Should be 0, 90, 180 or 270. 739de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher * @param capture Whether to adjust the JPEG capture orientation as well as the preview one. 740de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher */ 741de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher public void setDisplayOrientation(final int degrees, final boolean capture) { 7422d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu try { 7432d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getDispatchThread().runJob(new Runnable() { 7442d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu @Override 7452d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public void run() { 7462d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getCameraHandler() 7472d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu .obtainMessage(CameraActions.SET_DISPLAY_ORIENTATION, degrees, 7482d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu capture ? 1 : 0) 7492d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu .sendToTarget(); 7502d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu }}); 7512d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } catch (final RuntimeException ex) { 7522d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getAgent().getCameraExceptionHandler().onDispatchThreadException(ex); 7532d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 754a0842b40441db5332a5290f941021636b1182761Sol Boucher } 755bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 75625ee73acd2dbd6f60deef5306994fbf3a7997936Senpo Hu public void setJpegOrientation(final int degrees) { 7572d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu try { 7582d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getDispatchThread().runJob(new Runnable() { 7592d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu @Override 7602d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public void run() { 7612d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getCameraHandler() 7622d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu .obtainMessage(CameraActions.SET_JPEG_ORIENTATION, degrees, 0) 7632d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu .sendToTarget(); 7642d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu }}); 7652d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } catch (final RuntimeException ex) { 7662d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getAgent().getCameraExceptionHandler().onDispatchThreadException(ex); 7672d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 76825ee73acd2dbd6f60deef5306994fbf3a7997936Senpo Hu } 76925ee73acd2dbd6f60deef5306994fbf3a7997936Senpo Hu 770bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 771bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Sets the listener for zoom change. 772bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 773bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param listener The listener. 774bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 775a0842b40441db5332a5290f941021636b1182761Sol Boucher public abstract void setZoomChangeListener(OnZoomChangeListener listener); 776bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 777bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 778bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Sets the face detection listener. 779bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 780bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param handler The handler in which the callback will be invoked. 781bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param callback The callback for face detection results. 782bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 783a0842b40441db5332a5290f941021636b1182761Sol Boucher public abstract void setFaceDetectionCallback(Handler handler, 784a0842b40441db5332a5290f941021636b1182761Sol Boucher CameraFaceDetectionCallback callback); 785bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 786bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 787bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Starts the face detection. 788bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 789a0842b40441db5332a5290f941021636b1182761Sol Boucher public void startFaceDetection() { 7902d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu try { 7912d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getDispatchThread().runJob(new Runnable() { 7922d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu @Override 7932d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public void run() { 7942d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getCameraHandler().sendEmptyMessage(CameraActions.START_FACE_DETECTION); 7952d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu }}); 7962d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } catch (final RuntimeException ex) { 7972d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getAgent().getCameraExceptionHandler().onDispatchThreadException(ex); 7982d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 799a0842b40441db5332a5290f941021636b1182761Sol Boucher } 800bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 801bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 802bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Stops the face detection. 803bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 804a0842b40441db5332a5290f941021636b1182761Sol Boucher public void stopFaceDetection() { 8052d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu try { 8062d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getDispatchThread().runJob(new Runnable() { 8072d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu @Override 8082d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public void run() { 8092d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getCameraHandler().sendEmptyMessage(CameraActions.STOP_FACE_DETECTION); 8102d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu }}); 8112d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } catch (final RuntimeException ex) { 8122d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getAgent().getCameraExceptionHandler().onDispatchThreadException(ex); 8132d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 814a0842b40441db5332a5290f941021636b1182761Sol Boucher } 815bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 816bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 817bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Sets the camera parameters. 818bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 819bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param params The camera parameters to use. 820bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 8218097973089420749dcd1ab4974a629c2466b31ccAngus Kong @Deprecated 822a0842b40441db5332a5290f941021636b1182761Sol Boucher public abstract void setParameters(Camera.Parameters params); 823bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 824bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 825bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Gets the current camera parameters synchronously. This method is 826bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * synchronous since the caller has to wait for the camera to return 827bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * the parameters. If the parameters are already cached, it returns 828bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * immediately. 829bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 8308097973089420749dcd1ab4974a629c2466b31ccAngus Kong @Deprecated 831a0842b40441db5332a5290f941021636b1182761Sol Boucher public abstract Camera.Parameters getParameters(); 832bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 833bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 8348097973089420749dcd1ab4974a629c2466b31ccAngus Kong * Gets the current camera settings synchronously. 8358097973089420749dcd1ab4974a629c2466b31ccAngus Kong * <p>This method is synchronous since the caller has to wait for the 8368097973089420749dcd1ab4974a629c2466b31ccAngus Kong * camera to return the parameters. If the parameters are already 8378097973089420749dcd1ab4974a629c2466b31ccAngus Kong * cached, it returns immediately.</p> 8388097973089420749dcd1ab4974a629c2466b31ccAngus Kong */ 839a0842b40441db5332a5290f941021636b1182761Sol Boucher public abstract CameraSettings getSettings(); 840a0842b40441db5332a5290f941021636b1182761Sol Boucher 841a0842b40441db5332a5290f941021636b1182761Sol Boucher /** 842a0842b40441db5332a5290f941021636b1182761Sol Boucher * Default implementation of {@link #applySettings(CameraSettings)} 843a0842b40441db5332a5290f941021636b1182761Sol Boucher * that is only missing the set of states it needs to wait for 844a0842b40441db5332a5290f941021636b1182761Sol Boucher * before applying the settings. 845a0842b40441db5332a5290f941021636b1182761Sol Boucher * 846a0842b40441db5332a5290f941021636b1182761Sol Boucher * @param settings The settings to use on the device. 847a0842b40441db5332a5290f941021636b1182761Sol Boucher * @param statesToAwait Bitwise OR of the required camera states. 848a0842b40441db5332a5290f941021636b1182761Sol Boucher * @return Whether the settings can be applied. 849a0842b40441db5332a5290f941021636b1182761Sol Boucher */ 850de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher protected boolean applySettingsHelper(CameraSettings settings, 851a0842b40441db5332a5290f941021636b1182761Sol Boucher final int statesToAwait) { 852a0842b40441db5332a5290f941021636b1182761Sol Boucher if (settings == null) { 8539d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher Log.v(TAG, "null argument in applySettings()"); 854a0842b40441db5332a5290f941021636b1182761Sol Boucher return false; 855a0842b40441db5332a5290f941021636b1182761Sol Boucher } 856a0842b40441db5332a5290f941021636b1182761Sol Boucher if (!getCapabilities().supports(settings)) { 8579d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher Log.w(TAG, "Unsupported settings in applySettings()"); 858a0842b40441db5332a5290f941021636b1182761Sol Boucher return false; 859a0842b40441db5332a5290f941021636b1182761Sol Boucher } 860a0842b40441db5332a5290f941021636b1182761Sol Boucher 861de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher final CameraSettings copyOfSettings = settings.copy(); 8622d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu try { 8632d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getDispatchThread().runJob(new Runnable() { 8642d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu @Override 8652d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public void run() { 8662d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu CameraStateHolder cameraState = getCameraState(); 8672d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu // Don't bother to wait since camera is in bad state. 8682d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu if (cameraState.isInvalid()) { 8692d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu return; 8702d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 8712d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu cameraState.waitForStates(statesToAwait); 8722d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getCameraHandler().obtainMessage(CameraActions.APPLY_SETTINGS, copyOfSettings) 8732d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu .sendToTarget(); 8742d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu }}); 8752d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } catch (final RuntimeException ex) { 8762d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getAgent().getCameraExceptionHandler().onDispatchThreadException(ex); 8772d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 878a0842b40441db5332a5290f941021636b1182761Sol Boucher return true; 879a0842b40441db5332a5290f941021636b1182761Sol Boucher } 8808097973089420749dcd1ab4974a629c2466b31ccAngus Kong 8818097973089420749dcd1ab4974a629c2466b31ccAngus Kong /** 8828097973089420749dcd1ab4974a629c2466b31ccAngus Kong * Applies the settings to the camera device. 8838097973089420749dcd1ab4974a629c2466b31ccAngus Kong * 8846a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin * <p>If the camera is either focusing or capturing; settings applications 8856a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin * will be (asynchronously) deferred until those operations complete.</p> 8866a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin * 8878097973089420749dcd1ab4974a629c2466b31ccAngus Kong * @param settings The settings to use on the device. 8888097973089420749dcd1ab4974a629c2466b31ccAngus Kong * @return Whether the settings can be applied. 8898097973089420749dcd1ab4974a629c2466b31ccAngus Kong */ 890a0842b40441db5332a5290f941021636b1182761Sol Boucher public abstract boolean applySettings(CameraSettings settings); 8918097973089420749dcd1ab4974a629c2466b31ccAngus Kong 8928097973089420749dcd1ab4974a629c2466b31ccAngus Kong /** 893bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Forces {@code CameraProxy} to update the cached version of the camera 8948097973089420749dcd1ab4974a629c2466b31ccAngus Kong * settings regardless of the dirty bit. 895bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 896a0842b40441db5332a5290f941021636b1182761Sol Boucher public void refreshSettings() { 8972d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu try { 8982d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getDispatchThread().runJob(new Runnable() { 8992d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu @Override 9002d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public void run() { 9012d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getCameraHandler().sendEmptyMessage(CameraActions.REFRESH_PARAMETERS); 9022d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu }}); 9032d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } catch (final RuntimeException ex) { 9042d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getAgent().getCameraExceptionHandler().onDispatchThreadException(ex); 9052d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 906a0842b40441db5332a5290f941021636b1182761Sol Boucher } 907bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong 908bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong /** 909bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * Enables/Disables the camera shutter sound. 910bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * 911bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * @param enable {@code true} to enable the shutter sound, 912bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong * {@code false} to disable it. 913bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong */ 914a0842b40441db5332a5290f941021636b1182761Sol Boucher public void enableShutterSound(final boolean enable) { 9152d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu try { 9162d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getDispatchThread().runJob(new Runnable() { 9172d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu @Override 9182d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu public void run() { 9192d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getCameraHandler() 9202d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu .obtainMessage(CameraActions.ENABLE_SHUTTER_SOUND, (enable ? 1 : 0), 0) 9212d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu .sendToTarget(); 9222d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu }}); 9232d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } catch (final RuntimeException ex) { 9242d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu getAgent().getCameraExceptionHandler().onDispatchThreadException(ex); 9252d01b8e2b5ad30ce3c442799cad4c3d26607fc6fSenpo Hu } 926a0842b40441db5332a5290f941021636b1182761Sol Boucher } 92701e7c02174ef268b6d6daaa5a5bb4f752d55964cAngus Kong 92801e7c02174ef268b6d6daaa5a5bb4f752d55964cAngus Kong /** 92901e7c02174ef268b6d6daaa5a5bb4f752d55964cAngus Kong * Dumps the current settings of the camera device. 93001e7c02174ef268b6d6daaa5a5bb4f752d55964cAngus Kong * 93101e7c02174ef268b6d6daaa5a5bb4f752d55964cAngus Kong * <p>The content varies based on the underlying camera API settings 93201e7c02174ef268b6d6daaa5a5bb4f752d55964cAngus Kong * implementation.</p> 93301e7c02174ef268b6d6daaa5a5bb4f752d55964cAngus Kong * 93401e7c02174ef268b6d6daaa5a5bb4f752d55964cAngus Kong * @return The content of the device settings represented by a string. 93501e7c02174ef268b6d6daaa5a5bb4f752d55964cAngus Kong */ 936a0842b40441db5332a5290f941021636b1182761Sol Boucher public abstract String dumpDeviceSettings(); 937a0842b40441db5332a5290f941021636b1182761Sol Boucher 938a0842b40441db5332a5290f941021636b1182761Sol Boucher /** 939a0842b40441db5332a5290f941021636b1182761Sol Boucher * @return The handler to which camera tasks should be posted. 940a0842b40441db5332a5290f941021636b1182761Sol Boucher */ 941a0842b40441db5332a5290f941021636b1182761Sol Boucher public abstract Handler getCameraHandler(); 942a0842b40441db5332a5290f941021636b1182761Sol Boucher 943a0842b40441db5332a5290f941021636b1182761Sol Boucher /** 944a0842b40441db5332a5290f941021636b1182761Sol Boucher * @return The thread used on which client callbacks are served. 945a0842b40441db5332a5290f941021636b1182761Sol Boucher */ 946a0842b40441db5332a5290f941021636b1182761Sol Boucher public abstract DispatchThread getDispatchThread(); 947a0842b40441db5332a5290f941021636b1182761Sol Boucher 948a0842b40441db5332a5290f941021636b1182761Sol Boucher /** 949a0842b40441db5332a5290f941021636b1182761Sol Boucher * @return The state machine tracking the camera API's current mode. 950a0842b40441db5332a5290f941021636b1182761Sol Boucher */ 951a0842b40441db5332a5290f941021636b1182761Sol Boucher public abstract CameraStateHolder getCameraState(); 952a0842b40441db5332a5290f941021636b1182761Sol Boucher } 953a0842b40441db5332a5290f941021636b1182761Sol Boucher 954a0842b40441db5332a5290f941021636b1182761Sol Boucher public static class WaitDoneBundle { 955a0842b40441db5332a5290f941021636b1182761Sol Boucher public final Runnable mUnlockRunnable; 956a0842b40441db5332a5290f941021636b1182761Sol Boucher public final Object mWaitLock; 957a0842b40441db5332a5290f941021636b1182761Sol Boucher 958a0842b40441db5332a5290f941021636b1182761Sol Boucher WaitDoneBundle() { 959a0842b40441db5332a5290f941021636b1182761Sol Boucher mWaitLock = new Object(); 960a0842b40441db5332a5290f941021636b1182761Sol Boucher mUnlockRunnable = new Runnable() { 961a0842b40441db5332a5290f941021636b1182761Sol Boucher @Override 962a0842b40441db5332a5290f941021636b1182761Sol Boucher public void run() { 963a0842b40441db5332a5290f941021636b1182761Sol Boucher synchronized (mWaitLock) { 964a0842b40441db5332a5290f941021636b1182761Sol Boucher mWaitLock.notifyAll(); 965a0842b40441db5332a5290f941021636b1182761Sol Boucher } 966a0842b40441db5332a5290f941021636b1182761Sol Boucher }}; 967a0842b40441db5332a5290f941021636b1182761Sol Boucher } 9686a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin 9696a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin /** 9706a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin * Notify all synchronous waiters waiting on message completion with {@link #mWaitLock}. 9716a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin * 9726a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin * <p>This assumes that the message was sent with {@code this} as the {@code Message#obj}. 9736a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin * Otherwise the message is ignored.</p> 9746a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin */ 9756a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin /*package*/ static void unblockSyncWaiters(Message msg) { 9766a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin if (msg == null) return; 9776a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin 9786a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin if (msg.obj instanceof WaitDoneBundle) { 9796a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin WaitDoneBundle bundle = (WaitDoneBundle)msg.obj; 9806a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin bundle.mUnlockRunnable.run(); 9816a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin } 9826a9babad6eb8ac3e79a5e036d878ed7408e79f26Igor Murashkin } 983bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong } 984bdaaaf5f0257168590fa8965e4d59b054636e6dfAngus Kong} 985