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 25 import android.annotation.Nullable; 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.VisibleForTesting; 38 39 import com.android.internal.widget.LockPatternUtils; 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 or the calling user is not allowed to set 72 // separate profile challenge, it is the current user to set new password. Otherwise, 73 // it is the user who starts this activity setting new password. 74 int userId = ActivityManager.getCurrentUser(); 75 if (ACTION_SET_NEW_PASSWORD.equals(intent.getAction())) { 76 final int callingUserId = Utils.getSecureTargetUser(activityToken, 77 UserManager.get(context), null, intent.getExtras()).getIdentifier(); 78 final LockPatternUtils lockPatternUtils = new LockPatternUtils(context); 79 if (lockPatternUtils.isSeparateProfileChallengeAllowed(callingUserId)) { 80 userId = callingUserId; 81 } 82 } 83 // Create a wrapper of FingerprintManager for testing, see IFingerPrintManager for details. 84 final FingerprintManager fingerprintManager = Utils.getFingerprintManagerOrNull(context); 85 final FaceManager faceManager = Utils.getFaceManagerOrNull(context); 86 return new SetNewPasswordController(userId, 87 context.getPackageManager(), 88 fingerprintManager, faceManager, 89 (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE), ui); 90 } 91 92 @VisibleForTesting SetNewPasswordController( int targetUserId, PackageManager packageManager, FingerprintManager fingerprintManager, FaceManager faceManager, DevicePolicyManager devicePolicyManager, Ui ui)93 SetNewPasswordController( 94 int targetUserId, 95 PackageManager packageManager, 96 FingerprintManager fingerprintManager, 97 FaceManager faceManager, 98 DevicePolicyManager devicePolicyManager, 99 Ui ui) { 100 mTargetUserId = targetUserId; 101 mPackageManager = checkNotNull(packageManager); 102 mFingerprintManager = fingerprintManager; 103 mFaceManager = faceManager; 104 mDevicePolicyManager = checkNotNull(devicePolicyManager); 105 mUi = checkNotNull(ui); 106 } 107 108 /** 109 * Dispatches the set new password intent to the correct activity that handles it. 110 */ dispatchSetNewPasswordIntent()111 public void dispatchSetNewPasswordIntent() { 112 final Bundle extras; 113 114 final boolean hasFeatureFingerprint = mPackageManager 115 .hasSystemFeature(PackageManager.FEATURE_FINGERPRINT); 116 final boolean hasFeatureFace = mPackageManager 117 .hasSystemFeature(PackageManager.FEATURE_FACE); 118 119 final boolean shouldShowFingerprintEnroll = mFingerprintManager != null 120 && mFingerprintManager.isHardwareDetected() 121 && !mFingerprintManager.hasEnrolledFingerprints(mTargetUserId) 122 && !isFingerprintDisabledByAdmin(); 123 final boolean shouldShowFaceEnroll = mFaceManager != null 124 && mFaceManager.isHardwareDetected() 125 && !mFaceManager.hasEnrolledTemplates(mTargetUserId) 126 && !isFaceDisabledByAdmin(); 127 128 if (hasFeatureFace && shouldShowFaceEnroll 129 && hasFeatureFingerprint && shouldShowFingerprintEnroll) { 130 extras = getBiometricChooseLockExtras(); 131 } else if (hasFeatureFace && shouldShowFaceEnroll) { 132 extras = getFaceChooseLockExtras(); 133 } else if (hasFeatureFingerprint && shouldShowFingerprintEnroll) { 134 extras = getFingerprintChooseLockExtras(); 135 } else { 136 extras = new Bundle(); 137 } 138 139 // No matter we show fingerprint options or not, we should tell the next activity which 140 // user is setting new password. 141 extras.putInt(Intent.EXTRA_USER_ID, mTargetUserId); 142 mUi.launchChooseLock(extras); 143 } 144 getBiometricChooseLockExtras()145 private Bundle getBiometricChooseLockExtras() { 146 Bundle chooseLockExtras = new Bundle(); 147 chooseLockExtras.putBoolean( 148 ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS, true); 149 chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true); 150 chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS, true); 151 return chooseLockExtras; 152 } 153 getFingerprintChooseLockExtras()154 private Bundle getFingerprintChooseLockExtras() { 155 Bundle chooseLockExtras = new Bundle(); 156 chooseLockExtras.putBoolean( 157 ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS, true); 158 chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true); 159 chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, true); 160 return chooseLockExtras; 161 } 162 getFaceChooseLockExtras()163 private Bundle getFaceChooseLockExtras() { 164 Bundle chooseLockExtras = new Bundle(); 165 chooseLockExtras.putBoolean( 166 ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS, true); 167 chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true); 168 chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE, true); 169 return chooseLockExtras; 170 } 171 isFingerprintDisabledByAdmin()172 private boolean isFingerprintDisabledByAdmin() { 173 int disabledFeatures = 174 mDevicePolicyManager.getKeyguardDisabledFeatures(null, mTargetUserId); 175 return (disabledFeatures & KEYGUARD_DISABLE_FINGERPRINT) != 0; 176 } 177 isFaceDisabledByAdmin()178 private boolean isFaceDisabledByAdmin() { 179 int disabledFeatures = 180 mDevicePolicyManager.getKeyguardDisabledFeatures(null, mTargetUserId); 181 return (disabledFeatures & KEYGUARD_DISABLE_FACE) != 0; 182 } 183 } 184