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 {
onActiveCameraSelectionChanged(boolean isUsingFrontFacingCamera)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      */
InCallCameraManager(Context context)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      */
setUseFrontFacingCamera(boolean useFrontFacingCamera)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      */
isUsingFrontFacingCamera()97     public boolean isUsingFrontFacingCamera() {
98         return mUseFrontFacingCamera;
99     }
100 
101     /**
102      * Determines the active camera ID.
103      *
104      * @return The active camera ID.
105      */
getActiveCameraId()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      */
maybeInitializeCameraList(Context context)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 
addCameraSelectionListener(Listener listener)173     public void addCameraSelectionListener(Listener listener) {
174         if (listener != null) {
175             mCameraSelectionListeners.add(listener);
176         }
177     }
178 
removeCameraSelectionListener(Listener listener)179     public void removeCameraSelectionListener(Listener listener) {
180         if (listener != null) {
181             mCameraSelectionListeners.remove(listener);
182         }
183     }
184 }
185