Make failed ConfirmCredential attempts count towards wipe
Previously, failed ConfirmDeviceCredential attempts only counted towards the wipe limit if it is used as a separate work challenge. In this CL, we additionally make these failed attempts count towards the total failures in the following scenarios: 1) when unified work challenge is enabled 2) for the primary user (e.g. when a wipe limit is set by a DO) 3) for secondary users Bug: 27238008 Test: manual, by entering wrong credentials multiple times Test: make SettingsRoboTests Change-Id: Ie5a099bb3fd46245c13ccf4c8f91c4d935412a4e
This commit is contained in:
@@ -31,6 +31,7 @@ import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentSender;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
@@ -70,6 +71,10 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends OptionsMenuFra
|
||||
public static final String SHOW_WHEN_LOCKED =
|
||||
PACKAGE + ".ConfirmCredentials.showWhenLocked";
|
||||
|
||||
protected static final int USER_TYPE_PRIMARY = 1;
|
||||
protected static final int USER_TYPE_MANAGED_PROFILE = 2;
|
||||
protected static final int USER_TYPE_SECONDARY = 3;
|
||||
|
||||
private FingerprintUiHelper mFingerprintHelper;
|
||||
protected boolean mReturnCredentials = false;
|
||||
protected Button mCancelButton;
|
||||
@@ -78,6 +83,7 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends OptionsMenuFra
|
||||
protected int mUserId;
|
||||
protected UserManager mUserManager;
|
||||
protected LockPatternUtils mLockPatternUtils;
|
||||
protected DevicePolicyManager mDevicePolicyManager;
|
||||
protected TextView mErrorTextView;
|
||||
protected final Handler mHandler = new Handler();
|
||||
|
||||
@@ -92,6 +98,8 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends OptionsMenuFra
|
||||
mUserManager = UserManager.get(getActivity());
|
||||
mEffectiveUserId = mUserManager.getCredentialOwnerProfile(mUserId);
|
||||
mLockPatternUtils = new LockPatternUtils(getActivity());
|
||||
mDevicePolicyManager = (DevicePolicyManager) getActivity().getSystemService(
|
||||
Context.DEVICE_POLICY_SERVICE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -122,9 +130,8 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends OptionsMenuFra
|
||||
}
|
||||
|
||||
private boolean isFingerprintDisabledByAdmin() {
|
||||
DevicePolicyManager dpm = (DevicePolicyManager) getActivity().getSystemService(
|
||||
Context.DEVICE_POLICY_SERVICE);
|
||||
final int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, mEffectiveUserId);
|
||||
final int disabledFeatures =
|
||||
mDevicePolicyManager.getKeyguardDisabledFeatures(null, mEffectiveUserId);
|
||||
return (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) != 0;
|
||||
}
|
||||
|
||||
@@ -158,10 +165,7 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends OptionsMenuFra
|
||||
mFingerprintHelper.stopListening();
|
||||
}
|
||||
}
|
||||
if (isProfileChallenge()) {
|
||||
updateErrorMessage(mLockPatternUtils.getCurrentFailedPasswordAttempts(
|
||||
mEffectiveUserId));
|
||||
}
|
||||
updateErrorMessage(mLockPatternUtils.getCurrentFailedPasswordAttempts(mEffectiveUserId));
|
||||
}
|
||||
|
||||
protected void setAccessibilityTitle(CharSequence supplementalText) {
|
||||
@@ -245,9 +249,8 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends OptionsMenuFra
|
||||
mainContent.setPadding(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
DevicePolicyManager dpm = (DevicePolicyManager) getActivity().getSystemService(
|
||||
Context.DEVICE_POLICY_SERVICE);
|
||||
baseView.setBackground(new ColorDrawable(dpm.getOrganizationColorForUser(userId)));
|
||||
baseView.setBackground(
|
||||
new ColorDrawable(mDevicePolicyManager.getOrganizationColorForUser(userId)));
|
||||
ImageView imageView = (ImageView) baseView.findViewById(R.id.background_image);
|
||||
if (imageView != null) {
|
||||
Drawable image = getResources().getDrawable(R.drawable.work_challenge_background);
|
||||
@@ -263,13 +266,9 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends OptionsMenuFra
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isProfileChallenge() {
|
||||
return mUserManager.isManagedProfile(mEffectiveUserId);
|
||||
}
|
||||
|
||||
protected void reportSuccessfullAttempt() {
|
||||
if (isProfileChallenge()) {
|
||||
mLockPatternUtils.reportSuccessfulPasswordAttempt(mEffectiveUserId);
|
||||
protected void reportSuccessfulAttempt() {
|
||||
mLockPatternUtils.reportSuccessfulPasswordAttempt(mEffectiveUserId);
|
||||
if (mUserManager.isManagedProfile(mEffectiveUserId)) {
|
||||
// Keyguard is responsible to disable StrongAuth for primary user. Disable StrongAuth
|
||||
// for work challenge only here.
|
||||
mLockPatternUtils.userPresent(mEffectiveUserId);
|
||||
@@ -277,40 +276,73 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends OptionsMenuFra
|
||||
}
|
||||
|
||||
protected void reportFailedAttempt() {
|
||||
if (isProfileChallenge()) {
|
||||
// + 1 for this attempt.
|
||||
updateErrorMessage(
|
||||
mLockPatternUtils.getCurrentFailedPasswordAttempts(mEffectiveUserId) + 1);
|
||||
mLockPatternUtils.reportFailedPasswordAttempt(mEffectiveUserId);
|
||||
}
|
||||
updateErrorMessage(
|
||||
mLockPatternUtils.getCurrentFailedPasswordAttempts(mEffectiveUserId) + 1);
|
||||
mLockPatternUtils.reportFailedPasswordAttempt(mEffectiveUserId);
|
||||
}
|
||||
|
||||
protected void updateErrorMessage(int numAttempts) {
|
||||
final int maxAttempts =
|
||||
mLockPatternUtils.getMaximumFailedPasswordsForWipe(mEffectiveUserId);
|
||||
if (maxAttempts > 0 && numAttempts > 0) {
|
||||
int remainingAttempts = maxAttempts - numAttempts;
|
||||
if (remainingAttempts == 1) {
|
||||
// Last try
|
||||
final String title = getActivity().getString(
|
||||
R.string.lock_profile_wipe_warning_title);
|
||||
LastTryDialog.show(getFragmentManager(), title, getLastTryErrorMessage(),
|
||||
android.R.string.ok, false /* dismiss */);
|
||||
} else if (remainingAttempts <= 0) {
|
||||
// Profile is wiped
|
||||
LastTryDialog.show(getFragmentManager(), null /* title */,
|
||||
R.string.lock_profile_wipe_content, R.string.lock_profile_wipe_dismiss,
|
||||
true /* dismiss */);
|
||||
}
|
||||
if (mErrorTextView != null) {
|
||||
final String message = getActivity().getString(R.string.lock_profile_wipe_attempts,
|
||||
numAttempts, maxAttempts);
|
||||
showError(message, 0);
|
||||
}
|
||||
if (maxAttempts <= 0 || numAttempts <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the on-screen error string
|
||||
if (mErrorTextView != null) {
|
||||
final String message = getActivity().getString(
|
||||
R.string.lock_failed_attempts_before_wipe, numAttempts, maxAttempts);
|
||||
showError(message, 0);
|
||||
}
|
||||
|
||||
// Only show popup dialog before the last attempt and before wipe
|
||||
final int remainingAttempts = maxAttempts - numAttempts;
|
||||
if (remainingAttempts > 1) {
|
||||
return;
|
||||
}
|
||||
final FragmentManager fragmentManager = getChildFragmentManager();
|
||||
final int userType = getUserTypeForWipe();
|
||||
if (remainingAttempts == 1) {
|
||||
// Last try
|
||||
final String title = getActivity().getString(
|
||||
R.string.lock_last_attempt_before_wipe_warning_title);
|
||||
final int messageId = getLastTryErrorMessage(userType);
|
||||
LastTryDialog.show(fragmentManager, title, messageId,
|
||||
android.R.string.ok, false /* dismiss */);
|
||||
} else {
|
||||
// Device, profile, or secondary user is wiped
|
||||
final int messageId = getWipeMessage(userType);
|
||||
LastTryDialog.show(fragmentManager, null /* title */, messageId,
|
||||
R.string.lock_failed_attempts_now_wiping_dialog_dismiss, true /* dismiss */);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract int getLastTryErrorMessage();
|
||||
private int getUserTypeForWipe() {
|
||||
final UserInfo userToBeWiped = mUserManager.getUserInfo(
|
||||
mDevicePolicyManager.getProfileWithMinimumFailedPasswordsForWipe(mEffectiveUserId));
|
||||
if (userToBeWiped == null || userToBeWiped.isPrimary()) {
|
||||
return USER_TYPE_PRIMARY;
|
||||
} else if (userToBeWiped.isManagedProfile()) {
|
||||
return USER_TYPE_MANAGED_PROFILE;
|
||||
} else {
|
||||
return USER_TYPE_SECONDARY;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract int getLastTryErrorMessage(int userType);
|
||||
|
||||
private int getWipeMessage(int userType) {
|
||||
switch (userType) {
|
||||
case USER_TYPE_PRIMARY:
|
||||
return R.string.lock_failed_attempts_now_wiping_device;
|
||||
case USER_TYPE_MANAGED_PROFILE:
|
||||
return R.string.lock_failed_attempts_now_wiping_profile;
|
||||
case USER_TYPE_SECONDARY:
|
||||
return R.string.lock_failed_attempts_now_wiping_user;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unrecognized user type:" + userType);
|
||||
}
|
||||
}
|
||||
|
||||
private final Runnable mResetErrorRunnable = new Runnable() {
|
||||
@Override
|
||||
@@ -357,6 +389,7 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends OptionsMenuFra
|
||||
DialogFragment dialog = new LastTryDialog();
|
||||
dialog.setArguments(args);
|
||||
dialog.show(from, TAG);
|
||||
from.executePendingTransactions();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user