* Move all logics around aggregating password policies to the controller * Replace HIDE_DISABLED_PREFS and MINIMUM_QUALITY_KEY with HIDE_INSECURE_OPTIONS as all call sites are just using them to hide insecure screenlock options. * Remove password policy aggregation logic from ChooseLockPassword and make it use policies passed in. * Remove padlock from disabled screen lock options, per UX mock. * Increase char limit for some strings Bug: 177638284 Bug: 177641868 Bug: 182561862 Test: m RunSettingsRoboTests -j ROBOTEST_FILTER=com.android.settings.password Test: 1. set profile password quality/complexity and enroll device lock 2. set profile password quality/complexity and enroll work challenge 3. set parent password quality/complexity and enroll device lock 4. set parent password quality/complexity and enroll work challenge 5. set profile and parent password complexity, then enroll work challenge 6. set profile and parent password complexity, then unify work challenge 7. Enroll device lock during SUW Change-Id: Iba1d37e6f33eba7b7e8e1f805f8e37aaec108404
184 lines
7.8 KiB
Java
184 lines
7.8 KiB
Java
/*
|
|
* Copyright (C) 2016 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package com.android.settings.password;
|
|
|
|
import static android.app.admin.DevicePolicyManager.ACTION_SET_NEW_PASSWORD;
|
|
import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FACE;
|
|
import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT;
|
|
|
|
import static com.android.internal.util.Preconditions.checkNotNull;
|
|
|
|
import android.annotation.Nullable;
|
|
import android.app.ActivityManager;
|
|
import android.app.admin.DevicePolicyManager;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.content.pm.PackageManager;
|
|
import android.hardware.face.FaceManager;
|
|
import android.hardware.fingerprint.FingerprintManager;
|
|
import android.os.Bundle;
|
|
import android.os.IBinder;
|
|
import android.os.UserManager;
|
|
|
|
import androidx.annotation.VisibleForTesting;
|
|
|
|
import com.android.internal.widget.LockPatternUtils;
|
|
import com.android.settings.Utils;
|
|
|
|
/**
|
|
* Business logic for {@link SetNewPasswordActivity}.
|
|
*
|
|
* <p>On devices that supports fingerprint, this controller directs the user to configure
|
|
* fingerprint + a backup password if the device admin allows fingerprint for keyguard and
|
|
* the user has never configured a fingerprint before.
|
|
*/
|
|
final class SetNewPasswordController {
|
|
|
|
interface Ui {
|
|
/** Starts the {@link ChooseLockGeneric} activity with the given extras. */
|
|
void launchChooseLock(Bundle chooseLockFingerprintExtras);
|
|
}
|
|
|
|
/**
|
|
* Which user is setting new password.
|
|
*/
|
|
private final int mTargetUserId;
|
|
private final PackageManager mPackageManager;
|
|
@Nullable
|
|
private final FingerprintManager mFingerprintManager;
|
|
@Nullable
|
|
private final FaceManager mFaceManager;
|
|
private final DevicePolicyManager mDevicePolicyManager;
|
|
private final Ui mUi;
|
|
|
|
public static SetNewPasswordController create(Context context, Ui ui, Intent intent,
|
|
IBinder activityToken) {
|
|
// Trying to figure out which user is setting new password. If it is
|
|
// ACTION_SET_NEW_PARENT_PROFILE_PASSWORD or the calling user is not allowed to set
|
|
// separate profile challenge, it is the current user to set new password. Otherwise,
|
|
// it is the user who starts this activity setting new password.
|
|
int userId = ActivityManager.getCurrentUser();
|
|
if (ACTION_SET_NEW_PASSWORD.equals(intent.getAction())) {
|
|
final int callingUserId = Utils.getSecureTargetUser(activityToken,
|
|
UserManager.get(context), null, intent.getExtras()).getIdentifier();
|
|
final LockPatternUtils lockPatternUtils = new LockPatternUtils(context);
|
|
if (lockPatternUtils.isSeparateProfileChallengeAllowed(callingUserId)) {
|
|
userId = callingUserId;
|
|
}
|
|
}
|
|
// Create a wrapper of FingerprintManager for testing, see IFingerPrintManager for details.
|
|
final FingerprintManager fingerprintManager = Utils.getFingerprintManagerOrNull(context);
|
|
final FaceManager faceManager = Utils.getFaceManagerOrNull(context);
|
|
return new SetNewPasswordController(userId,
|
|
context.getPackageManager(),
|
|
fingerprintManager, faceManager,
|
|
(DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE), ui);
|
|
}
|
|
|
|
@VisibleForTesting
|
|
SetNewPasswordController(
|
|
int targetUserId,
|
|
PackageManager packageManager,
|
|
FingerprintManager fingerprintManager,
|
|
FaceManager faceManager,
|
|
DevicePolicyManager devicePolicyManager,
|
|
Ui ui) {
|
|
mTargetUserId = targetUserId;
|
|
mPackageManager = checkNotNull(packageManager);
|
|
mFingerprintManager = fingerprintManager;
|
|
mFaceManager = faceManager;
|
|
mDevicePolicyManager = checkNotNull(devicePolicyManager);
|
|
mUi = checkNotNull(ui);
|
|
}
|
|
|
|
/**
|
|
* Dispatches the set new password intent to the correct activity that handles it.
|
|
*/
|
|
public void dispatchSetNewPasswordIntent() {
|
|
final Bundle extras;
|
|
|
|
final boolean hasFeatureFingerprint = mPackageManager
|
|
.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT);
|
|
final boolean hasFeatureFace = mPackageManager
|
|
.hasSystemFeature(PackageManager.FEATURE_FACE);
|
|
|
|
final boolean shouldShowFingerprintEnroll = mFingerprintManager != null
|
|
&& mFingerprintManager.isHardwareDetected()
|
|
&& !mFingerprintManager.hasEnrolledFingerprints(mTargetUserId)
|
|
&& !isFingerprintDisabledByAdmin();
|
|
final boolean shouldShowFaceEnroll = mFaceManager != null
|
|
&& mFaceManager.isHardwareDetected()
|
|
&& !mFaceManager.hasEnrolledTemplates(mTargetUserId)
|
|
&& !isFaceDisabledByAdmin();
|
|
|
|
if (hasFeatureFace && shouldShowFaceEnroll
|
|
&& hasFeatureFingerprint && shouldShowFingerprintEnroll) {
|
|
extras = getBiometricChooseLockExtras();
|
|
} else if (hasFeatureFace && shouldShowFaceEnroll) {
|
|
extras = getFaceChooseLockExtras();
|
|
} else if (hasFeatureFingerprint && shouldShowFingerprintEnroll) {
|
|
extras = getFingerprintChooseLockExtras();
|
|
} else {
|
|
extras = new Bundle();
|
|
}
|
|
|
|
// No matter we show fingerprint options or not, we should tell the next activity which
|
|
// user is setting new password.
|
|
extras.putInt(Intent.EXTRA_USER_ID, mTargetUserId);
|
|
mUi.launchChooseLock(extras);
|
|
}
|
|
|
|
private Bundle getBiometricChooseLockExtras() {
|
|
Bundle chooseLockExtras = new Bundle();
|
|
chooseLockExtras.putBoolean(
|
|
ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS, true);
|
|
chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true);
|
|
chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS, true);
|
|
return chooseLockExtras;
|
|
}
|
|
|
|
private Bundle getFingerprintChooseLockExtras() {
|
|
Bundle chooseLockExtras = new Bundle();
|
|
chooseLockExtras.putBoolean(
|
|
ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS, true);
|
|
chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true);
|
|
chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, true);
|
|
return chooseLockExtras;
|
|
}
|
|
|
|
private Bundle getFaceChooseLockExtras() {
|
|
Bundle chooseLockExtras = new Bundle();
|
|
chooseLockExtras.putBoolean(
|
|
ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS, true);
|
|
chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true);
|
|
chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE, true);
|
|
return chooseLockExtras;
|
|
}
|
|
|
|
private boolean isFingerprintDisabledByAdmin() {
|
|
int disabledFeatures =
|
|
mDevicePolicyManager.getKeyguardDisabledFeatures(null, mTargetUserId);
|
|
return (disabledFeatures & KEYGUARD_DISABLE_FINGERPRINT) != 0;
|
|
}
|
|
|
|
private boolean isFaceDisabledByAdmin() {
|
|
int disabledFeatures =
|
|
mDevicePolicyManager.getKeyguardDisabledFeatures(null, mTargetUserId);
|
|
return (disabledFeatures & KEYGUARD_DISABLE_FACE) != 0;
|
|
}
|
|
}
|