CameraController.java revision 97e282a3764215ac193726e0d259e55bf94369fe
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 Kongimport android.util.Log; 2320fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 2420fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kongimport com.android.camera.CameraDisabledException; 2520fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kongimport com.android.camera.util.CameraUtil; 2620fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 2720fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong/** 2820fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong * A class which implements {@link com.android.camera.app.CameraProvider} used 2920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong * by {@link com.android.camera.CameraActivity}. 3020fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong * TODO: Make this class package private. 3120fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong */ 3220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kongpublic class CameraController implements CameraManager.CameraOpenCallback, CameraProvider { 33432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong private static final String TAG = "CameraController"; 34432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong private static final int EMPTY_REQUEST = -1; 35846d3abfe3da2fa2a5593c7d40a196005408bed1Sascha Haeberling private final Context mContext; 3620fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong private CameraManager.CameraOpenCallback mCallbackReceiver; 37846d3abfe3da2fa2a5593c7d40a196005408bed1Sascha Haeberling private final Handler mCallbackHandler; 3820fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong private final CameraManager mCameraManager; 3920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong private final Camera.CameraInfo[] mCameraInfos; 4020fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong private final int mNumberOfCameras; 4120fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong private final int mFirstBackCameraId; 4220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong private final int mFirstFrontCameraId; 4320fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 4420fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong private CameraManager.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 */ 5620fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong public CameraController(Context context, CameraManager.CameraOpenCallback callbackReceiver, 5720fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong Handler handler, CameraManager cameraManager) { 5820fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong mContext = context; 5920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong mCallbackReceiver = callbackReceiver; 6020fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong mCallbackHandler = handler; 6120fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong mCameraManager = cameraManager; 6220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong mNumberOfCameras = Camera.getNumberOfCameras(); 6320fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong mCameraInfos = new Camera.CameraInfo[mNumberOfCameras]; 6420fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong for (int i = 0; i < mNumberOfCameras; i++) { 6520fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong mCameraInfos[i] = new Camera.CameraInfo(); 6620fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong Camera.getCameraInfo(i, mCameraInfos[i]); 6720fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 6820fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 6920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong int firstFront = -1; 7020fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong int firstBack = -1; 7120fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong // Get the first (smallest) back and first front camera id. 7218500a493634b593dc8ba1e74b46d1f10bb6d031Angus Kong for (int i = mNumberOfCameras - 1; i >= 0; i--) { 7320fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong if (mCameraInfos[i].facing == Camera.CameraInfo.CAMERA_FACING_BACK) { 7420fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong firstBack = i; 7520fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } else { 7620fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong if (mCameraInfos[i].facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 7720fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong firstFront = i; 7820fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 7920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 8020fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 8120fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong mFirstBackCameraId = firstBack; 8220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong mFirstFrontCameraId = firstFront; 8320fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 8420fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 8520fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong @Override 8620fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong public Camera.CameraInfo[] getCameraInfo() { 8720fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong return mCameraInfos; 8820fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 8920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 9020fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong @Override 9120fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong public int getNumberOfCameras() { 9220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong return mNumberOfCameras; 9320fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 9420fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 9520fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong @Override 9620fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong public int getFirstBackCameraId() { 9720fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong return mFirstBackCameraId; 9820fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 9920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 10020fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong @Override 10120fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong public int getFirstFrontCameraId() { 10220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong return mFirstFrontCameraId; 10320fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 10420fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 10520fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong @Override 10639b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong public boolean isFrontFacingCamera(int id) { 10739b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong if (id >= mCameraInfos.length || mCameraInfos[id] == null) { 10839b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong Log.e(TAG, "Camera info not available:" + id); 10939b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong return false; 11039b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong } 11139b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong return (mCameraInfos[id].facing == Camera.CameraInfo.CAMERA_FACING_FRONT); 11239b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong } 11339b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong 11439b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong @Override 11539b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong public boolean isBackFacingCamera(int id) { 11639b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong if (id >= mCameraInfos.length || mCameraInfos[id] == null) { 11739b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong Log.e(TAG, "Camera info not available:" + id); 11839b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong return false; 11939b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong } 12039b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong return (mCameraInfos[id].facing == Camera.CameraInfo.CAMERA_FACING_BACK); 12139b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong } 12239b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong 12339b460b805adaa54f310d8637868b3a5c792b2f5Angus Kong @Override 12420fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong public void onCameraOpened(CameraManager.CameraProxy camera) { 12520fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong mCameraProxy = camera; 126432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong if(mRequestingCameraId == EMPTY_REQUEST) { 127f578829a0f9a298fd5e4fdd9081b768f25811599Angus Kong // Not requesting any camera. 128f578829a0f9a298fd5e4fdd9081b768f25811599Angus Kong return; 129f578829a0f9a298fd5e4fdd9081b768f25811599Angus Kong } 130432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong mRequestingCameraId = EMPTY_REQUEST; 13120fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong mCallbackReceiver.onCameraOpened(camera); 13220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 13320fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 13420fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong @Override 13520fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong public void onCameraDisabled(int cameraId) { 13620fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong mCallbackReceiver.onCameraDisabled(cameraId); 13720fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 13820fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 13920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong @Override 14020fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong public void onDeviceOpenFailure(int cameraId) { 14120fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong mCallbackReceiver.onDeviceOpenFailure(cameraId); 14220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 14320fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 14420fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong @Override 14562753ae94be2ae7c08bf24ebcf1c462975af230fAngus Kong public void onDeviceOpenedAlready(int cameraId) { 14662753ae94be2ae7c08bf24ebcf1c462975af230fAngus Kong mCallbackReceiver.onDeviceOpenedAlready(cameraId); 14762753ae94be2ae7c08bf24ebcf1c462975af230fAngus Kong } 14862753ae94be2ae7c08bf24ebcf1c462975af230fAngus Kong 14962753ae94be2ae7c08bf24ebcf1c462975af230fAngus Kong @Override 15020fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong public void onReconnectionFailure(CameraManager mgr) { 15120fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong mCallbackReceiver.onReconnectionFailure(mgr); 15220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 15320fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 15420fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong @Override 15520fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong public void requestCamera(int id) { 156432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong // Based on 157432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong // (mRequestingCameraId == id, mRequestingCameraId == EMPTY_REQUEST), 158432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong // we have (T, T), (T, F), (F, T), (F, F). 159432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong // (T, T): implies id == EMPTY_REQUEST. We don't allow this to happen 160432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong // here. Return. 161432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong // (F, F): A previous request hasn't been fulfilled yet. Return. 162432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong // (T, F): Already requested the same camera. No-op. Return. 163432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong // (F, T): Nothing is going on. Continue. 164432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong if (mRequestingCameraId != EMPTY_REQUEST || mRequestingCameraId == id) { 16520fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong return; 16620fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 16720fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong mRequestingCameraId = id; 16820fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong if (mCameraProxy == null) { 16920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong // No camera yet. 17020fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong checkAndOpenCamera(mContext, mCameraManager, id, mCallbackHandler, this); 17120fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } else if (mCameraProxy.getCameraId() != id) { 17220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong // Already has another camera opened. 17320fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong mCameraProxy.release(false); 17420fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong mCameraProxy = null; 17520fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong checkAndOpenCamera(mContext, mCameraManager, id, mCallbackHandler, this); 17620fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } else { 17720fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong // The same camera, just do a reconnect. 17820fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong mCameraProxy.reconnect(mCallbackHandler, this); 17920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong mCameraProxy = null; 18020fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 18120fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 18220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 18320fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong @Override 18497e282a3764215ac193726e0d259e55bf94369feAngus Kong public boolean waitingForCamera() { 18597e282a3764215ac193726e0d259e55bf94369feAngus Kong return mRequestingCameraId != EMPTY_REQUEST; 18697e282a3764215ac193726e0d259e55bf94369feAngus Kong } 18797e282a3764215ac193726e0d259e55bf94369feAngus Kong 18897e282a3764215ac193726e0d259e55bf94369feAngus Kong @Override 18920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong public void releaseCamera(int id) { 190f578829a0f9a298fd5e4fdd9081b768f25811599Angus Kong if (mCameraProxy == null) { 191432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong if (mRequestingCameraId == EMPTY_REQUEST) { 192f578829a0f9a298fd5e4fdd9081b768f25811599Angus Kong // Camera not requested yet. 193f578829a0f9a298fd5e4fdd9081b768f25811599Angus Kong Log.w(TAG, "Trying to release the camera before requesting"); 194f578829a0f9a298fd5e4fdd9081b768f25811599Angus Kong } 195f578829a0f9a298fd5e4fdd9081b768f25811599Angus Kong // Camera requested but not available yet. 196432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong mRequestingCameraId = EMPTY_REQUEST; 197f578829a0f9a298fd5e4fdd9081b768f25811599Angus Kong return; 198f578829a0f9a298fd5e4fdd9081b768f25811599Angus Kong } 19920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong if (mCameraProxy.getCameraId() != id) { 20020fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong throw new IllegalStateException("Trying to release an unopened camera."); 20120fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 202432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong mRequestingCameraId = EMPTY_REQUEST; 20320fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 20420fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 205846d3abfe3da2fa2a5593c7d40a196005408bed1Sascha Haeberling public void removeCallbackReceiver() { 206846d3abfe3da2fa2a5593c7d40a196005408bed1Sascha Haeberling mCallbackReceiver = null; 207846d3abfe3da2fa2a5593c7d40a196005408bed1Sascha Haeberling } 208846d3abfe3da2fa2a5593c7d40a196005408bed1Sascha Haeberling 20920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong /** 21020fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong * Closes the opened camera device. 21120fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong * TODO: Make this method package private. 21220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong */ 21320fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong public void closeCamera() { 21420fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong Log.v(TAG, "closing camera"); 21520fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong if (mCameraProxy == null) { 21620fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong return; 21720fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 21820fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong mCameraProxy.release(true); 21920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong mCameraProxy = null; 220432c964bb528a28600f19e18e81ff2b6407bb22dAngus Kong mRequestingCameraId = EMPTY_REQUEST; 22120fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 22220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong 22320fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong private static void checkAndOpenCamera(Context context, CameraManager cameraManager, 22420fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong final int cameraId, Handler handler, final CameraManager.CameraOpenCallback cb) { 22520fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong try { 22620fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong CameraUtil.throwIfCameraDisabled(context); 22720fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong cameraManager.cameraOpen(handler, cameraId, cb); 22820fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } catch (CameraDisabledException ex) { 22920fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong handler.post(new Runnable() { 23020fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong @Override 23120fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong public void run() { 23220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong cb.onCameraDisabled(cameraId); 23320fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 23420fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong }); 23520fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 23620fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong } 2374d4a4bc8891bbfc5a7ca842f2981829ac3a716e8Doris Liu 2384d4a4bc8891bbfc5a7ca842f2981829ac3a716e8Doris Liu public void setOneShotPreviewCallback(Handler handler, 2394d4a4bc8891bbfc5a7ca842f2981829ac3a716e8Doris Liu CameraManager.CameraPreviewDataCallback cb) { 2404d4a4bc8891bbfc5a7ca842f2981829ac3a716e8Doris Liu mCameraProxy.setOneShotPreviewCallback(handler, cb); 2414d4a4bc8891bbfc5a7ca842f2981829ac3a716e8Doris Liu } 24220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kong} 243