Merge "Make failed ConfirmCredential attempts count towards wipe"

This commit is contained in:
Charles He
2017-05-25 12:35:42 +00:00
committed by Android (Google) Code Review
4 changed files with 140 additions and 75 deletions

View File

@@ -1243,20 +1243,38 @@
<!-- Title shown on security settings to allow the user to change their lockscreen password [CHAR LIMIT=22]-->
<string name="unlock_change_lock_password_title">Change unlock password</string>
<!-- Message shown when the user incorrectly enters their lock and it counts towards the max attempts before wiping the work profile. -->
<string name="lock_profile_wipe_attempts">Try again. Attempt <xliff:g id="current_attempts">%1$d</xliff:g> of <xliff:g id="total_attempts">%2$d</xliff:g>.</string>
<!-- Title of a dialog shown when the user only has one attempt left to provide the lock before the work profile is wiped. -->
<string name="lock_profile_wipe_warning_title">Last try</string>
<!-- Content of the dialog shown when the user only has one attempt left to provide the work pattern before the work profile is wiped. -->
<string name="lock_profile_wipe_warning_content_pattern">If you enter an incorrect work pattern on this attempt, your work profile and associated data will be removed from this device.</string>
<!-- Content of the dialog shown when the user only has one attempt left to provide the work PIN before the work profile is wiped. -->
<string name="lock_profile_wipe_warning_content_pin">If you enter an incorrect work PIN on this attempt, your work profile and associated data will be removed from this device.</string>
<!-- Content of the dialog shown when the user only has one attempt left to provide the work password before the work profile is wiped. -->
<string name="lock_profile_wipe_warning_content_password">If you enter an incorrect work password on this attempt, your work profile and associated data will be removed from this device.</string>
<!-- Content of the dialog shown when the user has failed to provide the work lock too many times and the work profile is wiped. -->
<string name="lock_profile_wipe_content">Too many incorrect attempts. Your work profile and associated data will be removed from this device.</string>
<!-- Message shown on the lock screen when the user incorrectly enters their lock and it counts towards the max attempts before their data on the device is wiped. [CHAR LIMIT=NONE] -->
<string name="lock_failed_attempts_before_wipe">Try again. Attempt <xliff:g id="current_attempts">%1$d</xliff:g> of <xliff:g id="total_attempts">%2$d</xliff:g>.</string>
<!-- Title of a dialog shown when the user only has one attempt left to provide the lock before the device, one of its users, or a work profile is wiped. [CHAR LIMIT=NONE] -->
<string name="lock_last_attempt_before_wipe_warning_title">Your data will be deleted</string>
<!-- Content of the dialog shown when the user only has one attempt left to provide the device lock pattern before the device is wiped. [CHAR LIMIT=NONE] -->
<string name="lock_last_pattern_attempt_before_wipe_device">If you enter an incorrect pattern on the next attempt, this device's data will be deleted</string>
<!-- Content of the dialog shown when the user only has one attempt left to provide the device lock PIN before the device is wiped. [CHAR LIMIT=NONE] -->
<string name="lock_last_pin_attempt_before_wipe_device">If you enter an incorrect PIN on the next attempt, this device's data will be deleted</string>
<!-- Content of the dialog shown when the user only has one attempt left to provide the device lock password before the device is wiped. [CHAR LIMIT=NONE] -->
<string name="lock_last_password_attempt_before_wipe_device">If you enter an incorrect password on the next attempt, this device's data will be deleted</string>
<!-- Content of the dialog shown when the user only has one attempt left to provide the user lock pattern before the user is removed. [CHAR LIMIT=NONE] -->
<string name="lock_last_pattern_attempt_before_wipe_user">If you enter an incorrect pattern on the next attempt, this user will be deleted</string>
<!-- Content of the dialog shown when the user only has one attempt left to provide the user lock PIN before the user is removed. [CHAR LIMIT=NONE] -->
<string name="lock_last_pin_attempt_before_wipe_user">If you enter an incorrect PIN on the next attempt, this user will be deleted</string>
<!-- Content of the dialog shown when the user only has one attempt left to provide the user lock password before the user is removed. [CHAR LIMIT=NONE] -->
<string name="lock_last_password_attempt_before_wipe_user">If you enter an incorrect password on the next attempt, this user will be deleted</string>
<!-- Content of the dialog shown when the user only has one attempt left to provide the work lock pattern before the work profile is removed. [CHAR LIMIT=NONE] -->
<string name="lock_last_pattern_attempt_before_wipe_profile">If you enter an incorrect pattern on the next attempt, your work profile and its data will be deleted</string>
<!-- Content of the dialog shown when the user only has one attempt left to provide the work lock PIN before the work profile is removed. [CHAR LIMIT=NONE] -->
<string name="lock_last_pin_attempt_before_wipe_profile">If you enter an incorrect PIN on the next attempt, your work profile and its data will be deleted</string>
<!-- Content of the dialog shown when the user only has one attempt left to provide the work lock password before the work profile is removed. [CHAR LIMIT=NONE] -->
<string name="lock_last_password_attempt_before_wipe_profile">If you enter an incorrect password on the next attempt, your work profile and its data will be deleted</string>
<!-- Content of the dialog shown when the user has failed to provide the device lock too many times and the device is wiped. [CHAR LIMIT=NONE] -->
<string name="lock_failed_attempts_now_wiping_device">Too many incorrect attempts. This device's data will be deleted.</string>
<!-- Content of the dialog shown when the user has failed to provide the user lock too many times and the user is removed. [CHAR LIMIT=NONE] -->
<string name="lock_failed_attempts_now_wiping_user">Too many incorrect attempts. This user will be deleted.</string>
<!-- Content of the dialog shown when the user has failed to provide the work lock too many times and the work profile is removed. [CHAR LIMIT=NONE] -->
<string name="lock_failed_attempts_now_wiping_profile">Too many incorrect attempts. This work profile and its data will be deleted.</string>
<!-- Button label to dismiss the dialog telling the user the work profile has been wiped. [CHAR LIMIT=40] -->
<string name="lock_profile_wipe_dismiss">Dismiss</string>
<string name="lock_failed_attempts_now_wiping_dialog_dismiss">Dismiss</string>
<!-- Hint shown in dialog screen when password is too short -->
<string name="lockpassword_password_too_short">Must be at least <xliff:g id="count" example="3">%d</xliff:g> characters</string>

View File

@@ -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;
}

View File

@@ -211,9 +211,20 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
}
@Override
protected int getLastTryErrorMessage() {
return mIsAlpha ? R.string.lock_profile_wipe_warning_content_password
: R.string.lock_profile_wipe_warning_content_pin;
protected int getLastTryErrorMessage(int userType) {
switch (userType) {
case USER_TYPE_PRIMARY:
return mIsAlpha ? R.string.lock_last_password_attempt_before_wipe_device
: R.string.lock_last_pin_attempt_before_wipe_device;
case USER_TYPE_MANAGED_PROFILE:
return mIsAlpha ? R.string.lock_last_password_attempt_before_wipe_profile
: R.string.lock_last_pin_attempt_before_wipe_profile;
case USER_TYPE_SECONDARY:
return mIsAlpha ? R.string.lock_last_password_attempt_before_wipe_user
: R.string.lock_last_pin_attempt_before_wipe_user;
default:
throw new IllegalArgumentException("Unrecognized user type:" + userType);
}
}
@Override
@@ -278,10 +289,8 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
} else {
resetState();
mErrorTextView.setText("");
if (isProfileChallenge()) {
updateErrorMessage(mLockPatternUtils.getCurrentFailedPasswordAttempts(
mEffectiveUserId));
}
updateErrorMessage(
mLockPatternUtils.getCurrentFailedPasswordAttempts(mEffectiveUserId));
}
mCredentialCheckResultTracker.setListener(this);
}
@@ -444,7 +453,7 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
mPasswordEntryInputDisabler.setInputEnabled(true);
if (matched) {
if (newResult) {
reportSuccessfullAttempt();
reportSuccessfulAttempt();
}
startDisappearAnimation(intent);
checkForPendingIntent();
@@ -493,10 +502,8 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
public void onFinish() {
resetState();
mErrorTextView.setText("");
if (isProfileChallenge()) {
updateErrorMessage(mLockPatternUtils.getCurrentFailedPasswordAttempts(
mEffectiveUserId));
}
updateErrorMessage(
mLockPatternUtils.getCurrentFailedPasswordAttempts(mEffectiveUserId));
}
}.start();
}

View File

@@ -299,10 +299,8 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
mDetailsTextView.setText(getDefaultDetails());
}
mErrorTextView.setText("");
if (isProfileChallenge()) {
updateErrorMessage(mLockPatternUtils.getCurrentFailedPasswordAttempts(
mEffectiveUserId));
}
updateErrorMessage(
mLockPatternUtils.getCurrentFailedPasswordAttempts(mEffectiveUserId));
mLockPatternView.setEnabled(true);
mLockPatternView.enableInput();
@@ -497,7 +495,7 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
mLockPatternView.setEnabled(true);
if (matched) {
if (newResult) {
reportSuccessfullAttempt();
reportSuccessfulAttempt();
}
startDisappearAnimation(intent);
checkForPendingIntent();
@@ -524,8 +522,17 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
}
@Override
protected int getLastTryErrorMessage() {
return R.string.lock_profile_wipe_warning_content_pattern;
protected int getLastTryErrorMessage(int userType) {
switch (userType) {
case USER_TYPE_PRIMARY:
return R.string.lock_last_pattern_attempt_before_wipe_device;
case USER_TYPE_MANAGED_PROFILE:
return R.string.lock_last_pattern_attempt_before_wipe_profile;
case USER_TYPE_SECONDARY:
return R.string.lock_last_pattern_attempt_before_wipe_user;
default:
throw new IllegalArgumentException("Unrecognized user type:" + userType);
}
}
private void handleAttemptLockout(long elapsedRealtimeDeadline) {