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