blob: b5a8f91af9cfe2700e6ffc7a1313a39c7d47ab56 [file] [log] [blame]
Eric Erfanianccca3152017-02-22 16:32:36 -08001/*
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
17package com.android.incallui;
18
19import android.content.Context;
20import android.hardware.camera2.CameraAccessException;
21import android.hardware.camera2.CameraCharacteristics;
22import android.hardware.camera2.CameraManager;
23import java.util.Collections;
24import java.util.Set;
25import java.util.concurrent.ConcurrentHashMap;
26
27/** Used to track which camera is used for outgoing video. */
28public class InCallCameraManager {
29
linyuh183cb712017-12-27 17:02:37 -080030 private final Set<Listener> cameraSelectionListeners =
Eric Erfanianccca3152017-02-22 16:32:36 -080031 Collections.newSetFromMap(new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1));
32 /** The camera ID for the front facing camera. */
linyuh183cb712017-12-27 17:02:37 -080033 private String frontFacingCameraId;
Eric Erfanianccca3152017-02-22 16:32:36 -080034 /** The camera ID for the rear facing camera. */
linyuh183cb712017-12-27 17:02:37 -080035 private String rearFacingCameraId;
Eric Erfanianccca3152017-02-22 16:32:36 -080036 /** The currently active camera. */
linyuh183cb712017-12-27 17:02:37 -080037 private boolean useFrontFacingCamera;
Eric Erfanianccca3152017-02-22 16:32:36 -080038 /**
39 * Indicates whether the list of cameras has been initialized yet. Initialization is delayed until
40 * a video call is present.
41 */
linyuh183cb712017-12-27 17:02:37 -080042 private boolean isInitialized = false;
Eric Erfanianccca3152017-02-22 16:32:36 -080043 /** The context. */
linyuh183cb712017-12-27 17:02:37 -080044 private Context context;
Eric Erfanianccca3152017-02-22 16:32:36 -080045
46 /**
47 * Initializes the InCall CameraManager.
48 *
49 * @param context The current context.
50 */
51 public InCallCameraManager(Context context) {
linyuh183cb712017-12-27 17:02:37 -080052 useFrontFacingCamera = true;
53 this.context = context;
Eric Erfanianccca3152017-02-22 16:32:36 -080054 }
55
56 /**
57 * Sets whether the front facing camera should be used or not.
58 *
59 * @param useFrontFacingCamera {@code True} if the front facing camera is to be used.
60 */
61 public void setUseFrontFacingCamera(boolean useFrontFacingCamera) {
linyuh183cb712017-12-27 17:02:37 -080062 this.useFrontFacingCamera = useFrontFacingCamera;
63 for (Listener listener : cameraSelectionListeners) {
64 listener.onActiveCameraSelectionChanged(this.useFrontFacingCamera);
Eric Erfanianccca3152017-02-22 16:32:36 -080065 }
66 }
67
68 /**
69 * Determines whether the front facing camera is currently in use.
70 *
71 * @return {@code True} if the front facing camera is in use.
72 */
73 public boolean isUsingFrontFacingCamera() {
linyuh183cb712017-12-27 17:02:37 -080074 return useFrontFacingCamera;
Eric Erfanianccca3152017-02-22 16:32:36 -080075 }
76
77 /**
78 * Determines the active camera ID.
79 *
80 * @return The active camera ID.
81 */
82 public String getActiveCameraId() {
linyuh183cb712017-12-27 17:02:37 -080083 maybeInitializeCameraList(context);
Eric Erfanianccca3152017-02-22 16:32:36 -080084
linyuh183cb712017-12-27 17:02:37 -080085 if (useFrontFacingCamera) {
86 return frontFacingCameraId;
Eric Erfanianccca3152017-02-22 16:32:36 -080087 } else {
linyuh183cb712017-12-27 17:02:37 -080088 return rearFacingCameraId;
Eric Erfanianccca3152017-02-22 16:32:36 -080089 }
90 }
91
92 /** Calls when camera permission is granted by user. */
93 public void onCameraPermissionGranted() {
linyuh183cb712017-12-27 17:02:37 -080094 for (Listener listener : cameraSelectionListeners) {
Eric Erfanianccca3152017-02-22 16:32:36 -080095 listener.onCameraPermissionGranted();
96 }
97 }
98
99 /**
100 * Get the list of cameras available for use.
101 *
102 * @param context The context.
103 */
104 private void maybeInitializeCameraList(Context context) {
linyuh183cb712017-12-27 17:02:37 -0800105 if (isInitialized || context == null) {
Eric Erfanianccca3152017-02-22 16:32:36 -0800106 return;
107 }
108
109 Log.v(this, "initializeCameraList");
110
111 CameraManager cameraManager = null;
112 try {
113 cameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
114 } catch (Exception e) {
115 Log.e(this, "Could not get camera service.");
116 return;
117 }
118
119 if (cameraManager == null) {
120 return;
121 }
122
123 String[] cameraIds = {};
124 try {
125 cameraIds = cameraManager.getCameraIdList();
126 } catch (CameraAccessException e) {
127 Log.d(this, "Could not access camera: " + e);
128 // Camera disabled by device policy.
129 return;
130 }
131
132 for (int i = 0; i < cameraIds.length; i++) {
133 CameraCharacteristics c = null;
134 try {
135 c = cameraManager.getCameraCharacteristics(cameraIds[i]);
136 } catch (IllegalArgumentException e) {
137 // Device Id is unknown.
138 } catch (CameraAccessException e) {
139 // Camera disabled by device policy.
140 }
141 if (c != null) {
142 int facingCharacteristic = c.get(CameraCharacteristics.LENS_FACING);
143 if (facingCharacteristic == CameraCharacteristics.LENS_FACING_FRONT) {
linyuh183cb712017-12-27 17:02:37 -0800144 frontFacingCameraId = cameraIds[i];
Eric Erfanianccca3152017-02-22 16:32:36 -0800145 } else if (facingCharacteristic == CameraCharacteristics.LENS_FACING_BACK) {
linyuh183cb712017-12-27 17:02:37 -0800146 rearFacingCameraId = cameraIds[i];
Eric Erfanianccca3152017-02-22 16:32:36 -0800147 }
148 }
149 }
150
linyuh183cb712017-12-27 17:02:37 -0800151 isInitialized = true;
Eric Erfanianccca3152017-02-22 16:32:36 -0800152 Log.v(this, "initializeCameraList : done");
153 }
154
155 public void addCameraSelectionListener(Listener listener) {
156 if (listener != null) {
linyuh183cb712017-12-27 17:02:37 -0800157 cameraSelectionListeners.add(listener);
Eric Erfanianccca3152017-02-22 16:32:36 -0800158 }
159 }
160
161 public void removeCameraSelectionListener(Listener listener) {
162 if (listener != null) {
linyuh183cb712017-12-27 17:02:37 -0800163 cameraSelectionListeners.remove(listener);
Eric Erfanianccca3152017-02-22 16:32:36 -0800164 }
165 }
166
167 public interface Listener {
168
169 void onActiveCameraSelectionChanged(boolean isUsingFrontFacingCamera);
170
171 void onCameraPermissionGranted();
172 }
173}