2 * Copyright (C) 2016 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.settings.password;
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;
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;
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;
42 * Business logic for {@link SetNewPasswordActivity}.
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.
48 final class SetNewPasswordController {
51 /** Starts the {@link ChooseLockGeneric} activity with the given extras. */
52 void launchChooseLock(Bundle chooseLockFingerprintExtras);
56 * Which user is setting new password.
58 private final int mTargetUserId;
59 private final PackageManager mPackageManager;
60 @Nullable private final IFingerprintManager mFingerprintManager;
61 private final DevicePolicyManager mDevicePolicyManager;
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;
79 // Create a wrapper of FingerprintManager for testing, see IFingerPrintManager for details.
80 final FingerprintManager fingerprintManager =
81 (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
82 final IFingerprintManager fingerprintManagerWrapper =
83 fingerprintManager == null
85 : new FingerprintManagerWrapper(fingerprintManager);
86 return new SetNewPasswordController(userId,
87 context.getPackageManager(),
88 fingerprintManagerWrapper,
89 (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE), ui);
93 SetNewPasswordController(
95 PackageManager packageManager,
96 IFingerprintManager fingerprintManager,
97 DevicePolicyManager devicePolicyManager,
99 mTargetUserId = targetUserId;
100 mPackageManager = checkNotNull(packageManager);
101 mFingerprintManager = fingerprintManager;
102 mDevicePolicyManager = checkNotNull(devicePolicyManager);
103 mUi = checkNotNull(ui);
107 * Dispatches the set new password intent to the correct activity that handles it.
109 public void dispatchSetNewPasswordIntent() {
111 if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)
112 && mFingerprintManager != null
113 && mFingerprintManager.isHardwareDetected()
114 && !mFingerprintManager.hasEnrolledFingerprints(mTargetUserId)
115 && !isFingerprintDisabledByAdmin()) {
116 extras = getFingerprintChooseLockExtras();
118 extras = new Bundle();
120 // No matter we show fingerprint options or not, we should tell the next activity which
121 // user is setting new password.
122 extras.putInt(Intent.EXTRA_USER_ID, mTargetUserId);
123 mUi.launchChooseLock(extras);
126 private Bundle getFingerprintChooseLockExtras() {
127 Bundle chooseLockExtras = new Bundle();
128 long challenge = mFingerprintManager.preEnroll();
129 chooseLockExtras.putInt(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
130 PASSWORD_QUALITY_SOMETHING);
131 chooseLockExtras.putBoolean(
132 ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true);
133 chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true);
134 chooseLockExtras.putLong(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge);
135 chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, true);
136 return chooseLockExtras;
139 private boolean isFingerprintDisabledByAdmin() {
140 int disabledFeatures =
141 mDevicePolicyManager.getKeyguardDisabledFeatures(null, mTargetUserId);
142 return (disabledFeatures & KEYGUARD_DISABLE_FINGERPRINT) != 0;