diff --git a/res/values/strings.xml b/res/values/strings.xml
index c66812ed4e2..546259c0919 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1243,20 +1243,38 @@
Change unlock password
-
- Try again. Attempt %1$d of %2$d.
-
- Last try
-
- If you enter an incorrect work pattern on this attempt, your work profile and associated data will be removed from this device.
-
- If you enter an incorrect work PIN on this attempt, your work profile and associated data will be removed from this device.
-
- If you enter an incorrect work password on this attempt, your work profile and associated data will be removed from this device.
-
- Too many incorrect attempts. Your work profile and associated data will be removed from this device.
+
+ Try again. Attempt %1$d of %2$d.
+
+
+ Your data will be deleted
+
+ If you enter an incorrect pattern on the next attempt, this device's data will be deleted
+
+ If you enter an incorrect PIN on the next attempt, this device's data will be deleted
+
+ If you enter an incorrect password on the next attempt, this device's data will be deleted
+
+ If you enter an incorrect pattern on the next attempt, this user will be deleted
+
+ If you enter an incorrect PIN on the next attempt, this user will be deleted
+
+ If you enter an incorrect password on the next attempt, this user will be deleted
+
+ If you enter an incorrect pattern on the next attempt, your work profile and its data will be deleted
+
+ If you enter an incorrect PIN on the next attempt, your work profile and its data will be deleted
+
+ If you enter an incorrect password on the next attempt, your work profile and its data will be deleted
+
+
+ Too many incorrect attempts. This device's data will be deleted.
+
+ Too many incorrect attempts. This user will be deleted.
+
+ Too many incorrect attempts. This work profile and its data will be deleted.
- Dismiss
+ Dismiss
Must be at least %d characters
diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java b/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java
index ae2dd426912..0c36dba76ad 100644
--- a/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java
+++ b/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java
@@ -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;
}
diff --git a/src/com/android/settings/password/ConfirmLockPassword.java b/src/com/android/settings/password/ConfirmLockPassword.java
index ef115218657..a91f572b097 100644
--- a/src/com/android/settings/password/ConfirmLockPassword.java
+++ b/src/com/android/settings/password/ConfirmLockPassword.java
@@ -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();
}
diff --git a/src/com/android/settings/password/ConfirmLockPattern.java b/src/com/android/settings/password/ConfirmLockPattern.java
index b66edfec01d..c16b55ab9e5 100644
--- a/src/com/android/settings/password/ConfirmLockPattern.java
+++ b/src/com/android/settings/password/ConfirmLockPattern.java
@@ -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) {