Loading core/java/android/app/admin/DevicePolicyManager.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -2533,7 +2533,7 @@ public class DevicePolicyManager { * @return Returns true if the password meets the current requirements, else false. * @return Returns true if the password meets the current requirements, else false. * @throws SecurityException if the calling application does not own an active administrator * @throws SecurityException if the calling application does not own an active administrator * that uses {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} * 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() { public boolean isActivePasswordSufficient() { if (mService != null) { if (mService != null) { Loading core/java/android/app/admin/PasswordMetrics.java +17 −3 Original line number Original line Diff line number Diff line Loading @@ -18,13 +18,11 @@ package android.app.admin; import android.annotation.IntDef; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.NonNull; import android.app.admin.DevicePolicyManager; import android.os.Parcelable; import android.os.Parcel; import android.os.Parcel; import android.os.Parcelable; import java.lang.annotation.Retention; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; 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 * A class that represents the metrics of a password that are used to decide whether or not a Loading Loading @@ -159,6 +157,22 @@ public class PasswordMetrics implements Parcelable { quality, length, letters, upperCase, lowerCase, numeric, symbols, nonLetter); 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 * 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. * monotonically increasing characters with a constant interval or the same character repeated. Loading core/java/com/android/internal/widget/LockPatternUtils.java +39 −10 Original line number Original line Diff line number Diff line Loading @@ -803,12 +803,14 @@ public class LockPatternUtils { + "of length " + MIN_LOCK_PASSWORD_SIZE); + "of length " + MIN_LOCK_PASSWORD_SIZE); } } final int computedQuality = PasswordMetrics.computeForPassword(password).quality; setLong(PASSWORD_TYPE_KEY, setLong(PASSWORD_TYPE_KEY, Math.max(requestedQuality, computedQuality), userHandle); computePasswordQuality(CREDENTIAL_TYPE_PASSWORD, password, requestedQuality), userHandle); getLockSettings().setLockCredential(password, CREDENTIAL_TYPE_PASSWORD, savedPassword, getLockSettings().setLockCredential(password, CREDENTIAL_TYPE_PASSWORD, savedPassword, requestedQuality, userHandle); requestedQuality, userHandle); updateEncryptionPasswordIfNeeded(password, computedQuality, userHandle); updateEncryptionPasswordIfNeeded(password, PasswordMetrics.computeForPassword(password).quality, userHandle); updatePasswordHistory(password, userHandle); updatePasswordHistory(password, userHandle); } catch (RemoteException re) { } catch (RemoteException re) { // Cant do much // Cant do much Loading Loading @@ -897,6 +899,24 @@ public class LockPatternUtils { DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userHandle); DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userHandle); } } /** * 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 * 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. * for user handles that do not belong to a managed profile. Loading Loading @@ -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 { try { if (type != CREDENTIAL_TYPE_NONE) { if (type != CREDENTIAL_TYPE_NONE) { if (TextUtils.isEmpty(credential) || credential.length() < MIN_LOCK_PASSWORD_SIZE) { if (TextUtils.isEmpty(credential) || credential.length() < MIN_LOCK_PASSWORD_SIZE) { throw new IllegalArgumentException("password must not be null and at least " throw new IllegalArgumentException("password must not be null and at least " + "of length " + MIN_LOCK_PASSWORD_SIZE); + "of length " + MIN_LOCK_PASSWORD_SIZE); } } final int quality = computePasswordQuality(type, credential, requestedQuality); final int computedQuality = PasswordMetrics.computeForPassword(credential).quality; int quality = Math.max(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC, computedQuality); if (!getLockSettings().setLockCredentialWithToken(credential, type, tokenHandle, if (!getLockSettings().setLockCredentialWithToken(credential, type, tokenHandle, token, quality, userId)) { token, quality, userId)) { return false; return false; } } setLong(PASSWORD_TYPE_KEY, quality, userId); setLong(PASSWORD_TYPE_KEY, quality, userId); updateEncryptionPasswordIfNeeded(credential, computedQuality, userId); updateEncryptionPasswordIfNeeded(credential, quality, userId); updatePasswordHistory(credential, userId); updatePasswordHistory(credential, userId); } else { } else { if (!TextUtils.isEmpty(credential)) { if (!TextUtils.isEmpty(credential)) { Loading core/tests/coretests/src/android/app/admin/PasswordMetricsTest.java +45 −0 Original line number Original line Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.app.admin; package android.app.admin; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import android.os.Parcel; import android.os.Parcel; import android.support.test.filters.SmallTest; import android.support.test.filters.SmallTest; Loading Loading @@ -119,4 +120,48 @@ public class PasswordMetricsTest { // ordered, but not composed of alphas or digits // ordered, but not composed of alphas or digits assertEquals(1, PasswordMetrics.maxLengthSequence(":;<=>")); assertEquals(1, PasswordMetrics.maxLengthSequence(":;<=>")); } } @Test public void testEquals() { PasswordMetrics metrics0 = new PasswordMetrics(); PasswordMetrics metrics1 = new PasswordMetrics(); assertNotEquals(metrics0, null); assertNotEquals(metrics0, new Object()); assertEquals(metrics0, metrics0); assertEquals(metrics0, metrics1); assertEquals(new PasswordMetrics(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, 4), new PasswordMetrics(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, 4)); assertNotEquals(new PasswordMetrics(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, 4), new PasswordMetrics(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, 5)); assertNotEquals(new PasswordMetrics(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, 4), new PasswordMetrics(DevicePolicyManager.PASSWORD_QUALITY_COMPLEX, 4)); metrics0 = PasswordMetrics.computeForPassword("1234abcd,./"); metrics1 = PasswordMetrics.computeForPassword("1234abcd,./"); assertEquals(metrics0, metrics1); metrics1.letters++; assertNotEquals(metrics0, metrics1); metrics1.letters--; metrics1.upperCase++; assertNotEquals(metrics0, metrics1); metrics1.upperCase--; metrics1.lowerCase++; assertNotEquals(metrics0, metrics1); metrics1.lowerCase--; metrics1.numeric++; assertNotEquals(metrics0, metrics1); metrics1.numeric--; metrics1.symbols++; assertNotEquals(metrics0, metrics1); metrics1.symbols--; metrics1.nonLetter++; assertNotEquals(metrics0, metrics1); metrics1.nonLetter--; assertEquals(metrics0, metrics1); } } } services/core/java/com/android/server/locksettings/LockSettingsService.java +14 −3 Original line number Original line Diff line number Diff line Loading @@ -154,7 +154,8 @@ public class LockSettingsService extends ILockSettings.Stub { private final Injector mInjector; private final Injector mInjector; private final Context mContext; private final Context mContext; private final Handler mHandler; @VisibleForTesting protected final Handler mHandler; @VisibleForTesting @VisibleForTesting protected final LockSettingsStorage mStorage; protected final LockSettingsStorage mStorage; private final LockSettingsStrongAuth mStrongAuth; private final LockSettingsStrongAuth mStrongAuth; Loading Loading @@ -1736,6 +1737,10 @@ public class LockSettingsService extends ILockSettings.Stub { return response; return response; } } /** * Call this method to notify DPMS regarding the latest password metric. This should be called * when the user is authenticating or when a new password is being set. */ private void notifyActivePasswordMetricsAvailable(String password, @UserIdInt int userId) { private void notifyActivePasswordMetricsAvailable(String password, @UserIdInt int userId) { final PasswordMetrics metrics; final PasswordMetrics metrics; if (password == null) { if (password == null) { Loading Loading @@ -2197,6 +2202,8 @@ public class LockSettingsService extends ILockSettings.Stub { } } setLong(SYNTHETIC_PASSWORD_HANDLE_KEY, newHandle, userId); setLong(SYNTHETIC_PASSWORD_HANDLE_KEY, newHandle, userId); synchronizeUnifiedWorkChallengeForProfiles(userId, profilePasswords); synchronizeUnifiedWorkChallengeForProfiles(userId, profilePasswords); notifyActivePasswordMetricsAvailable(credential, userId); return newHandle; return newHandle; } } Loading Loading @@ -2246,13 +2253,13 @@ public class LockSettingsService extends ILockSettings.Stub { userId); userId); synchronizeUnifiedWorkChallengeForProfiles(userId, null); synchronizeUnifiedWorkChallengeForProfiles(userId, null); mSpManager.destroyPasswordBasedSyntheticPassword(handle, userId); mSpManager.destroyPasswordBasedSyntheticPassword(handle, userId); notifyActivePasswordMetricsAvailable(credential, userId); } else /* response == null || responseCode == VerifyCredentialResponse.RESPONSE_RETRY */ { } else /* response == null || responseCode == VerifyCredentialResponse.RESPONSE_RETRY */ { Slog.w(TAG, "spBasedSetLockCredentialInternalLocked: " + Slog.w(TAG, "spBasedSetLockCredentialInternalLocked: " + (response != null ? "rate limit exceeded" : "failed")); (response != null ? "rate limit exceeded" : "failed")); return; return; } } notifyActivePasswordMetricsAvailable(credential, userId); } } @Override @Override Loading Loading @@ -2358,6 +2365,10 @@ public class LockSettingsService extends ILockSettings.Stub { Slog.w(TAG, "Invalid escrow token supplied"); Slog.w(TAG, "Invalid escrow token supplied"); return false; return false; } } // Update PASSWORD_TYPE_KEY since it's needed by notifyActivePasswordMetricsAvailable() // called by setLockCredentialWithAuthTokenLocked(). // TODO: refactor usage of PASSWORD_TYPE_KEY b/65239740 setLong(LockPatternUtils.PASSWORD_TYPE_KEY, requestedQuality, userId); long oldHandle = getSyntheticPasswordHandleLocked(userId); long oldHandle = getSyntheticPasswordHandleLocked(userId); setLockCredentialWithAuthTokenLocked(credential, type, result.authToken, setLockCredentialWithAuthTokenLocked(credential, type, result.authToken, requestedQuality, userId); requestedQuality, userId); Loading Loading
core/java/android/app/admin/DevicePolicyManager.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -2533,7 +2533,7 @@ public class DevicePolicyManager { * @return Returns true if the password meets the current requirements, else false. * @return Returns true if the password meets the current requirements, else false. * @throws SecurityException if the calling application does not own an active administrator * @throws SecurityException if the calling application does not own an active administrator * that uses {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} * 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() { public boolean isActivePasswordSufficient() { if (mService != null) { if (mService != null) { Loading
core/java/android/app/admin/PasswordMetrics.java +17 −3 Original line number Original line Diff line number Diff line Loading @@ -18,13 +18,11 @@ package android.app.admin; import android.annotation.IntDef; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.NonNull; import android.app.admin.DevicePolicyManager; import android.os.Parcelable; import android.os.Parcel; import android.os.Parcel; import android.os.Parcelable; import java.lang.annotation.Retention; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; 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 * A class that represents the metrics of a password that are used to decide whether or not a Loading Loading @@ -159,6 +157,22 @@ public class PasswordMetrics implements Parcelable { quality, length, letters, upperCase, lowerCase, numeric, symbols, nonLetter); 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 * 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. * monotonically increasing characters with a constant interval or the same character repeated. Loading
core/java/com/android/internal/widget/LockPatternUtils.java +39 −10 Original line number Original line Diff line number Diff line Loading @@ -803,12 +803,14 @@ public class LockPatternUtils { + "of length " + MIN_LOCK_PASSWORD_SIZE); + "of length " + MIN_LOCK_PASSWORD_SIZE); } } final int computedQuality = PasswordMetrics.computeForPassword(password).quality; setLong(PASSWORD_TYPE_KEY, setLong(PASSWORD_TYPE_KEY, Math.max(requestedQuality, computedQuality), userHandle); computePasswordQuality(CREDENTIAL_TYPE_PASSWORD, password, requestedQuality), userHandle); getLockSettings().setLockCredential(password, CREDENTIAL_TYPE_PASSWORD, savedPassword, getLockSettings().setLockCredential(password, CREDENTIAL_TYPE_PASSWORD, savedPassword, requestedQuality, userHandle); requestedQuality, userHandle); updateEncryptionPasswordIfNeeded(password, computedQuality, userHandle); updateEncryptionPasswordIfNeeded(password, PasswordMetrics.computeForPassword(password).quality, userHandle); updatePasswordHistory(password, userHandle); updatePasswordHistory(password, userHandle); } catch (RemoteException re) { } catch (RemoteException re) { // Cant do much // Cant do much Loading Loading @@ -897,6 +899,24 @@ public class LockPatternUtils { DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userHandle); DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userHandle); } } /** * 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 * 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. * for user handles that do not belong to a managed profile. Loading Loading @@ -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 { try { if (type != CREDENTIAL_TYPE_NONE) { if (type != CREDENTIAL_TYPE_NONE) { if (TextUtils.isEmpty(credential) || credential.length() < MIN_LOCK_PASSWORD_SIZE) { if (TextUtils.isEmpty(credential) || credential.length() < MIN_LOCK_PASSWORD_SIZE) { throw new IllegalArgumentException("password must not be null and at least " throw new IllegalArgumentException("password must not be null and at least " + "of length " + MIN_LOCK_PASSWORD_SIZE); + "of length " + MIN_LOCK_PASSWORD_SIZE); } } final int quality = computePasswordQuality(type, credential, requestedQuality); final int computedQuality = PasswordMetrics.computeForPassword(credential).quality; int quality = Math.max(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC, computedQuality); if (!getLockSettings().setLockCredentialWithToken(credential, type, tokenHandle, if (!getLockSettings().setLockCredentialWithToken(credential, type, tokenHandle, token, quality, userId)) { token, quality, userId)) { return false; return false; } } setLong(PASSWORD_TYPE_KEY, quality, userId); setLong(PASSWORD_TYPE_KEY, quality, userId); updateEncryptionPasswordIfNeeded(credential, computedQuality, userId); updateEncryptionPasswordIfNeeded(credential, quality, userId); updatePasswordHistory(credential, userId); updatePasswordHistory(credential, userId); } else { } else { if (!TextUtils.isEmpty(credential)) { if (!TextUtils.isEmpty(credential)) { Loading
core/tests/coretests/src/android/app/admin/PasswordMetricsTest.java +45 −0 Original line number Original line Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.app.admin; package android.app.admin; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import android.os.Parcel; import android.os.Parcel; import android.support.test.filters.SmallTest; import android.support.test.filters.SmallTest; Loading Loading @@ -119,4 +120,48 @@ public class PasswordMetricsTest { // ordered, but not composed of alphas or digits // ordered, but not composed of alphas or digits assertEquals(1, PasswordMetrics.maxLengthSequence(":;<=>")); assertEquals(1, PasswordMetrics.maxLengthSequence(":;<=>")); } } @Test public void testEquals() { PasswordMetrics metrics0 = new PasswordMetrics(); PasswordMetrics metrics1 = new PasswordMetrics(); assertNotEquals(metrics0, null); assertNotEquals(metrics0, new Object()); assertEquals(metrics0, metrics0); assertEquals(metrics0, metrics1); assertEquals(new PasswordMetrics(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, 4), new PasswordMetrics(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, 4)); assertNotEquals(new PasswordMetrics(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, 4), new PasswordMetrics(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, 5)); assertNotEquals(new PasswordMetrics(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, 4), new PasswordMetrics(DevicePolicyManager.PASSWORD_QUALITY_COMPLEX, 4)); metrics0 = PasswordMetrics.computeForPassword("1234abcd,./"); metrics1 = PasswordMetrics.computeForPassword("1234abcd,./"); assertEquals(metrics0, metrics1); metrics1.letters++; assertNotEquals(metrics0, metrics1); metrics1.letters--; metrics1.upperCase++; assertNotEquals(metrics0, metrics1); metrics1.upperCase--; metrics1.lowerCase++; assertNotEquals(metrics0, metrics1); metrics1.lowerCase--; metrics1.numeric++; assertNotEquals(metrics0, metrics1); metrics1.numeric--; metrics1.symbols++; assertNotEquals(metrics0, metrics1); metrics1.symbols--; metrics1.nonLetter++; assertNotEquals(metrics0, metrics1); metrics1.nonLetter--; assertEquals(metrics0, metrics1); } } }
services/core/java/com/android/server/locksettings/LockSettingsService.java +14 −3 Original line number Original line Diff line number Diff line Loading @@ -154,7 +154,8 @@ public class LockSettingsService extends ILockSettings.Stub { private final Injector mInjector; private final Injector mInjector; private final Context mContext; private final Context mContext; private final Handler mHandler; @VisibleForTesting protected final Handler mHandler; @VisibleForTesting @VisibleForTesting protected final LockSettingsStorage mStorage; protected final LockSettingsStorage mStorage; private final LockSettingsStrongAuth mStrongAuth; private final LockSettingsStrongAuth mStrongAuth; Loading Loading @@ -1736,6 +1737,10 @@ public class LockSettingsService extends ILockSettings.Stub { return response; return response; } } /** * Call this method to notify DPMS regarding the latest password metric. This should be called * when the user is authenticating or when a new password is being set. */ private void notifyActivePasswordMetricsAvailable(String password, @UserIdInt int userId) { private void notifyActivePasswordMetricsAvailable(String password, @UserIdInt int userId) { final PasswordMetrics metrics; final PasswordMetrics metrics; if (password == null) { if (password == null) { Loading Loading @@ -2197,6 +2202,8 @@ public class LockSettingsService extends ILockSettings.Stub { } } setLong(SYNTHETIC_PASSWORD_HANDLE_KEY, newHandle, userId); setLong(SYNTHETIC_PASSWORD_HANDLE_KEY, newHandle, userId); synchronizeUnifiedWorkChallengeForProfiles(userId, profilePasswords); synchronizeUnifiedWorkChallengeForProfiles(userId, profilePasswords); notifyActivePasswordMetricsAvailable(credential, userId); return newHandle; return newHandle; } } Loading Loading @@ -2246,13 +2253,13 @@ public class LockSettingsService extends ILockSettings.Stub { userId); userId); synchronizeUnifiedWorkChallengeForProfiles(userId, null); synchronizeUnifiedWorkChallengeForProfiles(userId, null); mSpManager.destroyPasswordBasedSyntheticPassword(handle, userId); mSpManager.destroyPasswordBasedSyntheticPassword(handle, userId); notifyActivePasswordMetricsAvailable(credential, userId); } else /* response == null || responseCode == VerifyCredentialResponse.RESPONSE_RETRY */ { } else /* response == null || responseCode == VerifyCredentialResponse.RESPONSE_RETRY */ { Slog.w(TAG, "spBasedSetLockCredentialInternalLocked: " + Slog.w(TAG, "spBasedSetLockCredentialInternalLocked: " + (response != null ? "rate limit exceeded" : "failed")); (response != null ? "rate limit exceeded" : "failed")); return; return; } } notifyActivePasswordMetricsAvailable(credential, userId); } } @Override @Override Loading Loading @@ -2358,6 +2365,10 @@ public class LockSettingsService extends ILockSettings.Stub { Slog.w(TAG, "Invalid escrow token supplied"); Slog.w(TAG, "Invalid escrow token supplied"); return false; return false; } } // Update PASSWORD_TYPE_KEY since it's needed by notifyActivePasswordMetricsAvailable() // called by setLockCredentialWithAuthTokenLocked(). // TODO: refactor usage of PASSWORD_TYPE_KEY b/65239740 setLong(LockPatternUtils.PASSWORD_TYPE_KEY, requestedQuality, userId); long oldHandle = getSyntheticPasswordHandleLocked(userId); long oldHandle = getSyntheticPasswordHandleLocked(userId); setLockCredentialWithAuthTokenLocked(credential, type, result.authToken, setLockCredentialWithAuthTokenLocked(credential, type, result.authToken, requestedQuality, userId); requestedQuality, userId); Loading