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