diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index c8c35c704297d..8a3a16e9a6cfc 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -374,9 +374,31 @@
Wrong password
Too many incorrect attempts.\nTry again in %d seconds.
+
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\u2019s data will be deleted.
+
+ If you enter an incorrect PIN on the next attempt, this device\u2019s data will be deleted.
+
+ If you enter an incorrect password on the next attempt, this device\u2019s 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\u2019s data will be deleted.
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java
index 13f3c0fce5c21..b006bc1351a32 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java
@@ -347,21 +347,35 @@ public abstract class AuthCredentialView extends LinearLayout {
showError(message);
}
- // Only show popup dialog before wipe.
+ // Only show dialog if <=1 attempts are left before wiping.
final int remainingAttempts = maxAttempts - numAttempts;
- if (remainingAttempts <= 0) {
- showNowWipingMessage();
- mContainerView.animateAway(AuthDialogCallback.DISMISSED_ERROR);
+ if (remainingAttempts == 1) {
+ showLastAttemptBeforeWipeDialog();
+ } else if (remainingAttempts <= 0) {
+ showNowWipingDialog();
}
return true;
}
- private void showNowWipingMessage() {
+ private void showLastAttemptBeforeWipeDialog() {
+ final AlertDialog alertDialog = new AlertDialog.Builder(mContext)
+ .setTitle(R.string.biometric_dialog_last_attempt_before_wipe_dialog_title)
+ .setMessage(
+ getLastAttemptBeforeWipeMessageRes(getUserTypeForWipe(), mCredentialType))
+ .setPositiveButton(android.R.string.ok, null)
+ .create();
+ alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL);
+ alertDialog.show();
+ }
+
+ private void showNowWipingDialog() {
final AlertDialog alertDialog = new AlertDialog.Builder(mContext)
.setMessage(getNowWipingMessageRes(getUserTypeForWipe()))
.setPositiveButton(R.string.biometric_dialog_now_wiping_dialog_dismiss, null)
+ .setOnDismissListener(
+ dialog -> mContainerView.animateAway(AuthDialogCallback.DISMISSED_ERROR))
.create();
- alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+ alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL);
alertDialog.show();
}
@@ -377,6 +391,59 @@ public abstract class AuthCredentialView extends LinearLayout {
}
}
+ private static @StringRes int getLastAttemptBeforeWipeMessageRes(
+ @UserType int userType, @Utils.CredentialType int credentialType) {
+ switch (userType) {
+ case USER_TYPE_PRIMARY:
+ return getLastAttemptBeforeWipeDeviceMessageRes(credentialType);
+ case USER_TYPE_MANAGED_PROFILE:
+ return getLastAttemptBeforeWipeProfileMessageRes(credentialType);
+ case USER_TYPE_SECONDARY:
+ return getLastAttemptBeforeWipeUserMessageRes(credentialType);
+ default:
+ throw new IllegalArgumentException("Unrecognized user type:" + userType);
+ }
+ }
+
+ private static @StringRes int getLastAttemptBeforeWipeDeviceMessageRes(
+ @Utils.CredentialType int credentialType) {
+ switch (credentialType) {
+ case Utils.CREDENTIAL_PIN:
+ return R.string.biometric_dialog_last_pin_attempt_before_wipe_device;
+ case Utils.CREDENTIAL_PATTERN:
+ return R.string.biometric_dialog_last_pattern_attempt_before_wipe_device;
+ case Utils.CREDENTIAL_PASSWORD:
+ default:
+ return R.string.biometric_dialog_last_password_attempt_before_wipe_device;
+ }
+ }
+
+ private static @StringRes int getLastAttemptBeforeWipeProfileMessageRes(
+ @Utils.CredentialType int credentialType) {
+ switch (credentialType) {
+ case Utils.CREDENTIAL_PIN:
+ return R.string.biometric_dialog_last_pin_attempt_before_wipe_profile;
+ case Utils.CREDENTIAL_PATTERN:
+ return R.string.biometric_dialog_last_pattern_attempt_before_wipe_profile;
+ case Utils.CREDENTIAL_PASSWORD:
+ default:
+ return R.string.biometric_dialog_last_password_attempt_before_wipe_profile;
+ }
+ }
+
+ private static @StringRes int getLastAttemptBeforeWipeUserMessageRes(
+ @Utils.CredentialType int credentialType) {
+ switch (credentialType) {
+ case Utils.CREDENTIAL_PIN:
+ return R.string.biometric_dialog_last_pin_attempt_before_wipe_user;
+ case Utils.CREDENTIAL_PATTERN:
+ return R.string.biometric_dialog_last_pattern_attempt_before_wipe_user;
+ case Utils.CREDENTIAL_PASSWORD:
+ default:
+ return R.string.biometric_dialog_last_password_attempt_before_wipe_user;
+ }
+ }
+
private static @StringRes int getNowWipingMessageRes(@UserType int userType) {
switch (userType) {
case USER_TYPE_PRIMARY: