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.UserHandle; 26 import android.safetycenter.SafetyEvent; 27 import android.safetycenter.SafetySourceData; 28 import android.safetycenter.SafetySourceStatus; 29 30 import com.android.settings.R; 31 import com.android.settings.Utils; 32 import com.android.settings.biometrics.BiometricNavigationUtils; 33 import com.android.settings.biometrics.combination.CombinedBiometricStatusUtils; 34 import com.android.settings.biometrics.face.FaceStatusUtils; 35 import com.android.settings.biometrics.fingerprint.FingerprintStatusUtils; 36 import com.android.settingslib.RestrictedLockUtils; 37 38 /** Combined Biometrics Safety Source for Safety Center. */ 39 public final class BiometricsSafetySource { 40 41 public static final String SAFETY_SOURCE_ID = "AndroidBiometrics"; 42 private static final int REQUEST_CODE_COMBINED_BIOMETRIC_SETTING = 10; 43 private static final int REQUEST_CODE_FACE_SETTING = 20; 44 private static final int REQUEST_CODE_FINGERPRINT_SETTING = 30; 45 BiometricsSafetySource()46 private BiometricsSafetySource() { 47 } 48 49 /** Sets biometric safety data for Safety Center. */ setSafetySourceData(Context context, SafetyEvent safetyEvent)50 public static void setSafetySourceData(Context context, SafetyEvent safetyEvent) { 51 if (!SafetyCenterManagerWrapper.get().isEnabled(context)) { 52 return; 53 } 54 55 final int userId = UserHandle.myUserId(); 56 57 final BiometricNavigationUtils biometricNavigationUtils = new BiometricNavigationUtils( 58 userId); 59 final CombinedBiometricStatusUtils combinedBiometricStatusUtils = 60 new CombinedBiometricStatusUtils(context, userId); 61 62 if (combinedBiometricStatusUtils.isAvailable()) { 63 final RestrictedLockUtils.EnforcedAdmin disablingAdmin = 64 combinedBiometricStatusUtils.getDisablingAdmin(); 65 setBiometricSafetySourceData(context, 66 context.getString(R.string.security_settings_biometric_preference_title), 67 combinedBiometricStatusUtils.getSummary(), 68 createPendingIntent(context, 69 biometricNavigationUtils.getBiometricSettingsIntent(context, 70 combinedBiometricStatusUtils.getSettingsClassName(), 71 disablingAdmin, Bundle.EMPTY), 72 REQUEST_CODE_COMBINED_BIOMETRIC_SETTING), 73 disablingAdmin == null /* enabled */, 74 combinedBiometricStatusUtils.hasEnrolled(), 75 safetyEvent); 76 return; 77 } 78 79 final FaceManager faceManager = Utils.getFaceManagerOrNull(context); 80 final FaceStatusUtils faceStatusUtils = new FaceStatusUtils(context, faceManager, userId); 81 82 if (faceStatusUtils.isAvailable()) { 83 final RestrictedLockUtils.EnforcedAdmin disablingAdmin = 84 faceStatusUtils.getDisablingAdmin(); 85 setBiometricSafetySourceData(context, 86 context.getString(R.string.security_settings_face_preference_title), 87 faceStatusUtils.getSummary(), 88 createPendingIntent(context, 89 biometricNavigationUtils.getBiometricSettingsIntent(context, 90 faceStatusUtils.getSettingsClassName(), disablingAdmin, 91 Bundle.EMPTY), 92 REQUEST_CODE_FACE_SETTING), 93 disablingAdmin == null /* enabled */, 94 faceStatusUtils.hasEnrolled(), 95 safetyEvent); 96 97 return; 98 } 99 100 final FingerprintManager fingerprintManager = Utils.getFingerprintManagerOrNull(context); 101 final FingerprintStatusUtils fingerprintStatusUtils = new FingerprintStatusUtils(context, 102 fingerprintManager, userId); 103 104 if (fingerprintStatusUtils.isAvailable()) { 105 final RestrictedLockUtils.EnforcedAdmin disablingAdmin = 106 fingerprintStatusUtils.getDisablingAdmin(); 107 setBiometricSafetySourceData(context, 108 context.getString(R.string.security_settings_fingerprint_preference_title), 109 fingerprintStatusUtils.getSummary(), 110 createPendingIntent(context, 111 biometricNavigationUtils.getBiometricSettingsIntent(context, 112 fingerprintStatusUtils.getSettingsClassName(), disablingAdmin, 113 Bundle.EMPTY), 114 REQUEST_CODE_FINGERPRINT_SETTING), 115 disablingAdmin == null /* enabled */, 116 fingerprintStatusUtils.hasEnrolled(), 117 safetyEvent); 118 } 119 } 120 121 /** Notifies Safety Center of a change in biometrics settings. */ onBiometricsChanged(Context context)122 public static void onBiometricsChanged(Context context) { 123 setSafetySourceData( 124 context, 125 new SafetyEvent.Builder(SafetyEvent.SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED).build() 126 ); 127 } 128 setBiometricSafetySourceData(Context context, String title, String summary, PendingIntent pendingIntent, boolean enabled, boolean hasEnrolled, SafetyEvent safetyEvent)129 private static void setBiometricSafetySourceData(Context context, String title, String summary, 130 PendingIntent pendingIntent, boolean enabled, boolean hasEnrolled, 131 SafetyEvent safetyEvent) { 132 final int severityLevel = 133 enabled && hasEnrolled ? SafetySourceData.SEVERITY_LEVEL_INFORMATION 134 : SafetySourceData.SEVERITY_LEVEL_UNSPECIFIED; 135 136 final SafetySourceStatus status = new SafetySourceStatus.Builder(title, summary, 137 severityLevel).setPendingIntent(pendingIntent).setEnabled(enabled).build(); 138 final SafetySourceData safetySourceData = 139 new SafetySourceData.Builder().setStatus(status).build(); 140 141 SafetyCenterManagerWrapper.get().setSafetySourceData( 142 context, SAFETY_SOURCE_ID, safetySourceData, safetyEvent); 143 } 144 createPendingIntent(Context context, Intent intent, int requestCode)145 private static PendingIntent createPendingIntent(Context context, Intent intent, 146 int requestCode) { 147 return PendingIntent 148 .getActivity( 149 context, 150 requestCode, 151 intent, 152 PendingIntent.FLAG_IMMUTABLE); 153 } 154 } 155