• 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 static com.android.settings.safetycenter.BiometricSourcesUtils.REQUEST_CODE_COMBINED_BIOMETRIC_SETTING;
20 import static com.android.settings.safetycenter.BiometricSourcesUtils.REQUEST_CODE_FACE_SETTING;
21 import static com.android.settings.safetycenter.BiometricSourcesUtils.REQUEST_CODE_FINGERPRINT_SETTING;
22 
23 import android.content.Context;
24 import android.hardware.face.FaceManager;
25 import android.hardware.fingerprint.FingerprintManager;
26 import android.os.Bundle;
27 import android.os.Process;
28 import android.os.UserHandle;
29 import android.os.UserManager;
30 import android.safetycenter.SafetyEvent;
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.settings.flags.Flags;
39 import com.android.settingslib.RestrictedLockUtils;
40 
41 /** Combined Biometrics Safety Source for Safety Center. */
42 public final class BiometricsSafetySource {
43 
44     public static final String SAFETY_SOURCE_ID = "AndroidBiometrics";
45 
BiometricsSafetySource()46     private BiometricsSafetySource() {}
47 
48     /** Sets biometric safety data for Safety Center. */
setSafetySourceData(Context context, SafetyEvent safetyEvent)49     public static void setSafetySourceData(Context context, SafetyEvent safetyEvent) {
50         if (!SafetyCenterManagerWrapper.get().isEnabled(context)) {
51             return;
52         }
53         if (Flags.biometricsOnboardingEducation()) { // this source is effectively turned off
54             sendNullData(context, safetyEvent);
55             return;
56         }
57 
58         UserHandle userHandle = Process.myUserHandle();
59         int userId = userHandle.getIdentifier();
60         UserManager userManager = UserManager.get(context);
61         UserHandle profileParentUserHandle = userManager.getProfileParent(userHandle);
62         if (profileParentUserHandle == null) {
63             profileParentUserHandle = userHandle;
64         }
65         Context profileParentContext = context.createContextAsUser(profileParentUserHandle, 0);
66         if (android.os.Flags.allowPrivateProfile()
67                 && android.multiuser.Flags.enablePrivateSpaceFeatures()
68                 && userManager.isPrivateProfile()) {
69             // SC always expects a response from the source if the broadcast has been sent for this
70             // source, therefore, we need to send a null SafetySourceData.
71             sendNullData(context, safetyEvent);
72             return;
73         }
74 
75         BiometricNavigationUtils biometricNavigationUtils = new BiometricNavigationUtils(userId);
76         CombinedBiometricStatusUtils combinedBiometricStatusUtils =
77                 new CombinedBiometricStatusUtils(context, userId);
78         ActiveUnlockStatusUtils activeUnlockStatusUtils = new ActiveUnlockStatusUtils(context);
79         if (!userManager.isProfile() && activeUnlockStatusUtils.isAvailable()) {
80             RestrictedLockUtils.EnforcedAdmin disablingAdmin =
81                     combinedBiometricStatusUtils.getDisablingAdmin();
82             BiometricSourcesUtils.setBiometricSafetySourceData(
83                     SAFETY_SOURCE_ID,
84                     context,
85                     activeUnlockStatusUtils.getTitleForActiveUnlock(),
86                     combinedBiometricStatusUtils.getSummary(),
87                     BiometricSourcesUtils.createPendingIntent(
88                             context,
89                             biometricNavigationUtils.getBiometricSettingsIntent(
90                                     context,
91                                     combinedBiometricStatusUtils.getSettingsClassName(),
92                                     disablingAdmin,
93                                     Bundle.EMPTY),
94                             REQUEST_CODE_COMBINED_BIOMETRIC_SETTING),
95                     disablingAdmin == null /* enabled */,
96                     combinedBiometricStatusUtils.hasEnrolled(),
97                     safetyEvent);
98             return;
99         }
100         if (combinedBiometricStatusUtils.isAvailable()) {
101             RestrictedLockUtils.EnforcedAdmin disablingAdmin =
102                     combinedBiometricStatusUtils.getDisablingAdmin();
103             BiometricSourcesUtils.setBiometricSafetySourceData(
104                     SAFETY_SOURCE_ID,
105                     context,
106                     combinedBiometricStatusUtils.getTitle(),
107                     combinedBiometricStatusUtils.getSummary(),
108                     BiometricSourcesUtils.createPendingIntent(
109                             profileParentContext,
110                             biometricNavigationUtils
111                                     .getBiometricSettingsIntent(
112                                             context,
113                                             combinedBiometricStatusUtils
114                                                     .getSettingsClassNameBasedOnUser(),
115                                             disablingAdmin,
116                                             Bundle.EMPTY)
117                                     .setIdentifier(Integer.toString(userId)),
118                             REQUEST_CODE_COMBINED_BIOMETRIC_SETTING),
119                     disablingAdmin == null /* enabled */,
120                     combinedBiometricStatusUtils.hasEnrolled(),
121                     safetyEvent);
122             return;
123         }
124 
125         FaceManager faceManager = Utils.getFaceManagerOrNull(context);
126         FaceStatusUtils faceStatusUtils = new FaceStatusUtils(context, faceManager, userId);
127 
128         if (faceStatusUtils.isAvailable()) {
129             RestrictedLockUtils.EnforcedAdmin disablingAdmin = faceStatusUtils.getDisablingAdmin();
130             BiometricSourcesUtils.setBiometricSafetySourceData(
131                     SAFETY_SOURCE_ID,
132                     context,
133                     faceStatusUtils.getTitle(),
134                     faceStatusUtils.getSummary(),
135                     BiometricSourcesUtils.createPendingIntent(
136                             profileParentContext,
137                             biometricNavigationUtils
138                                     .getBiometricSettingsIntent(
139                                             context,
140                                             faceStatusUtils.getSettingsClassName(),
141                                             disablingAdmin,
142                                             Bundle.EMPTY)
143                                     .setIdentifier(Integer.toString(userId)),
144                             REQUEST_CODE_FACE_SETTING),
145                     disablingAdmin == null /* enabled */,
146                     faceStatusUtils.hasEnrolled(),
147                     safetyEvent);
148 
149             return;
150         }
151 
152         FingerprintManager fingerprintManager = Utils.getFingerprintManagerOrNull(context);
153         FingerprintStatusUtils fingerprintStatusUtils =
154                 new FingerprintStatusUtils(context, fingerprintManager, userId);
155 
156         if (fingerprintStatusUtils.isAvailable()) {
157             RestrictedLockUtils.EnforcedAdmin disablingAdmin =
158                     fingerprintStatusUtils.getDisablingAdmin();
159             BiometricSourcesUtils.setBiometricSafetySourceData(
160                     SAFETY_SOURCE_ID,
161                     context,
162                     fingerprintStatusUtils.getTitle(),
163                     fingerprintStatusUtils.getSummary(),
164                     BiometricSourcesUtils.createPendingIntent(
165                             profileParentContext,
166                             biometricNavigationUtils
167                                     .getBiometricSettingsIntent(
168                                             context,
169                                             fingerprintStatusUtils.getSettingsClassName(),
170                                             disablingAdmin,
171                                             Bundle.EMPTY)
172                                     .setIdentifier(Integer.toString(userId)),
173                             REQUEST_CODE_FINGERPRINT_SETTING),
174                     disablingAdmin == null /* enabled */,
175                     fingerprintStatusUtils.hasEnrolled(),
176                     safetyEvent);
177             return;
178         }
179 
180         sendNullData(context, safetyEvent);
181     }
182 
sendNullData(Context context, SafetyEvent safetyEvent)183     private static void sendNullData(Context context, SafetyEvent safetyEvent) {
184         SafetyCenterManagerWrapper.get()
185                 .setSafetySourceData(
186                         context, SAFETY_SOURCE_ID, /* safetySourceData= */ null, safetyEvent);
187     }
188 
189     /** Notifies Safety Center of a change in biometrics settings. */
onBiometricsChanged(Context context)190     public static void onBiometricsChanged(Context context) {
191         setSafetySourceData(
192                 context,
193                 new SafetyEvent.Builder(SafetyEvent.SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED)
194                         .build());
195     }
196 }
197