blob: bf552718b1409cb2fa087f3daf2e240457c03362 [file] [log] [blame]
Steven Ng4fdcec72016-09-26 22:13:08 +01001/*
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
17package com.android.settings.password;
18
Tony Mak8f41b9b2016-11-23 11:36:18 +000019import static android.app.admin.DevicePolicyManager.ACTION_SET_NEW_PASSWORD;
Kevin Chyn81dc0292018-06-28 14:59:38 -070020import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FACE;
Tony Mak8f41b9b2016-11-23 11:36:18 +000021import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT;
22import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
Fan Zhang23f8d592018-08-28 15:11:40 -070023
Steven Ng4fdcec72016-09-26 22:13:08 +010024import static com.android.internal.util.Preconditions.checkNotNull;
25
26import android.annotation.Nullable;
Tony Mak8f41b9b2016-11-23 11:36:18 +000027import android.app.ActivityManager;
Steven Ng4fdcec72016-09-26 22:13:08 +010028import android.app.admin.DevicePolicyManager;
29import android.content.Context;
30import android.content.Intent;
31import android.content.pm.PackageManager;
Kevin Chyn81dc0292018-06-28 14:59:38 -070032import android.hardware.face.FaceManager;
Steven Ng4fdcec72016-09-26 22:13:08 +010033import android.hardware.fingerprint.FingerprintManager;
34import android.os.Bundle;
Tony Make0405fc2016-12-14 02:57:14 +000035import android.os.IBinder;
Tony Mak8f41b9b2016-11-23 11:36:18 +000036import android.os.UserManager;
Steven Ng4fdcec72016-09-26 22:13:08 +010037
Fan Zhang23f8d592018-08-28 15:11:40 -070038import androidx.annotation.VisibleForTesting;
39
Tony Mak8f41b9b2016-11-23 11:36:18 +000040import com.android.internal.widget.LockPatternUtils;
Jeff Sharkeyab508072016-10-11 14:25:22 -060041import com.android.settings.Utils;
Steven Ng4fdcec72016-09-26 22:13:08 +010042
43/**
44 * Business logic for {@link SetNewPasswordActivity}.
45 *
46 * <p>On devices that supports fingerprint, this controller directs the user to configure
47 * fingerprint + a backup password if the device admin allows fingerprint for keyguard and
48 * the user has never configured a fingerprint before.
49 */
50final class SetNewPasswordController {
51
52 interface Ui {
53 /** Starts the {@link ChooseLockGeneric} activity with the given extras. */
Tony Mak8f41b9b2016-11-23 11:36:18 +000054 void launchChooseLock(Bundle chooseLockFingerprintExtras);
Steven Ng4fdcec72016-09-26 22:13:08 +010055 }
56
Tony Mak8f41b9b2016-11-23 11:36:18 +000057 /**
58 * Which user is setting new password.
59 */
60 private final int mTargetUserId;
Steven Ng4fdcec72016-09-26 22:13:08 +010061 private final PackageManager mPackageManager;
Fan Zhang1b9b1a22018-03-30 16:30:31 -070062 @Nullable
63 private final FingerprintManager mFingerprintManager;
Kevin Chyn81dc0292018-06-28 14:59:38 -070064 @Nullable
65 private final FaceManager mFaceManager;
Steven Ng4fdcec72016-09-26 22:13:08 +010066 private final DevicePolicyManager mDevicePolicyManager;
67 private final Ui mUi;
68
Tony Make0405fc2016-12-14 02:57:14 +000069 public static SetNewPasswordController create(Context context, Ui ui, Intent intent,
70 IBinder activityToken) {
Tony Mak8f41b9b2016-11-23 11:36:18 +000071 // Trying to figure out which user is setting new password. If it is
72 // ACTION_SET_NEW_PARENT_PROFILE_PASSWORD or the calling user is not allowed to set
73 // separate profile challenge, it is the current user to set new password. Otherwise,
74 // it is the user who starts this activity setting new password.
75 int userId = ActivityManager.getCurrentUser();
76 if (ACTION_SET_NEW_PASSWORD.equals(intent.getAction())) {
Tony Make0405fc2016-12-14 02:57:14 +000077 final int callingUserId = Utils.getSecureTargetUser(activityToken,
Tony Mak8f41b9b2016-11-23 11:36:18 +000078 UserManager.get(context), null, intent.getExtras()).getIdentifier();
79 final LockPatternUtils lockPatternUtils = new LockPatternUtils(context);
80 if (lockPatternUtils.isSeparateProfileChallengeAllowed(callingUserId)) {
81 userId = callingUserId;
82 }
83 }
84 // Create a wrapper of FingerprintManager for testing, see IFingerPrintManager for details.
85 final FingerprintManager fingerprintManager = Utils.getFingerprintManagerOrNull(context);
Kevin Chyn81dc0292018-06-28 14:59:38 -070086 final FaceManager faceManager = Utils.getFaceManagerOrNull(context);
Tony Mak8f41b9b2016-11-23 11:36:18 +000087 return new SetNewPasswordController(userId,
Steven Ng4fdcec72016-09-26 22:13:08 +010088 context.getPackageManager(),
Kevin Chyn81dc0292018-06-28 14:59:38 -070089 fingerprintManager, faceManager,
Tony Mak8f41b9b2016-11-23 11:36:18 +000090 (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE), ui);
Steven Ng4fdcec72016-09-26 22:13:08 +010091 }
92
93 @VisibleForTesting
94 SetNewPasswordController(
Tony Mak8f41b9b2016-11-23 11:36:18 +000095 int targetUserId,
Steven Ng4fdcec72016-09-26 22:13:08 +010096 PackageManager packageManager,
Fan Zhang1b9b1a22018-03-30 16:30:31 -070097 FingerprintManager fingerprintManager,
Kevin Chyn81dc0292018-06-28 14:59:38 -070098 FaceManager faceManager,
Steven Ng4fdcec72016-09-26 22:13:08 +010099 DevicePolicyManager devicePolicyManager,
100 Ui ui) {
Tony Mak8f41b9b2016-11-23 11:36:18 +0000101 mTargetUserId = targetUserId;
Steven Ng4fdcec72016-09-26 22:13:08 +0100102 mPackageManager = checkNotNull(packageManager);
103 mFingerprintManager = fingerprintManager;
Kevin Chyn81dc0292018-06-28 14:59:38 -0700104 mFaceManager = faceManager;
Steven Ng4fdcec72016-09-26 22:13:08 +0100105 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 */
112 public void dispatchSetNewPasswordIntent() {
Tony Mak8f41b9b2016-11-23 11:36:18 +0000113 final Bundle extras;
Kevin Chyn81dc0292018-06-28 14:59:38 -0700114 // TODO: handle the case with multiple biometrics, perhaps take an arg for biometric type?
115 if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)
116 && mFaceManager != null
117 && mFaceManager.isHardwareDetected()
Kevin Chyn76d40d32018-08-26 15:43:00 -0700118 && !mFaceManager.hasEnrolledTemplates(mTargetUserId)
Kevin Chyn81dc0292018-06-28 14:59:38 -0700119 && !isFaceDisabledByAdmin()) {
120 extras = getFaceChooseLockExtras();
121 } else if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)
Steven Ng4fdcec72016-09-26 22:13:08 +0100122 && mFingerprintManager != null
123 && mFingerprintManager.isHardwareDetected()
Tony Mak8f41b9b2016-11-23 11:36:18 +0000124 && !mFingerprintManager.hasEnrolledFingerprints(mTargetUserId)
Steven Ng4fdcec72016-09-26 22:13:08 +0100125 && !isFingerprintDisabledByAdmin()) {
Tony Mak8f41b9b2016-11-23 11:36:18 +0000126 extras = getFingerprintChooseLockExtras();
Steven Ng4fdcec72016-09-26 22:13:08 +0100127 } else {
Tony Mak8f41b9b2016-11-23 11:36:18 +0000128 extras = new Bundle();
Steven Ng4fdcec72016-09-26 22:13:08 +0100129 }
Tony Mak8f41b9b2016-11-23 11:36:18 +0000130 // No matter we show fingerprint options or not, we should tell the next activity which
131 // user is setting new password.
132 extras.putInt(Intent.EXTRA_USER_ID, mTargetUserId);
133 mUi.launchChooseLock(extras);
Steven Ng4fdcec72016-09-26 22:13:08 +0100134 }
135
136 private Bundle getFingerprintChooseLockExtras() {
137 Bundle chooseLockExtras = new Bundle();
Tony Mak8f41b9b2016-11-23 11:36:18 +0000138 long challenge = mFingerprintManager.preEnroll();
139 chooseLockExtras.putInt(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
140 PASSWORD_QUALITY_SOMETHING);
141 chooseLockExtras.putBoolean(
142 ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true);
143 chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true);
144 chooseLockExtras.putLong(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge);
145 chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, true);
Steven Ng4fdcec72016-09-26 22:13:08 +0100146 return chooseLockExtras;
147 }
148
Kevin Chyn81dc0292018-06-28 14:59:38 -0700149 private Bundle getFaceChooseLockExtras() {
150 Bundle chooseLockExtras = new Bundle();
Kevin Chyna8843f292018-09-25 12:08:21 -0700151 long challenge = mFaceManager.generateChallenge();
Kevin Chyn81dc0292018-06-28 14:59:38 -0700152 chooseLockExtras.putInt(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
153 PASSWORD_QUALITY_SOMETHING);
154 chooseLockExtras.putBoolean(
155 ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true);
156 chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true);
157 chooseLockExtras.putLong(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge);
158 chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE, true);
159 return chooseLockExtras;
160 }
161
Steven Ng4fdcec72016-09-26 22:13:08 +0100162 private boolean isFingerprintDisabledByAdmin() {
Tony Mak8f41b9b2016-11-23 11:36:18 +0000163 int disabledFeatures =
164 mDevicePolicyManager.getKeyguardDisabledFeatures(null, mTargetUserId);
165 return (disabledFeatures & KEYGUARD_DISABLE_FINGERPRINT) != 0;
Steven Ng4fdcec72016-09-26 22:13:08 +0100166 }
Kevin Chyn81dc0292018-06-28 14:59:38 -0700167
168 private boolean isFaceDisabledByAdmin() {
169 int disabledFeatures =
170 mDevicePolicyManager.getKeyguardDisabledFeatures(null, mTargetUserId);
171 return (disabledFeatures & KEYGUARD_DISABLE_FACE) != 0;
172 }
Steven Ng4fdcec72016-09-26 22:13:08 +0100173}