1 /* 2 * Copyright (C) 2016 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.password; 18 19 import static android.app.admin.DevicePolicyManager.ACTION_SET_NEW_PASSWORD; 20 import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FACE; 21 import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT; 22 23 import static com.android.internal.util.Preconditions.checkNotNull; 24 import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FINGERPRINT_ENROLLMENT_ONLY; 25 26 import android.app.ActivityManager; 27 import android.app.admin.DevicePolicyManager; 28 import android.content.Context; 29 import android.content.Intent; 30 import android.content.pm.PackageManager; 31 import android.hardware.face.FaceManager; 32 import android.hardware.fingerprint.FingerprintManager; 33 import android.os.Bundle; 34 import android.os.IBinder; 35 import android.os.UserManager; 36 37 import androidx.annotation.Nullable; 38 import androidx.annotation.VisibleForTesting; 39 40 import com.android.settings.Utils; 41 42 /** 43 * Business logic for {@link SetNewPasswordActivity}. 44 * 45 * <p>On devices that supports fingerprint, this controller directs the user to configure 46 * fingerprint + a backup password if the device admin allows fingerprint for keyguard and 47 * the user has never configured a fingerprint before. 48 */ 49 final class SetNewPasswordController { 50 51 interface Ui { 52 /** Starts the {@link ChooseLockGeneric} activity with the given extras. */ launchChooseLock(Bundle chooseLockFingerprintExtras)53 void launchChooseLock(Bundle chooseLockFingerprintExtras); 54 } 55 56 /** 57 * Which user is setting new password. 58 */ 59 private final int mTargetUserId; 60 private final PackageManager mPackageManager; 61 @Nullable 62 private final FingerprintManager mFingerprintManager; 63 @Nullable 64 private final FaceManager mFaceManager; 65 private final DevicePolicyManager mDevicePolicyManager; 66 private final Ui mUi; 67 create(Context context, Ui ui, Intent intent, IBinder activityToken)68 public static SetNewPasswordController create(Context context, Ui ui, Intent intent, 69 IBinder activityToken) { 70 // Trying to figure out which user is setting new password. If it is 71 // ACTION_SET_NEW_PARENT_PROFILE_PASSWORD, it is the current user to set 72 // new password. Otherwise, it is the user who starts this activity 73 // setting new password. 74 final int userId; 75 if (ACTION_SET_NEW_PASSWORD.equals(intent.getAction())) { 76 userId = Utils.getSecureTargetUser(activityToken, 77 UserManager.get(context), null, intent.getExtras()).getIdentifier(); 78 } else { 79 userId = ActivityManager.getCurrentUser(); 80 } 81 // Create a wrapper of FingerprintManager for testing, see IFingerPrintManager for details. 82 final FingerprintManager fingerprintManager = Utils.getFingerprintManagerOrNull(context); 83 final FaceManager faceManager = 84 !intent.getBooleanExtra(EXTRA_KEY_FINGERPRINT_ENROLLMENT_ONLY, false) 85 ? Utils.getFaceManagerOrNull(context) 86 : null; 87 return new SetNewPasswordController(userId, 88 context.getPackageManager(), 89 fingerprintManager, faceManager, 90 (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE), ui); 91 } 92 93 @VisibleForTesting SetNewPasswordController( int targetUserId, PackageManager packageManager, FingerprintManager fingerprintManager, FaceManager faceManager, DevicePolicyManager devicePolicyManager, Ui ui)94 SetNewPasswordController( 95 int targetUserId, 96 PackageManager packageManager, 97 FingerprintManager fingerprintManager, 98 FaceManager faceManager, 99 DevicePolicyManager devicePolicyManager, 100 Ui ui) { 101 mTargetUserId = targetUserId; 102 mPackageManager = checkNotNull(packageManager); 103 mFingerprintManager = fingerprintManager; 104 mFaceManager = faceManager; 105 mDevicePolicyManager = checkNotNull(devicePolicyManager); 106 mUi = checkNotNull(ui); 107 } 108 109 /** 110 * Dispatches the set new password intent to the correct activity that handles it. 111 */ dispatchSetNewPasswordIntent()112 public void dispatchSetNewPasswordIntent() { 113 final Bundle extras; 114 115 final boolean hasFeatureFingerprint = mPackageManager 116 .hasSystemFeature(PackageManager.FEATURE_FINGERPRINT); 117 final boolean hasFeatureFace = mPackageManager 118 .hasSystemFeature(PackageManager.FEATURE_FACE); 119 120 final boolean shouldShowFingerprintEnroll = mFingerprintManager != null 121 && mFingerprintManager.isHardwareDetected() 122 && !mFingerprintManager.hasEnrolledFingerprints(mTargetUserId) 123 && !isFingerprintDisabledByAdmin(); 124 final boolean shouldShowFaceEnroll = mFaceManager != null 125 && mFaceManager.isHardwareDetected() 126 && !mFaceManager.hasEnrolledTemplates(mTargetUserId) 127 && !isFaceDisabledByAdmin(); 128 129 if (hasFeatureFace && shouldShowFaceEnroll 130 && hasFeatureFingerprint && shouldShowFingerprintEnroll) { 131 extras = getBiometricChooseLockExtras(); 132 } else if (hasFeatureFace && shouldShowFaceEnroll) { 133 extras = getFaceChooseLockExtras(); 134 } else if (hasFeatureFingerprint && shouldShowFingerprintEnroll) { 135 extras = getFingerprintChooseLockExtras(); 136 } else { 137 extras = new Bundle(); 138 } 139 140 // No matter we show fingerprint options or not, we should tell the next activity which 141 // user is setting new password. 142 extras.putInt(Intent.EXTRA_USER_ID, mTargetUserId); 143 mUi.launchChooseLock(extras); 144 } 145 getBiometricChooseLockExtras()146 private Bundle getBiometricChooseLockExtras() { 147 Bundle chooseLockExtras = new Bundle(); 148 chooseLockExtras.putBoolean( 149 ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS, true); 150 chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true); 151 chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS, true); 152 return chooseLockExtras; 153 } 154 getFingerprintChooseLockExtras()155 private Bundle getFingerprintChooseLockExtras() { 156 Bundle chooseLockExtras = new Bundle(); 157 chooseLockExtras.putBoolean( 158 ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS, true); 159 chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true); 160 chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, true); 161 return chooseLockExtras; 162 } 163 getFaceChooseLockExtras()164 private Bundle getFaceChooseLockExtras() { 165 Bundle chooseLockExtras = new Bundle(); 166 chooseLockExtras.putBoolean( 167 ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS, true); 168 chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true); 169 chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE, true); 170 return chooseLockExtras; 171 } 172 isFingerprintDisabledByAdmin()173 private boolean isFingerprintDisabledByAdmin() { 174 int disabledFeatures = 175 mDevicePolicyManager.getKeyguardDisabledFeatures(null, mTargetUserId); 176 return (disabledFeatures & KEYGUARD_DISABLE_FINGERPRINT) != 0; 177 } 178 isFaceDisabledByAdmin()179 private boolean isFaceDisabledByAdmin() { 180 int disabledFeatures = 181 mDevicePolicyManager.getKeyguardDisabledFeatures(null, mTargetUserId); 182 return (disabledFeatures & KEYGUARD_DISABLE_FACE) != 0; 183 } 184 } 185