1ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/* 2ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Copyright (C) 2014 The Android Open Source Project 3ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 4ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Licensed under the Apache License, Version 2.0 (the "License"); 5ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * you may not use this file except in compliance with the License. 6ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * You may obtain a copy of the License at 7ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 8ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * http://www.apache.org/licenses/LICENSE-2.0 9ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 10ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Unless required by applicable law or agreed to in writing, software 11ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * distributed under the License is distributed on an "AS IS" BASIS, 12ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * See the License for the specific language governing permissions and 14ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * limitations under the License 15ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */ 16ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 17ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianpackage com.android.incallui; 18ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 19ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.content.Context; 20ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.hardware.camera2.CameraAccessException; 21ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.hardware.camera2.CameraCharacteristics; 22ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.hardware.camera2.CameraManager; 23ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport java.util.Collections; 24ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport java.util.Set; 25ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport java.util.concurrent.ConcurrentHashMap; 26ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 27ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/** Used to track which camera is used for outgoing video. */ 28ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianpublic class InCallCameraManager { 29ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 30ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private final Set<Listener> mCameraSelectionListeners = 31ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian Collections.newSetFromMap(new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1)); 32ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** The camera ID for the front facing camera. */ 33ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private String mFrontFacingCameraId; 34ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** The camera ID for the rear facing camera. */ 35ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private String mRearFacingCameraId; 36ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** The currently active camera. */ 37ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private boolean mUseFrontFacingCamera; 38ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** 39ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Indicates whether the list of cameras has been initialized yet. Initialization is delayed until 40ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * a video call is present. 41ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */ 42ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private boolean mIsInitialized = false; 43ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** The context. */ 44ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private Context mContext; 45ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 46ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** 47ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Initializes the InCall CameraManager. 48ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 49ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * @param context The current context. 50ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */ 51ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public InCallCameraManager(Context context) { 52ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian mUseFrontFacingCamera = true; 53ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian mContext = context; 54ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 55ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 56ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** 57ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Sets whether the front facing camera should be used or not. 58ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 59ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * @param useFrontFacingCamera {@code True} if the front facing camera is to be used. 60ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */ 61ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public void setUseFrontFacingCamera(boolean useFrontFacingCamera) { 62ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian mUseFrontFacingCamera = useFrontFacingCamera; 63ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian for (Listener listener : mCameraSelectionListeners) { 64ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian listener.onActiveCameraSelectionChanged(mUseFrontFacingCamera); 65ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 66ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 67ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 68ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** 69ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Determines whether the front facing camera is currently in use. 70ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 71ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * @return {@code True} if the front facing camera is in use. 72ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */ 73ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public boolean isUsingFrontFacingCamera() { 74ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return mUseFrontFacingCamera; 75ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 76ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 77ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** 78ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Determines the active camera ID. 79ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 80ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * @return The active camera ID. 81ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */ 82ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public String getActiveCameraId() { 83ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian maybeInitializeCameraList(mContext); 84ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 85ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (mUseFrontFacingCamera) { 86ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return mFrontFacingCameraId; 87ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } else { 88ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return mRearFacingCameraId; 89ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 90ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 91ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 92ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** Calls when camera permission is granted by user. */ 93ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public void onCameraPermissionGranted() { 94ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian for (Listener listener : mCameraSelectionListeners) { 95ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian listener.onCameraPermissionGranted(); 96ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 97ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 98ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 99ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** 100ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Get the list of cameras available for use. 101ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 102ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * @param context The context. 103ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */ 104ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private void maybeInitializeCameraList(Context context) { 105ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (mIsInitialized || context == null) { 106ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return; 107ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 108ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 109ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian Log.v(this, "initializeCameraList"); 110ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 111ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian CameraManager cameraManager = null; 112ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian try { 113ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian cameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE); 114ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } catch (Exception e) { 115ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian Log.e(this, "Could not get camera service."); 116ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return; 117ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 118ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 119ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (cameraManager == null) { 120ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return; 121ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 122ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 123ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian String[] cameraIds = {}; 124ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian try { 125ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian cameraIds = cameraManager.getCameraIdList(); 126ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } catch (CameraAccessException e) { 127ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian Log.d(this, "Could not access camera: " + e); 128ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // Camera disabled by device policy. 129ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return; 130ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 131ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 132ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian for (int i = 0; i < cameraIds.length; i++) { 133ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian CameraCharacteristics c = null; 134ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian try { 135ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian c = cameraManager.getCameraCharacteristics(cameraIds[i]); 136ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } catch (IllegalArgumentException e) { 137ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // Device Id is unknown. 138ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } catch (CameraAccessException e) { 139ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // Camera disabled by device policy. 140ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 141ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (c != null) { 142ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian int facingCharacteristic = c.get(CameraCharacteristics.LENS_FACING); 143ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (facingCharacteristic == CameraCharacteristics.LENS_FACING_FRONT) { 144ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian mFrontFacingCameraId = cameraIds[i]; 145ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } else if (facingCharacteristic == CameraCharacteristics.LENS_FACING_BACK) { 146ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian mRearFacingCameraId = cameraIds[i]; 147ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 148ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 149ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 150ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 151ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian mIsInitialized = true; 152ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian Log.v(this, "initializeCameraList : done"); 153ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 154ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 155ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public void addCameraSelectionListener(Listener listener) { 156ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (listener != null) { 157ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian mCameraSelectionListeners.add(listener); 158ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 159ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 160ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 161ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public void removeCameraSelectionListener(Listener listener) { 162ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (listener != null) { 163ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian mCameraSelectionListeners.remove(listener); 164ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 165ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 166ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 167ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public interface Listener { 168ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 169ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian void onActiveCameraSelectionChanged(boolean isUsingFrontFacingCamera); 170ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 171ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian void onCameraPermissionGranted(); 172ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 173ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian} 174