CameraController.java revision 6190c36db653e848f29d1caefc4fa1bb61e8a662
120fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong/* 220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong * Copyright (C) 2013 The Android Open Source Project 320fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong * 420fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong * Licensed under the Apache License, Version 2.0 (the "License"); 520fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong * you may not use this file except in compliance with the License. 620fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong * You may obtain a copy of the License at 720fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong * 820fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong * http://www.apache.org/licenses/LICENSE-2.0 920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong * 1020fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong * Unless required by applicable law or agreed to in writing, software 1120fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong * distributed under the License is distributed on an "AS IS" BASIS, 1220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1320fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong * See the License for the specific language governing permissions and 1420fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong * limitations under the License. 1520fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong */ 1620fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 1720fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kongpackage com.android.camera.app; 1820fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 1920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kongimport android.content.Context; 2020fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kongimport android.hardware.Camera; 2120fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kongimport android.os.Handler; 2220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 2320fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kongimport com.android.camera.CameraDisabledException; 245596b4c902dcb685928b43678f428746ca5ffd08Angus Kongimport com.android.camera.debug.Log; 2520fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kongimport com.android.camera.util.CameraUtil; 265a344964cb003525727c31d295ca3a592c245606Sol Boucherimport com.android.ex.camera2.portability.CameraDeviceInfo; 275a344964cb003525727c31d295ca3a592c245606Sol Boucherimport com.android.ex.camera2.portability.CameraAgent; 285a344964cb003525727c31d295ca3a592c245606Sol Boucherimport com.android.ex.camera2.portability.CameraAgent.CameraExceptionCallback; 2920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 3020fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong/** 3120fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong * A class which implements {@link com.android.camera.app.CameraProvider} used 3220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong * by {@link com.android.camera.CameraActivity}. 3320fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong * TODO: Make this class package private. 3420fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong */ 355a344964cb003525727c31d295ca3a592c245606Sol Boucherpublic class CameraController implements CameraAgent.CameraOpenCallback, CameraProvider { 365596b4c902dcb685928b43678f428746ca5ffd08Angus Kong private static final Log.Tag TAG = new Log.Tag("CameraController"); 37432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong private static final int EMPTY_REQUEST = -1; 38846d3abfe3da2fa2a5593c7d40a196005408bed1Sascha Haeberling private final Context mContext; 395a344964cb003525727c31d295ca3a592c245606Sol Boucher private CameraAgent.CameraOpenCallback mCallbackReceiver; 40846d3abfe3da2fa2a5593c7d40a196005408bed1Sascha Haeberling private final Handler mCallbackHandler; 415a344964cb003525727c31d295ca3a592c245606Sol Boucher private final CameraAgent mCameraAgent; 42c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong private CameraDeviceInfo mInfo; 4320fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 445a344964cb003525727c31d295ca3a592c245606Sol Boucher private CameraAgent.CameraProxy mCameraProxy; 45432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong private int mRequestingCameraId = EMPTY_REQUEST; 4620fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 4720fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong /** 4820fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong * Constructor. 4920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong * 5020fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong * @param context The {@link android.content.Context} used to check if the 5120fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong * camera is disabled. 5220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong * @param handler The {@link android.os.Handler} to post the camera 5320fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong * callbacks to. 5420fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong * @param cameraManager Used for camera open/close. 5520fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong */ 565a344964cb003525727c31d295ca3a592c245606Sol Boucher public CameraController(Context context, CameraAgent.CameraOpenCallback callbackReceiver, 575a344964cb003525727c31d295ca3a592c245606Sol Boucher Handler handler, CameraAgent cameraManager) { 5820fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong mContext = context; 5920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong mCallbackReceiver = callbackReceiver; 6020fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong mCallbackHandler = handler; 615a344964cb003525727c31d295ca3a592c245606Sol Boucher mCameraAgent = cameraManager; 625a344964cb003525727c31d295ca3a592c245606Sol Boucher mInfo = mCameraAgent.getCameraDeviceInfo(); 63c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong if (mInfo == null && mCallbackReceiver != null) { 64c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong mCallbackReceiver.onDeviceOpenFailure(-1, "GETTING_CAMERA_INFO"); 65c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong } 6620fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 6720fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 6820fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong @Override 69630d55ba8111357730119899565026be503264c0Erin Dahlgren public void setCameraDefaultExceptionCallback(CameraExceptionCallback callback, 70630d55ba8111357730119899565026be503264c0Erin Dahlgren Handler handler) { 715a344964cb003525727c31d295ca3a592c245606Sol Boucher mCameraAgent.setCameraDefaultExceptionCallback(callback, handler); 72630d55ba8111357730119899565026be503264c0Erin Dahlgren } 73630d55ba8111357730119899565026be503264c0Erin Dahlgren 74630d55ba8111357730119899565026be503264c0Erin Dahlgren @Override 7520fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong public Camera.CameraInfo[] getCameraInfo() { 76c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong if (mInfo == null) { 77c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong return null; 78c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong } 79c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong return mInfo.getCameraInfos(); 8020fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 8120fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 8220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong @Override 836190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren public int getCurrentCameraId() { 846190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren if (mCameraProxy != null) { 856190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren return mCameraProxy.getCameraId(); 866190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren } else { 876190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren return -1; 886190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren } 896190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren } 906190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren 916190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren @Override 9220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong public int getNumberOfCameras() { 93c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong if (mInfo == null) { 94c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong return 0; 95c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong } 96c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong return mInfo.getNumberOfCameras(); 9720fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 9820fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 9920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong @Override 10020fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong public int getFirstBackCameraId() { 101c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong if (mInfo == null) { 102c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong return -1; 103c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong } 104c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong return mInfo.getFirstBackCameraId(); 10520fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 10620fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 10720fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong @Override 10820fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong public int getFirstFrontCameraId() { 109c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong if (mInfo == null) { 110c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong return -1; 111c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong } 112c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong return mInfo.getFirstFrontCameraId(); 11320fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 11420fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 11520fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong @Override 11639b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong public boolean isFrontFacingCamera(int id) { 117c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong if (mInfo == null) { 118c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong return false; 119c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong } 120c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong if (id >= mInfo.getCameraInfos().length || mInfo.getCameraInfos()[id] == null) { 12139b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong Log.e(TAG, "Camera info not available:" + id); 12239b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong return false; 12339b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong } 124c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong return (mInfo.getCameraInfos()[id].facing == Camera.CameraInfo.CAMERA_FACING_FRONT); 12539b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong } 12639b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong 12739b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong @Override 12839b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong public boolean isBackFacingCamera(int id) { 129c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong if (mInfo == null) { 130c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong return false; 131c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong } 132c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong if (id >= mInfo.getCameraInfos().length || mInfo.getCameraInfos()[id] == null) { 13339b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong Log.e(TAG, "Camera info not available:" + id); 13439b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong return false; 13539b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong } 136c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong return (mInfo.getCameraInfos()[id].facing == Camera.CameraInfo.CAMERA_FACING_BACK); 13739b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong } 13839b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong 13939b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong @Override 1405a344964cb003525727c31d295ca3a592c245606Sol Boucher public void onCameraOpened(CameraAgent.CameraProxy camera) { 1410b9eb5bb8d2ef409e8c88196c0c82c8ece65728bAngus Kong Log.v(TAG, "onCameraOpened"); 1420b9eb5bb8d2ef409e8c88196c0c82c8ece65728bAngus Kong if (mRequestingCameraId != camera.getCameraId()) { 1430b9eb5bb8d2ef409e8c88196c0c82c8ece65728bAngus Kong // Not requesting any camera or not waiting for this one. 144f578829a0f9a298fd5e4fdd9081b768f25811599Angus Kong return; 145f578829a0f9a298fd5e4fdd9081b768f25811599Angus Kong } 1460b9eb5bb8d2ef409e8c88196c0c82c8ece65728bAngus Kong mCameraProxy = camera; 147432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong mRequestingCameraId = EMPTY_REQUEST; 1480fed7e62bfa0d8351b91d3531228a113637963a3Sascha Haeberling if (mCallbackReceiver != null) { 1490fed7e62bfa0d8351b91d3531228a113637963a3Sascha Haeberling mCallbackReceiver.onCameraOpened(camera); 1500fed7e62bfa0d8351b91d3531228a113637963a3Sascha Haeberling } 15120fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 15220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 15320fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong @Override 15420fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong public void onCameraDisabled(int cameraId) { 1550fed7e62bfa0d8351b91d3531228a113637963a3Sascha Haeberling if (mCallbackReceiver != null) { 1560fed7e62bfa0d8351b91d3531228a113637963a3Sascha Haeberling mCallbackReceiver.onCameraDisabled(cameraId); 1570fed7e62bfa0d8351b91d3531228a113637963a3Sascha Haeberling } 15820fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 15920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 16020fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong @Override 1611b9d4fb6f649262e491c0fa743229b4930a87802Angus Kong public void onDeviceOpenFailure(int cameraId, String info) { 1620fed7e62bfa0d8351b91d3531228a113637963a3Sascha Haeberling if (mCallbackReceiver != null) { 1631b9d4fb6f649262e491c0fa743229b4930a87802Angus Kong mCallbackReceiver.onDeviceOpenFailure(cameraId, info); 1640fed7e62bfa0d8351b91d3531228a113637963a3Sascha Haeberling } 16520fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 16620fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 16720fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong @Override 1680b9eb5bb8d2ef409e8c88196c0c82c8ece65728bAngus Kong public void onDeviceOpenedAlready(int cameraId, String info) { 1690fed7e62bfa0d8351b91d3531228a113637963a3Sascha Haeberling if (mCallbackReceiver != null) { 1700b9eb5bb8d2ef409e8c88196c0c82c8ece65728bAngus Kong mCallbackReceiver.onDeviceOpenedAlready(cameraId, info); 1710fed7e62bfa0d8351b91d3531228a113637963a3Sascha Haeberling } 17262753ae94be2ae7c08bf24ebcf1c462975af230fAngus Kong } 17362753ae94be2ae7c08bf24ebcf1c462975af230fAngus Kong 17462753ae94be2ae7c08bf24ebcf1c462975af230fAngus Kong @Override 1755a344964cb003525727c31d295ca3a592c245606Sol Boucher public void onReconnectionFailure(CameraAgent mgr, String info) { 1760fed7e62bfa0d8351b91d3531228a113637963a3Sascha Haeberling if (mCallbackReceiver != null) { 1770b9eb5bb8d2ef409e8c88196c0c82c8ece65728bAngus Kong mCallbackReceiver.onReconnectionFailure(mgr, info); 1780fed7e62bfa0d8351b91d3531228a113637963a3Sascha Haeberling } 17920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 18020fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 18120fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong @Override 18220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong public void requestCamera(int id) { 183432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong // Based on 184432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong // (mRequestingCameraId == id, mRequestingCameraId == EMPTY_REQUEST), 185432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong // we have (T, T), (T, F), (F, T), (F, F). 186432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong // (T, T): implies id == EMPTY_REQUEST. We don't allow this to happen 187432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong // here. Return. 188432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong // (F, F): A previous request hasn't been fulfilled yet. Return. 189432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong // (T, F): Already requested the same camera. No-op. Return. 190432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong // (F, T): Nothing is going on. Continue. 191432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong if (mRequestingCameraId != EMPTY_REQUEST || mRequestingCameraId == id) { 19220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong return; 19320fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 194c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong if (mInfo == null) { 195c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong return; 196c44c5d93a681d98719dfffdf7223c694e1cab715Angus Kong } 19720fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong mRequestingCameraId = id; 19820fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong if (mCameraProxy == null) { 19920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong // No camera yet. 2005a344964cb003525727c31d295ca3a592c245606Sol Boucher checkAndOpenCamera(mContext, mCameraAgent, id, mCallbackHandler, this); 20120fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } else if (mCameraProxy.getCameraId() != id) { 20220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong // Already has another camera opened. 2035a344964cb003525727c31d295ca3a592c245606Sol Boucher mCameraAgent.closeCamera(mCameraProxy, false); 2045a344964cb003525727c31d295ca3a592c245606Sol Boucher checkAndOpenCamera(mContext, mCameraAgent, id, mCallbackHandler, this); 20520fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } else { 20620fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong // The same camera, just do a reconnect. 2070b9eb5bb8d2ef409e8c88196c0c82c8ece65728bAngus Kong Log.v(TAG, "reconnecting to use the existing camera"); 20820fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong mCameraProxy.reconnect(mCallbackHandler, this); 20920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong mCameraProxy = null; 21020fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 21120fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 21220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 21320fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong @Override 21497e282a3764215ac193726e0d259e55bf94369feAngus Kong public boolean waitingForCamera() { 21597e282a3764215ac193726e0d259e55bf94369feAngus Kong return mRequestingCameraId != EMPTY_REQUEST; 21697e282a3764215ac193726e0d259e55bf94369feAngus Kong } 21797e282a3764215ac193726e0d259e55bf94369feAngus Kong 21897e282a3764215ac193726e0d259e55bf94369feAngus Kong @Override 21920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong public void releaseCamera(int id) { 220f578829a0f9a298fd5e4fdd9081b768f25811599Angus Kong if (mCameraProxy == null) { 221432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong if (mRequestingCameraId == EMPTY_REQUEST) { 222f578829a0f9a298fd5e4fdd9081b768f25811599Angus Kong // Camera not requested yet. 223f578829a0f9a298fd5e4fdd9081b768f25811599Angus Kong Log.w(TAG, "Trying to release the camera before requesting"); 224f578829a0f9a298fd5e4fdd9081b768f25811599Angus Kong } 225f578829a0f9a298fd5e4fdd9081b768f25811599Angus Kong // Camera requested but not available yet. 226432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong mRequestingCameraId = EMPTY_REQUEST; 227f578829a0f9a298fd5e4fdd9081b768f25811599Angus Kong return; 228f578829a0f9a298fd5e4fdd9081b768f25811599Angus Kong } 22920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong if (mCameraProxy.getCameraId() != id) { 23020fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong throw new IllegalStateException("Trying to release an unopened camera."); 23120fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 232432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong mRequestingCameraId = EMPTY_REQUEST; 23320fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 23420fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 235846d3abfe3da2fa2a5593c7d40a196005408bed1Sascha Haeberling public void removeCallbackReceiver() { 236846d3abfe3da2fa2a5593c7d40a196005408bed1Sascha Haeberling mCallbackReceiver = null; 237846d3abfe3da2fa2a5593c7d40a196005408bed1Sascha Haeberling } 238846d3abfe3da2fa2a5593c7d40a196005408bed1Sascha Haeberling 23920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong /** 24020fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong * Closes the opened camera device. 24120fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong * TODO: Make this method package private. 24220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong */ 2430b9eb5bb8d2ef409e8c88196c0c82c8ece65728bAngus Kong public void closeCamera(boolean synced) { 24420fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong Log.v(TAG, "closing camera"); 24520fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong mCameraProxy = null; 2465a344964cb003525727c31d295ca3a592c245606Sol Boucher mCameraAgent.closeCamera(mCameraProxy, synced); 247432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong mRequestingCameraId = EMPTY_REQUEST; 24820fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 24920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 2505a344964cb003525727c31d295ca3a592c245606Sol Boucher private static void checkAndOpenCamera(Context context, CameraAgent cameraManager, 2515a344964cb003525727c31d295ca3a592c245606Sol Boucher final int cameraId, Handler handler, final CameraAgent.CameraOpenCallback cb) { 25220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong try { 25320fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong CameraUtil.throwIfCameraDisabled(context); 2540b9eb5bb8d2ef409e8c88196c0c82c8ece65728bAngus Kong cameraManager.openCamera(handler, cameraId, cb); 25520fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } catch (CameraDisabledException ex) { 25620fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong handler.post(new Runnable() { 25720fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong @Override 25820fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong public void run() { 25920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong cb.onCameraDisabled(cameraId); 26020fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 26120fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong }); 26220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 26320fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 2644d4a4bc8891bbfc5a7ca842f2981829ac3a716e8Doris Liu 2654d4a4bc8891bbfc5a7ca842f2981829ac3a716e8Doris Liu public void setOneShotPreviewCallback(Handler handler, 2665a344964cb003525727c31d295ca3a592c245606Sol Boucher CameraAgent.CameraPreviewDataCallback cb) { 2674d4a4bc8891bbfc5a7ca842f2981829ac3a716e8Doris Liu mCameraProxy.setOneShotPreviewCallback(handler, cb); 2684d4a4bc8891bbfc5a7ca842f2981829ac3a716e8Doris Liu } 26920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong} 270