summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
authorRubin Xu <rubinxu@google.com>2017-09-06 12:19:51 +0000
committerandroid-build-merger <android-build-merger@google.com>2017-09-06 12:19:51 +0000
commitc17f1d412b682ee12f30bc77b3b5275a5898fc7e (patch)
tree8cea64aba883e4a2167d5238c6f36159f591f46c /core/java
parent1605878d62832c1d6f0bc5622667963a71d9c68b (diff)
parent2e21fba2b506e8b56fcc776853f3c314dc593ffb (diff)
Merge "Fix resetPasswordWithToken before user unlock" into oc-mr1-dev
am: 2e21fba2b5 Change-Id: I83688cd83cf18f37b3507ebe69d29dbc2669178b
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java2
-rw-r--r--core/java/android/app/admin/PasswordMetrics.java20
-rw-r--r--core/java/com/android/internal/widget/LockPatternUtils.java49
3 files changed, 57 insertions, 14 deletions
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 56123a72d00e..121b58a2b104 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -2531,7 +2531,7 @@ public class DevicePolicyManager {
* @return Returns true if the password meets the current requirements, else false.
* @throws SecurityException if the calling application does not own an active administrator
* that uses {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD}
- * @throws InvalidStateException if the user is not unlocked.
+ * @throws IllegalStateException if the user is not unlocked.
*/
public boolean isActivePasswordSufficient() {
if (mService != null) {
diff --git a/core/java/android/app/admin/PasswordMetrics.java b/core/java/android/app/admin/PasswordMetrics.java
index ea3f560d02db..4658a47444f9 100644
--- a/core/java/android/app/admin/PasswordMetrics.java
+++ b/core/java/android/app/admin/PasswordMetrics.java
@@ -18,13 +18,11 @@ package android.app.admin;
import android.annotation.IntDef;
import android.annotation.NonNull;
-import android.app.admin.DevicePolicyManager;
-import android.os.Parcelable;
import android.os.Parcel;
+import android.os.Parcelable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.io.IOException;
/**
* A class that represents the metrics of a password that are used to decide whether or not a
@@ -159,6 +157,22 @@ public class PasswordMetrics implements Parcelable {
quality, length, letters, upperCase, lowerCase, numeric, symbols, nonLetter);
}
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof PasswordMetrics)) {
+ return false;
+ }
+ PasswordMetrics o = (PasswordMetrics) other;
+ return this.quality == o.quality
+ && this.length == o.length
+ && this.letters == o.letters
+ && this.upperCase == o.upperCase
+ && this.lowerCase == o.lowerCase
+ && this.numeric == o.numeric
+ && this.symbols == o.symbols
+ && this.nonLetter == o.nonLetter;
+ }
+
/*
* Returns the maximum length of a sequential characters. A sequence is defined as
* monotonically increasing characters with a constant interval or the same character repeated.
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 0d1575805ee9..f85333eb9588 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -803,12 +803,14 @@ public class LockPatternUtils {
+ "of length " + MIN_LOCK_PASSWORD_SIZE);
}
- final int computedQuality = PasswordMetrics.computeForPassword(password).quality;
- setLong(PASSWORD_TYPE_KEY, Math.max(requestedQuality, computedQuality), userHandle);
+ setLong(PASSWORD_TYPE_KEY,
+ computePasswordQuality(CREDENTIAL_TYPE_PASSWORD, password, requestedQuality),
+ userHandle);
getLockSettings().setLockCredential(password, CREDENTIAL_TYPE_PASSWORD, savedPassword,
requestedQuality, userHandle);
- updateEncryptionPasswordIfNeeded(password, computedQuality, userHandle);
+ updateEncryptionPasswordIfNeeded(password,
+ PasswordMetrics.computeForPassword(password).quality, userHandle);
updatePasswordHistory(password, userHandle);
} catch (RemoteException re) {
// Cant do much
@@ -898,6 +900,24 @@ public class LockPatternUtils {
}
/**
+ * Returns the password quality of the given credential, promoting it to a higher level
+ * if DevicePolicyManager has a stronger quality requirement. This value will be written
+ * to PASSWORD_TYPE_KEY.
+ */
+ private int computePasswordQuality(int type, String credential, int requestedQuality) {
+ final int quality;
+ if (type == CREDENTIAL_TYPE_PASSWORD) {
+ int computedQuality = PasswordMetrics.computeForPassword(credential).quality;
+ quality = Math.max(requestedQuality, computedQuality);
+ } else if (type == CREDENTIAL_TYPE_PATTERN) {
+ quality = DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
+ } else /* if (type == CREDENTIAL_TYPE_NONE) */ {
+ quality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+ }
+ return quality;
+ }
+
+ /**
* Enables/disables the Separate Profile Challenge for this {@param userHandle}. This is a no-op
* for user handles that do not belong to a managed profile.
*
@@ -1505,25 +1525,34 @@ public class LockPatternUtils {
}
}
- public boolean setLockCredentialWithToken(String credential, int type, long tokenHandle,
- byte[] token, int userId) {
+ /**
+ * Change a user's lock credential with a pre-configured escrow token.
+ *
+ * @param credential The new credential to be set
+ * @param type Credential type: password / pattern / none.
+ * @param requestedQuality the requested password quality by DevicePolicyManager.
+ * See {@link DevicePolicyManager#getPasswordQuality(android.content.ComponentName)}
+ * @param tokenHandle Handle of the escrow token
+ * @param token Escrow token
+ * @param userId The user who's lock credential to be changed
+ * @return {@code true} if the operation is successful.
+ */
+ public boolean setLockCredentialWithToken(String credential, int type, int requestedQuality,
+ long tokenHandle, byte[] token, int userId) {
try {
if (type != CREDENTIAL_TYPE_NONE) {
if (TextUtils.isEmpty(credential) || credential.length() < MIN_LOCK_PASSWORD_SIZE) {
throw new IllegalArgumentException("password must not be null and at least "
+ "of length " + MIN_LOCK_PASSWORD_SIZE);
}
-
- final int computedQuality = PasswordMetrics.computeForPassword(credential).quality;
- int quality = Math.max(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC,
- computedQuality);
+ final int quality = computePasswordQuality(type, credential, requestedQuality);
if (!getLockSettings().setLockCredentialWithToken(credential, type, tokenHandle,
token, quality, userId)) {
return false;
}
setLong(PASSWORD_TYPE_KEY, quality, userId);
- updateEncryptionPasswordIfNeeded(credential, computedQuality, userId);
+ updateEncryptionPasswordIfNeeded(credential, quality, userId);
updatePasswordHistory(credential, userId);
} else {
if (!TextUtils.isEmpty(credential)) {