• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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.settings.safetycenter;
18 
19 import android.app.PendingIntent;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.hardware.face.FaceManager;
23 import android.hardware.fingerprint.FingerprintManager;
24 import android.os.Bundle;
25 import android.os.Process;
26 import android.os.UserHandle;
27 import android.os.UserManager;
28 import android.safetycenter.SafetyEvent;
29 import android.safetycenter.SafetySourceData;
30 import android.safetycenter.SafetySourceStatus;
31 
32 import com.android.settings.Utils;
33 import com.android.settings.biometrics.BiometricNavigationUtils;
34 import com.android.settings.biometrics.activeunlock.ActiveUnlockStatusUtils;
35 import com.android.settings.biometrics.combination.CombinedBiometricStatusUtils;
36 import com.android.settings.biometrics.face.FaceStatusUtils;
37 import com.android.settings.biometrics.fingerprint.FingerprintStatusUtils;
38 import com.android.settingslib.RestrictedLockUtils;
39 
40 /** Combined Biometrics Safety Source for Safety Center. */
41 public final class BiometricsSafetySource {
42 
43     public static final String SAFETY_SOURCE_ID = "AndroidBiometrics";
44     private static final int REQUEST_CODE_COMBINED_BIOMETRIC_SETTING = 10;
45     private static final int REQUEST_CODE_FACE_SETTING = 20;
46     private static final int REQUEST_CODE_FINGERPRINT_SETTING = 30;
47 
BiometricsSafetySource()48     private BiometricsSafetySource() {}
49 
50     /** Sets biometric safety data for Safety Center. */
setSafetySourceData(Context context, SafetyEvent safetyEvent)51     public static void setSafetySourceData(Context context, SafetyEvent safetyEvent) {
52         if (!SafetyCenterManagerWrapper.get().isEnabled(context)) {
53             return;
54         }
55 
56         final UserHandle userHandle = Process.myUserHandle();
57         final int userId = userHandle.getIdentifier();
58         final UserManager userManager = UserManager.get(context);
59         UserHandle profileParentUserHandle = userManager.getProfileParent(userHandle);
60         if (profileParentUserHandle == null) {
61             profileParentUserHandle = userHandle;
62         }
63         final Context profileParentContext =
64                 context.createContextAsUser(profileParentUserHandle, 0);
65 
66         final BiometricNavigationUtils biometricNavigationUtils =
67                 new BiometricNavigationUtils(userId);
68         final CombinedBiometricStatusUtils combinedBiometricStatusUtils =
69                 new CombinedBiometricStatusUtils(context, userId);
70         final ActiveUnlockStatusUtils activeUnlockStatusUtils =
71                 new ActiveUnlockStatusUtils(context);
72         if (!userManager.isProfile() && activeUnlockStatusUtils.isAvailable()) {
73             final RestrictedLockUtils.EnforcedAdmin disablingAdmin =
74                     combinedBiometricStatusUtils.getDisablingAdmin();
75             setBiometricSafetySourceData(
76                     context,
77                     activeUnlockStatusUtils.getTitleForActiveUnlock(),
78                     combinedBiometricStatusUtils.getSummary(),
79                     createPendingIntent(
80                             context,
81                             biometricNavigationUtils.getBiometricSettingsIntent(
82                                     context,
83                                     combinedBiometricStatusUtils.getSettingsClassName(),
84                                     disablingAdmin,
85                                     Bundle.EMPTY),
86                             REQUEST_CODE_COMBINED_BIOMETRIC_SETTING),
87                     disablingAdmin == null /* enabled */,
88                     combinedBiometricStatusUtils.hasEnrolled(),
89                     safetyEvent);
90             return;
91         }
92         if (combinedBiometricStatusUtils.isAvailable()) {
93             final RestrictedLockUtils.EnforcedAdmin disablingAdmin =
94                     combinedBiometricStatusUtils.getDisablingAdmin();
95             setBiometricSafetySourceData(
96                     context,
97                     combinedBiometricStatusUtils.getTitle(),
98                     combinedBiometricStatusUtils.getSummary(),
99                     createPendingIntent(
100                             profileParentContext,
101                             biometricNavigationUtils
102                                     .getBiometricSettingsIntent(
103                                             context,
104                                             combinedBiometricStatusUtils
105                                                     .getSettingsClassNameBasedOnUser(),
106                                             disablingAdmin,
107                                             Bundle.EMPTY)
108                                     .setIdentifier(Integer.toString(userId)),
109                             REQUEST_CODE_COMBINED_BIOMETRIC_SETTING),
110                     disablingAdmin == null /* enabled */,
111                     combinedBiometricStatusUtils.hasEnrolled(),
112                     safetyEvent);
113             return;
114         }
115 
116         final FaceManager faceManager = Utils.getFaceManagerOrNull(context);
117         final FaceStatusUtils faceStatusUtils = new FaceStatusUtils(context, faceManager, userId);
118 
119         if (faceStatusUtils.isAvailable()) {
120             final RestrictedLockUtils.EnforcedAdmin disablingAdmin =
121                     faceStatusUtils.getDisablingAdmin();
122             setBiometricSafetySourceData(
123                     context,
124                     faceStatusUtils.getTitle(),
125                     faceStatusUtils.getSummary(),
126                     createPendingIntent(
127                             profileParentContext,
128                             biometricNavigationUtils
129                                     .getBiometricSettingsIntent(
130                                             context,
131                                             faceStatusUtils.getSettingsClassName(),
132                                             disablingAdmin,
133                                             Bundle.EMPTY)
134                                     .setIdentifier(Integer.toString(userId)),
135                             REQUEST_CODE_FACE_SETTING),
136                     disablingAdmin == null /* enabled */,
137                     faceStatusUtils.hasEnrolled(),
138                     safetyEvent);
139 
140             return;
141         }
142 
143         final FingerprintManager fingerprintManager = Utils.getFingerprintManagerOrNull(context);
144         final FingerprintStatusUtils fingerprintStatusUtils =
145                 new FingerprintStatusUtils(context, fingerprintManager, userId);
146 
147         if (fingerprintStatusUtils.isAvailable()) {
148             final RestrictedLockUtils.EnforcedAdmin disablingAdmin =
149                     fingerprintStatusUtils.getDisablingAdmin();
150             setBiometricSafetySourceData(
151                     context,
152                     fingerprintStatusUtils.getTitle(),
153                     fingerprintStatusUtils.getSummary(),
154                     createPendingIntent(
155                             profileParentContext,
156                             biometricNavigationUtils
157                                     .getBiometricSettingsIntent(
158                                             context,
159                                             fingerprintStatusUtils.getSettingsClassName(),
160                                             disablingAdmin,
161                                             Bundle.EMPTY)
162                                     .setIdentifier(Integer.toString(userId)),
163                             REQUEST_CODE_FINGERPRINT_SETTING),
164                     disablingAdmin == null /* enabled */,
165                     fingerprintStatusUtils.hasEnrolled(),
166                     safetyEvent);
167         }
168     }
169 
170     /** Notifies Safety Center of a change in biometrics settings. */
onBiometricsChanged(Context context)171     public static void onBiometricsChanged(Context context) {
172         setSafetySourceData(
173                 context,
174                 new SafetyEvent.Builder(SafetyEvent.SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED)
175                         .build());
176     }
177 
setBiometricSafetySourceData( Context context, String title, String summary, PendingIntent pendingIntent, boolean enabled, boolean hasEnrolled, SafetyEvent safetyEvent)178     private static void setBiometricSafetySourceData(
179             Context context,
180             String title,
181             String summary,
182             PendingIntent pendingIntent,
183             boolean enabled,
184             boolean hasEnrolled,
185             SafetyEvent safetyEvent) {
186         final int severityLevel =
187                 enabled && hasEnrolled
188                         ? SafetySourceData.SEVERITY_LEVEL_INFORMATION
189                         : SafetySourceData.SEVERITY_LEVEL_UNSPECIFIED;
190 
191         final SafetySourceStatus status =
192                 new SafetySourceStatus.Builder(title, summary, severityLevel)
193                         .setPendingIntent(pendingIntent)
194                         .setEnabled(enabled)
195                         .build();
196         final SafetySourceData safetySourceData =
197                 new SafetySourceData.Builder().setStatus(status).build();
198 
199         SafetyCenterManagerWrapper.get()
200                 .setSafetySourceData(context, SAFETY_SOURCE_ID, safetySourceData, safetyEvent);
201     }
202 
createPendingIntent( Context context, Intent intent, int requestCode)203     private static PendingIntent createPendingIntent(
204             Context context, Intent intent, int requestCode) {
205         return PendingIntent.getActivity(
206                 context, requestCode, intent, PendingIntent.FLAG_IMMUTABLE);
207     }
208 }
209