summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java18
-rw-r--r--core/java/android/app/admin/IDevicePolicyManager.aidl1
-rw-r--r--packages/Keyguard/res/values/strings.xml64
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java73
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java13
5 files changed, 145 insertions, 24 deletions
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 57d53aa..86f9060 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1345,6 +1345,24 @@ public class DevicePolicyManager {
}
/**
+ * Returns the profile with the smallest maximum failed passwords for wipe,
+ * for the given user. So for primary user, it might return the primary or
+ * a managed profile. For a secondary user, it would be the same as the
+ * user passed in.
+ * @hide Used only by Keyguard
+ */
+ public int getProfileWithMinimumFailedPasswordsForWipe(int userHandle) {
+ if (mService != null) {
+ try {
+ return mService.getProfileWithMinimumFailedPasswordsForWipe(userHandle);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed talking with device policy service", e);
+ }
+ }
+ return UserHandle.USER_NULL;
+ }
+
+ /**
* Flag for {@link #resetPassword}: don't allow other admins to change
* the password again until the user has entered it.
*/
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 07aa800..d144ae8 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -66,6 +66,7 @@ interface IDevicePolicyManager {
boolean isActivePasswordSufficient(int userHandle);
int getCurrentFailedPasswordAttempts(int userHandle);
+ int getProfileWithMinimumFailedPasswordsForWipe(int userHandle);
void setMaximumFailedPasswordsForWipe(in ComponentName admin, int num, int userHandle);
int getMaximumFailedPasswordsForWipe(in ComponentName admin, int userHandle);
diff --git a/packages/Keyguard/res/values/strings.xml b/packages/Keyguard/res/values/strings.xml
index a136acf..21d8dc5 100644
--- a/packages/Keyguard/res/values/strings.xml
+++ b/packages/Keyguard/res/values/strings.xml
@@ -290,28 +290,76 @@
You have incorrectly drawn your unlock pattern <xliff:g id="number">%d</xliff:g> times.
\n\nTry again in <xliff:g id="number">%d</xliff:g> seconds.
</string>
- <!-- Message shown when user is almost at the limit of password attempts where the device will be wiped. -->
+
+ <!-- Message shown when user is almost at the limit of password attempts where the device will be wiped. [CHAR LIMIT=none] -->
<string name="kg_failed_attempts_almost_at_wipe" product="tablet">
You have incorrectly attempted to unlock the tablet <xliff:g id="number">%d</xliff:g> times.
After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
- the tablet will be reset to factory default and all user data will be lost.
+ this tablet will be reset, which will delete all its data.
</string>
- <!-- Message shown when user is almost at the limit of password attempts where the device will be wiped. -->
+ <!-- Message shown when user is almost at the limit of password attempts where the device will be wiped. [CHAR LIMIT=none] -->
<string name="kg_failed_attempts_almost_at_wipe" product="default">
You have incorrectly attempted to unlock the phone <xliff:g id="number">%d</xliff:g> times.
After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
- the phone will be reset to factory default and all user data will be lost.
+ this phone will be reset, which will delete all its data.
</string>
- <!-- Message shown in dialog when user has exceeded the maximum attempts and the device will now be wiped -->
+ <!-- Message shown in dialog when user has exceeded the maximum attempts and the device will now be wiped [CHAR LIMIT=none] -->
<string name="kg_failed_attempts_now_wiping" product="tablet">
You have incorrectly attempted to unlock the tablet <xliff:g id="number">%d</xliff:g> times.
- The tablet will now be reset to factory default.
+ This tablet will be reset, which will delete all its data.
</string>
- <!-- Message shown in dialog when user has exceeded the maximum attempts and the device will now be wiped -->
+ <!-- Message shown in dialog when user has exceeded the maximum attempts and the device will now be wiped [CHAR LIMIT=none] -->
<string name="kg_failed_attempts_now_wiping" product="default">
You have incorrectly attempted to unlock the phone <xliff:g id="number">%d</xliff:g> times.
- The phone will now be reset to factory default.
+ This phone will be reset, which will delete all its data.
+ </string>
+
+ <!-- Message shown when user is almost at the limit of password attempts where the user will be removed. [CHAR LIMIT=none] -->
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet">
+ You have incorrectly attempted to unlock the tablet <xliff:g id="number">%d</xliff:g> times.
+ After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
+ this user will be removed, which will delete all user data.
+ </string>
+ <!-- Message shown when user is almost at the limit of password attempts where the user will be removed. [CHAR LIMIT=none] -->
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default">
+ You have incorrectly attempted to unlock the phone <xliff:g id="number">%d</xliff:g> times.
+ After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
+ this user will be removed, which will delete all user data.
+ </string>
+ <!-- Message shown in dialog when user has exceeded the maximum attempts and the user will be removed. [CHAR LIMIT=none] -->
+ <string name="kg_failed_attempts_now_erasing_user" product="tablet">
+ You have incorrectly attempted to unlock the tablet <xliff:g id="number">%d</xliff:g> times.
+ This user will be removed, which will delete all user data.
+ </string>
+ <!-- Message shown in dialog when user has exceeded the maximum attempts and the user will be removed. [CHAR LIMIT=none] -->
+ <string name="kg_failed_attempts_now_erasing_user" product="default">
+ You have incorrectly attempted to unlock the phone <xliff:g id="number">%d</xliff:g> times.
+ This user will be removed, which will delete all user data.
</string>
+
+ <!-- Message shown when user is almost at the limit of password attempts where the profile will be removed. [CHAR LIMIT=none] -->
+ <string name="kg_failed_attempts_almost_at_erase_profile" product="tablet">
+ You have incorrectly attempted to unlock the tablet <xliff:g id="number">%d</xliff:g> times.
+ After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
+ the work profile will be removed, which will delete all profile data.
+ </string>
+ <!-- Message shown when user is almost at the limit of password attempts where the profile will be removed. [CHAR LIMIT=none] -->
+ <string name="kg_failed_attempts_almost_at_erase_profile" product="default">
+ You have incorrectly attempted to unlock the phone <xliff:g id="number">%d</xliff:g> times.
+ After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
+ the work profile will be removed, which will delete all profile data.
+ </string>
+ <!-- Message shown in dialog when user has exceeded the maximum attempts and the profile will be removed. [CHAR LIMIT=none] -->
+ <string name="kg_failed_attempts_now_erasing_profile" product="tablet">
+ You have incorrectly attempted to unlock the tablet <xliff:g id="number">%d</xliff:g> times.
+ The work profile will be removed, which will delete all profile data.
+ </string>
+ <!-- Message shown in dialog when user has exceeded the maximum attempts and the profile will be removed. [CHAR LIMIT=none] -->
+ <string name="kg_failed_attempts_now_erasing_profile" product="default">
+ You have incorrectly attempted to unlock the phone <xliff:g id="number">%d</xliff:g> times.
+ The work profile will be removed, which will delete all profile data.
+ </string>
+
<!-- Message shown in dialog when user is almost at the limit where they will be
locked out and may have to enter an alternate username/password to unlock the phone -->
<string name="kg_failed_attempts_almost_at_login" product="tablet">
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
index 119471b..979c377 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -17,7 +17,10 @@ package com.android.keyguard;
import android.app.Activity;
import android.app.AlertDialog;
+import android.app.admin.DevicePolicyManager;
import android.content.Context;
+import android.os.UserHandle;
+import android.os.UserManager;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Slog;
@@ -32,6 +35,11 @@ import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSecurityView {
private static final boolean DEBUG = KeyguardConstants.DEBUG;
private static final String TAG = "KeyguardSecurityView";
+
+ private static final int USER_TYPE_PRIMARY = 1;
+ private static final int USER_TYPE_WORK_PROFILE = 2;
+ private static final int USER_TYPE_SECONDARY_USER = 3;
+
private KeyguardSecurityModel mSecurityModel;
private boolean mEnableFallback; // TODO: This should get the value from KeyguardPatternView
private LockPatternUtils mLockPatternUtils;
@@ -207,14 +215,41 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
}
}
- private void showAlmostAtWipeDialog(int attempts, int remaining) {
- String message = mContext.getString(R.string.kg_failed_attempts_almost_at_wipe,
- attempts, remaining);
+ private void showAlmostAtWipeDialog(int attempts, int remaining, int userType) {
+ String message = null;
+ switch (userType) {
+ case USER_TYPE_PRIMARY:
+ message = mContext.getString(R.string.kg_failed_attempts_almost_at_wipe,
+ attempts, remaining);
+ break;
+ case USER_TYPE_SECONDARY_USER:
+ message = mContext.getString(R.string.kg_failed_attempts_almost_at_erase_user,
+ attempts, remaining);
+ break;
+ case USER_TYPE_WORK_PROFILE:
+ message = mContext.getString(R.string.kg_failed_attempts_almost_at_erase_profile,
+ attempts, remaining);
+ break;
+ }
showDialog(null, message);
}
- private void showWipeDialog(int attempts) {
- String message = mContext.getString(R.string.kg_failed_attempts_now_wiping, attempts);
+ private void showWipeDialog(int attempts, int userType) {
+ String message = null;
+ switch (userType) {
+ case USER_TYPE_PRIMARY:
+ message = mContext.getString(R.string.kg_failed_attempts_now_wiping,
+ attempts);
+ break;
+ case USER_TYPE_SECONDARY_USER:
+ message = mContext.getString(R.string.kg_failed_attempts_now_erasing_user,
+ attempts);
+ break;
+ case USER_TYPE_WORK_PROFILE:
+ message = mContext.getString(R.string.kg_failed_attempts_now_erasing_profile,
+ attempts);
+ break;
+ }
showDialog(null, message);
}
@@ -235,9 +270,10 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
SecurityMode mode = mSecurityModel.getSecurityMode();
final boolean usingPattern = mode == KeyguardSecurityModel.SecurityMode.Pattern;
-
- final int failedAttemptsBeforeWipe = mLockPatternUtils.getDevicePolicyManager()
- .getMaximumFailedPasswordsForWipe(null, mLockPatternUtils.getCurrentUser());
+ final int currentUser = mLockPatternUtils.getCurrentUser();
+ final DevicePolicyManager dpm = mLockPatternUtils.getDevicePolicyManager();
+ final int failedAttemptsBeforeWipe =
+ dpm.getMaximumFailedPasswordsForWipe(null, currentUser);
final int failedAttemptWarning = LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET
- LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT;
@@ -245,22 +281,27 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
final int remainingBeforeWipe = failedAttemptsBeforeWipe > 0 ?
(failedAttemptsBeforeWipe - failedAttempts)
: Integer.MAX_VALUE; // because DPM returns 0 if no restriction
-
boolean showTimeout = false;
if (remainingBeforeWipe < LockPatternUtils.FAILED_ATTEMPTS_BEFORE_WIPE_GRACE) {
// The user has installed a DevicePolicyManager that requests a user/profile to be wiped
// N attempts. Once we get below the grace period, we post this dialog every time as a
// clear warning until the deletion fires.
- //
- // TODO: Show a different dialog depending on whether the device will be completely
- // wiped (i.e. policy is set for the primary profile of the USER_OWNER) or a single
- // secondary user or managed profile will be removed.
+ // Check which profile has the strictest policy for failed password attempts
+ final int expiringUser = dpm.getProfileWithMinimumFailedPasswordsForWipe(currentUser);
+ int userType = USER_TYPE_PRIMARY;
+ if (expiringUser == currentUser) {
+ if (expiringUser != UserHandle.USER_OWNER) {
+ userType = USER_TYPE_SECONDARY_USER;
+ }
+ } else if (expiringUser != UserHandle.USER_NULL) {
+ userType = USER_TYPE_WORK_PROFILE;
+ } // If USER_NULL, which shouldn't happen, leave it as USER_TYPE_PRIMARY
if (remainingBeforeWipe > 0) {
- showAlmostAtWipeDialog(failedAttempts, remainingBeforeWipe);
+ showAlmostAtWipeDialog(failedAttempts, remainingBeforeWipe, userType);
} else {
// Too many attempts. The device will be wiped shortly.
- Slog.i(TAG, "Too many unlock attempts; device will be wiped!");
- showWipeDialog(failedAttempts);
+ Slog.i(TAG, "Too many unlock attempts; user " + expiringUser + " will be wiped!");
+ showWipeDialog(failedAttempts, userType);
}
} else {
showTimeout =
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index b97f4f9..ac5fb18 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -2521,6 +2521,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
+ @Override
public int getMaximumFailedPasswordsForWipe(ComponentName who, int userHandle) {
if (!mHasFeature) {
return 0;
@@ -2533,6 +2534,18 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
+ @Override
+ public int getProfileWithMinimumFailedPasswordsForWipe(int userHandle) {
+ if (!mHasFeature) {
+ return UserHandle.USER_NULL;
+ }
+ enforceCrossUserPermission(userHandle);
+ synchronized (this) {
+ ActiveAdmin admin = getAdminWithMinimumFailedPasswordsForWipeLocked(userHandle);
+ return admin != null ? admin.getUserHandle().getIdentifier() : UserHandle.USER_NULL;
+ }
+ }
+
/**
* Returns the admin with the strictest policy on maximum failed passwords for this user and all
* profiles that are visible from this user. If the policy for the primary and any other profile