diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index aee0ff6292280..86d11be78b0ac 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -841,7 +841,7 @@ public class LockPatternUtils { final byte[] bytes = string.getBytes(); for (int i = 0; i < bytes.length; i++) { - byte b = bytes[i]; + byte b = (byte) (bytes[i] - '1'); result.add(LockPatternView.Cell.of(b / 3, b % 3)); } return result; @@ -861,7 +861,21 @@ public class LockPatternUtils { byte[] res = new byte[patternSize]; for (int i = 0; i < patternSize; i++) { LockPatternView.Cell cell = pattern.get(i); - res[i] = (byte) (cell.getRow() * 3 + cell.getColumn()); + res[i] = (byte) (cell.getRow() * 3 + cell.getColumn() + '1'); + } + return new String(res); + } + + public static String patternStringToBaseZero(String pattern) { + if (pattern == null) { + return ""; + } + final int patternSize = pattern.length(); + + byte[] res = new byte[patternSize]; + final byte[] bytes = pattern.getBytes(); + for (int i = 0; i < patternSize; i++) { + res[i] = (byte) (bytes[i] - '1'); } return new String(res); } diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java index f6ca0d7ac44b3..5436ce020abcf 100644 --- a/services/core/java/com/android/server/LockSettingsService.java +++ b/services/core/java/com/android/server/LockSettingsService.java @@ -502,12 +502,21 @@ public class LockSettingsService extends ILockSettings.Stub { return doVerifyPattern(pattern, true, challenge, userId); } - private VerifyCredentialResponse doVerifyPattern(String pattern, boolean hasChallenge, long challenge, - int userId) throws RemoteException { + private VerifyCredentialResponse doVerifyPattern(String pattern, boolean hasChallenge, + long challenge, int userId) throws RemoteException { checkPasswordReadPermission(userId); CredentialHash storedHash = mStorage.readPatternHash(userId); - return verifyCredential(userId, storedHash, pattern, hasChallenge, - challenge, + boolean shouldReEnrollBaseZero = storedHash != null && storedHash.isBaseZeroPattern; + + String patternToVerify; + if (shouldReEnrollBaseZero) { + patternToVerify = LockPatternUtils.patternStringToBaseZero(pattern); + } else { + patternToVerify = pattern; + } + + VerifyCredentialResponse response = verifyCredential(userId, storedHash, patternToVerify, + hasChallenge, challenge, new CredentialUtil() { @Override public void setCredential(String pattern, String oldPattern, int userId) @@ -517,11 +526,19 @@ public class LockSettingsService extends ILockSettings.Stub { @Override public byte[] toHash(String pattern, int userId) { - return mLockPatternUtils.patternToHash( - mLockPatternUtils.stringToPattern(pattern)); + return LockPatternUtils.patternToHash( + LockPatternUtils.stringToPattern(pattern)); } } ); + + if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK + && shouldReEnrollBaseZero) { + setLockPattern(pattern, patternToVerify, userId); + } + + return response; + } @Override diff --git a/services/core/java/com/android/server/LockSettingsStorage.java b/services/core/java/com/android/server/LockSettingsStorage.java index f202c3657eca3..de48e714b4c55 100644 --- a/services/core/java/com/android/server/LockSettingsStorage.java +++ b/services/core/java/com/android/server/LockSettingsStorage.java @@ -56,7 +56,8 @@ class LockSettingsStorage { }; private static final String SYSTEM_DIRECTORY = "/system/"; - private static final String LOCK_PATTERN_FILE = "gatekeeper.gesture.key"; + private static final String LOCK_PATTERN_FILE = "gatekeeper.pattern.key"; + private static final String BASE_ZERO_LOCK_PATTERN_FILE = "gatekeeper.gesture.key"; private static final String LEGACY_LOCK_PATTERN_FILE = "gesture.key"; private static final String LOCK_PASSWORD_FILE = "gatekeeper.password.key"; private static final String LEGACY_LOCK_PASSWORD_FILE = "password.key"; @@ -81,10 +82,18 @@ class LockSettingsStorage { CredentialHash(byte[] hash, int version) { this.hash = hash; this.version = version; + this.isBaseZeroPattern = false; + } + + CredentialHash(byte[] hash, boolean isBaseZeroPattern) { + this.hash = hash; + this.version = VERSION_GATEKEEPER; + this.isBaseZeroPattern = isBaseZeroPattern; } byte[] hash; int version; + boolean isBaseZeroPattern; } public LockSettingsStorage(Context context, Callback callback) { @@ -219,6 +228,11 @@ class LockSettingsStorage { return new CredentialHash(stored, CredentialHash.VERSION_GATEKEEPER); } + stored = readFile(getBaseZeroLockPatternFilename(userId)); + if (stored != null && stored.length > 0) { + return new CredentialHash(stored, true); + } + stored = readFile(getLegacyLockPatternFilename(userId)); if (stored != null && stored.length > 0) { return new CredentialHash(stored, CredentialHash.VERSION_LEGACY); @@ -227,6 +241,7 @@ class LockSettingsStorage { return null; } + public boolean hasPassword(int userId) { return hasFile(getLockPasswordFilename(userId)) || hasFile(getLegacyLockPasswordFilename(userId)); @@ -234,6 +249,7 @@ class LockSettingsStorage { public boolean hasPattern(int userId) { return hasFile(getLockPatternFilename(userId)) || + hasFile(getBaseZeroLockPatternFilename(userId)) || hasFile(getLegacyLockPatternFilename(userId)); } @@ -301,6 +317,13 @@ class LockSettingsStorage { } } + private void deleteFile(String name) { + File f = new File(name); + if (f != null) { + f.delete(); + } + } + public void writePatternHash(byte[] hash, int userId) { mStoredCredentialType = hash == null ? CredentialHash.TYPE_NONE @@ -345,6 +368,10 @@ class LockSettingsStorage { return getLockCredentialFilePathForUser(userId, LEGACY_LOCK_PASSWORD_FILE); } + private String getBaseZeroLockPatternFilename(int userId) { + return getLockCredentialFilePathForUser(userId, BASE_ZERO_LOCK_PATTERN_FILE); + } + private String getLockCredentialFilePathForUser(int userId, String basename) { userId = getUserParentOrSelfId(userId); String dataSystemDirectory =