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_FINGERPRINT; 21 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING; 22 import static com.android.internal.util.Preconditions.checkNotNull; 23 24 import android.annotation.Nullable; 25 import android.app.ActivityManager; 26 import android.app.admin.DevicePolicyManager; 27 import android.content.Context; 28 import android.content.Intent; 29 import android.content.pm.PackageManager; 30 import android.hardware.fingerprint.FingerprintManager; 31 import android.os.Bundle; 32 import android.os.IBinder; 33 import android.os.UserManager; 34 35 import com.android.internal.annotations.VisibleForTesting; 36 import com.android.internal.widget.LockPatternUtils; 37 import com.android.settings.ChooseLockGeneric; 38 import com.android.settings.ChooseLockSettingsHelper; 39 import com.android.settings.Utils; 40 41 /** 42 * Business logic for {@link SetNewPasswordActivity}. 43 * 44 * <p>On devices that supports fingerprint, this controller directs the user to configure 45 * fingerprint + a backup password if the device admin allows fingerprint for keyguard and 46 * the user has never configured a fingerprint before. 47 */ 48 final class SetNewPasswordController { 49 50 interface Ui { 51 /** Starts the {@link ChooseLockGeneric} activity with the given extras. */ launchChooseLock(Bundle chooseLockFingerprintExtras)52 void launchChooseLock(Bundle chooseLockFingerprintExtras); 53 } 54 55 /** 56 * Which user is setting new password. 57 */ 58 private final int mTargetUserId; 59 private final PackageManager mPackageManager; 60 @Nullable private final IFingerprintManager mFingerprintManager; 61 private final DevicePolicyManager mDevicePolicyManager; 62 private final Ui mUi; 63 create(Context context, Ui ui, Intent intent, IBinder activityToken)64 public static SetNewPasswordController create(Context context, Ui ui, Intent intent, 65 IBinder activityToken) { 66 // Trying to figure out which user is setting new password. If it is 67 // ACTION_SET_NEW_PARENT_PROFILE_PASSWORD or the calling user is not allowed to set 68 // separate profile challenge, it is the current user to set new password. Otherwise, 69 // it is the user who starts this activity setting new password. 70 int userId = ActivityManager.getCurrentUser(); 71 if (ACTION_SET_NEW_PASSWORD.equals(intent.getAction())) { 72 final int callingUserId = Utils.getSecureTargetUser(activityToken, 73 UserManager.get(context), null, intent.getExtras()).getIdentifier(); 74 final LockPatternUtils lockPatternUtils = new LockPatternUtils(context); 75 if (lockPatternUtils.isSeparateProfileChallengeAllowed(callingUserId)) { 76 userId = callingUserId; 77 } 78 } 79 // Create a wrapper of FingerprintManager for testing, see IFingerPrintManager for details. 80 final FingerprintManager fingerprintManager = Utils.getFingerprintManagerOrNull(context); 81 final IFingerprintManager fingerprintManagerWrapper = 82 fingerprintManager == null 83 ? null 84 : new FingerprintManagerWrapper(fingerprintManager); 85 return new SetNewPasswordController(userId, 86 context.getPackageManager(), 87 fingerprintManagerWrapper, 88 (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE), ui); 89 } 90 91 @VisibleForTesting SetNewPasswordController( int targetUserId, PackageManager packageManager, IFingerprintManager fingerprintManager, DevicePolicyManager devicePolicyManager, Ui ui)92 SetNewPasswordController( 93 int targetUserId, 94 PackageManager packageManager, 95 IFingerprintManager fingerprintManager, 96 DevicePolicyManager devicePolicyManager, 97 Ui ui) { 98 mTargetUserId = targetUserId; 99 mPackageManager = checkNotNull(packageManager); 100 mFingerprintManager = fingerprintManager; 101 mDevicePolicyManager = checkNotNull(devicePolicyManager); 102 mUi = checkNotNull(ui); 103 } 104 105 /** 106 * Dispatches the set new password intent to the correct activity that handles it. 107 */ dispatchSetNewPasswordIntent()108 public void dispatchSetNewPasswordIntent() { 109 final Bundle extras; 110 if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT) 111 && mFingerprintManager != null 112 && mFingerprintManager.isHardwareDetected() 113 && !mFingerprintManager.hasEnrolledFingerprints(mTargetUserId) 114 && !isFingerprintDisabledByAdmin()) { 115 extras = getFingerprintChooseLockExtras(); 116 } else { 117 extras = new Bundle(); 118 } 119 // No matter we show fingerprint options or not, we should tell the next activity which 120 // user is setting new password. 121 extras.putInt(Intent.EXTRA_USER_ID, mTargetUserId); 122 mUi.launchChooseLock(extras); 123 } 124 getFingerprintChooseLockExtras()125 private Bundle getFingerprintChooseLockExtras() { 126 Bundle chooseLockExtras = new Bundle(); 127 long challenge = mFingerprintManager.preEnroll(); 128 chooseLockExtras.putInt(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY, 129 PASSWORD_QUALITY_SOMETHING); 130 chooseLockExtras.putBoolean( 131 ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true); 132 chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true); 133 chooseLockExtras.putLong(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge); 134 chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, true); 135 return chooseLockExtras; 136 } 137 isFingerprintDisabledByAdmin()138 private boolean isFingerprintDisabledByAdmin() { 139 int disabledFeatures = 140 mDevicePolicyManager.getKeyguardDisabledFeatures(null, mTargetUserId); 141 return (disabledFeatures & KEYGUARD_DISABLE_FINGERPRINT) != 0; 142 } 143 } 144