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