| /* |
| * Copyright (C) 2014 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.testingcamera2; |
| |
| import java.util.HashSet; |
| import java.util.Set; |
| |
| import android.Manifest; |
| import android.app.Activity; |
| import android.content.pm.PackageManager; |
| import android.hardware.camera2.CameraCharacteristics; |
| import android.hardware.camera2.CameraDevice; |
| import android.hardware.camera2.CameraManager; |
| import android.hardware.camera2.CameraAccessException; |
| |
| /** |
| * A central manager of camera devices and current clients for them. |
| * |
| */ |
| public class CameraOps2 extends CameraManager.AvailabilityCallback { |
| |
| private final CameraManager mCameraManager; |
| private final Activity mActivity; |
| private final Set<CameraDevice> mOpenCameras = new HashSet<CameraDevice>(); |
| |
| // For persisting values for permission requests |
| private static final int PERMISSIONS_REQUEST_CAMERA = 1; |
| private String mDelayedOpenId = null; |
| private CameraDevice.StateCallback mDelayedOpenListener = null; |
| |
| public CameraOps2(Activity activity) { |
| mActivity = activity; |
| mCameraManager = (CameraManager) activity.getSystemService(Activity.CAMERA_SERVICE); |
| if (mCameraManager == null) { |
| throw new AssertionError("Can't connect to camera manager!"); |
| } |
| try { |
| String[] cameraIds = mCameraManager.getCameraIdList(); |
| TLog.i("Camera count: %d", cameraIds.length); |
| for (String cameraId : cameraIds) { |
| TLog.i(" Camera %s", cameraId); |
| } |
| } catch (CameraAccessException e) { |
| TLog.e("Unable to get camera list: %s", e); |
| } |
| |
| mCameraManager.registerAvailabilityCallback(this, /*handler*/null); |
| } |
| |
| /** |
| * Add a listener for new camera addition events, and retrieve the list of |
| * current cameras |
| * |
| * @param listener |
| * A listener to notify on changes to camera availability |
| * @return the current list of available cameras |
| * @throws CameraAccessException |
| * if the camera manager cannot be queried |
| */ |
| public String[] getCamerasAndListen(CameraManager.AvailabilityCallback listener) |
| throws CameraAccessException { |
| |
| mCameraManager.registerAvailabilityCallback(listener, /*handler*/null); |
| |
| return mCameraManager.getCameraIdList(); |
| } |
| |
| public void removeAvailabilityCallback(CameraManager.AvailabilityCallback listener) { |
| mCameraManager.unregisterAvailabilityCallback(listener); |
| } |
| |
| @Override |
| public void onCameraAvailable(String cameraId) { |
| TLog.i("Camera %s is now available", cameraId); |
| } |
| |
| @Override |
| public void onCameraUnavailable(String cameraId) { |
| TLog.i("Camera %s is now unavailable", cameraId); |
| } |
| |
| /** |
| * Attempt to open a camera device. Returns false if the open call cannot be |
| * made or the device is already open |
| * |
| * @param cameraId id of the camera to open |
| * @param listener listener to notify of camera device state changes |
| * @return true if open call was sent successfully. The client needs to wait |
| * for its listener to be called to determine if open will succeed. |
| */ |
| public boolean openCamera(String cameraId, CameraDevice.StateCallback listener) { |
| for (CameraDevice camera : mOpenCameras) { |
| if (camera.getId() == cameraId) { |
| TLog.e("Camera %s is already open", cameraId); |
| return false; |
| } |
| } |
| if (mActivity.checkSelfPermission(Manifest.permission.CAMERA) |
| != PackageManager.PERMISSION_GRANTED) { |
| TLog.i("Requesting camera permissions"); |
| |
| mDelayedOpenId = cameraId; |
| mDelayedOpenListener = listener; |
| |
| mActivity.requestPermissions(new String[] {Manifest.permission.CAMERA}, |
| PERMISSIONS_REQUEST_CAMERA); |
| return false; |
| } |
| |
| return doOpenCamera(cameraId, listener); |
| } |
| |
| private boolean doOpenCamera(String cameraId, CameraDevice.StateCallback listener) { |
| try { |
| DeviceStateCallback proxyListener = new DeviceStateCallback(listener); |
| mCameraManager.openCamera(cameraId, proxyListener, null); |
| } catch (CameraAccessException e) { |
| TLog.e("Unable to open camera %s.", e, cameraId); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| public void onRequestPermissionsResult (int requestCode, String[] permissions, |
| int[] grantResults) { |
| if (requestCode == PERMISSIONS_REQUEST_CAMERA) { |
| if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { |
| TLog.i("Camera permission granted"); |
| if (mDelayedOpenId != null && mDelayedOpenListener != null) { |
| doOpenCamera(mDelayedOpenId, mDelayedOpenListener); |
| } |
| mDelayedOpenId = null; |
| mDelayedOpenListener = null; |
| } else { |
| TLog.i("Camera permission denied, not opening camera"); |
| if (mDelayedOpenId != null && mDelayedOpenListener != null) { |
| mDelayedOpenListener.onError(null, |
| CameraDevice.StateCallback.ERROR_CAMERA_DISABLED); |
| mDelayedOpenId = null; |
| mDelayedOpenListener = null; |
| } |
| } |
| if (grantResults[1] == PackageManager.PERMISSION_GRANTED) { |
| TLog.i("Storage permission granted"); |
| } else { |
| TLog.i("Storage permission not granted; saving will not work"); |
| } |
| } |
| } |
| |
| public CameraCharacteristics getCameraInfo(String cameraId) { |
| try { |
| return mCameraManager.getCameraCharacteristics(cameraId); |
| } catch (CameraAccessException e) { |
| TLog.e("Unable to get camera characteristics for camera %s.", e, cameraId); |
| } |
| return null; |
| } |
| |
| private class DeviceStateCallback extends CameraDevice.StateCallback { |
| |
| private final CameraDevice.StateCallback mClientListener; |
| |
| public DeviceStateCallback(CameraDevice.StateCallback clientListener) { |
| mClientListener = clientListener; |
| } |
| |
| @Override |
| public void onClosed(CameraDevice camera) { |
| mOpenCameras.remove(camera); |
| TLog.i("Camera %s now closed", camera.getId()); |
| mClientListener.onClosed(camera); |
| } |
| |
| @Override |
| public void onDisconnected(CameraDevice camera) { |
| TLog.i("Camera %s now disconnected", camera.getId()); |
| mClientListener.onDisconnected(camera); |
| } |
| |
| @Override |
| public void onError(CameraDevice camera, int error) { |
| TLog.i("Camera %s encountered error: %d", camera.getId(), error); |
| mClientListener.onError(camera, error); |
| } |
| |
| @Override |
| public void onOpened(CameraDevice camera) { |
| mOpenCameras.add(camera); |
| TLog.i("Camera %s now open", camera.getId()); |
| mClientListener.onOpened(camera); |
| } |
| |
| } |
| } |