Wire up GateKeeper to LockSettingsService

Adds:
- Communication to GKService
- password upgrade flow
- enroll takes previous credential

Change-Id: I0161b64642be3d0e34ff4a9e6e3ca8569f2d7c0a
diff --git a/services/core/java/com/android/server/LockSettingsStorage.java b/services/core/java/com/android/server/LockSettingsStorage.java
index d81daa9..f202c36 100644
--- a/services/core/java/com/android/server/LockSettingsStorage.java
+++ b/services/core/java/com/android/server/LockSettingsStorage.java
@@ -56,8 +56,10 @@
     };
 
     private static final String SYSTEM_DIRECTORY = "/system/";
-    private static final String LOCK_PATTERN_FILE = "gesture.key";
-    private static final String LOCK_PASSWORD_FILE = "password.key";
+    private static final String 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";
 
     private static final Object DEFAULT = new Object();
 
@@ -66,6 +68,25 @@
     private final Cache mCache = new Cache();
     private final Object mFileWriteLock = new Object();
 
+    private int mStoredCredentialType;
+
+    class CredentialHash {
+        static final int TYPE_NONE = -1;
+        static final int TYPE_PATTERN = 1;
+        static final int TYPE_PASSWORD = 2;
+
+        static final int VERSION_LEGACY = 0;
+        static final int VERSION_GATEKEEPER = 1;
+
+        CredentialHash(byte[] hash, int version) {
+            this.hash = hash;
+            this.version = version;
+        }
+
+        byte[] hash;
+        int version;
+    }
+
     public LockSettingsStorage(Context context, Callback callback) {
         mContext = context;
         mOpenHelper = new DatabaseHelper(context, callback);
@@ -148,28 +169,72 @@
         readPatternHash(userId);
     }
 
-    public byte[] readPasswordHash(int userId) {
-        final byte[] stored = readFile(getLockPasswordFilename(userId));
-        if (stored != null && stored.length > 0) {
-            return stored;
+    public int getStoredCredentialType(int userId) {
+        if (mStoredCredentialType != 0) {
+            return mStoredCredentialType;
         }
+
+        CredentialHash pattern = readPatternHash(userId);
+        if (pattern == null) {
+            if (readPasswordHash(userId) != null) {
+                mStoredCredentialType = CredentialHash.TYPE_PASSWORD;
+            } else {
+                mStoredCredentialType = CredentialHash.TYPE_NONE;
+            }
+        } else {
+            CredentialHash password = readPasswordHash(userId);
+            if (password != null) {
+                // Both will never be GateKeeper
+                if (password.version == CredentialHash.VERSION_GATEKEEPER) {
+                    mStoredCredentialType = CredentialHash.TYPE_PASSWORD;
+                } else {
+                    mStoredCredentialType = CredentialHash.TYPE_PATTERN;
+                }
+            } else {
+                mStoredCredentialType = CredentialHash.TYPE_PATTERN;
+            }
+        }
+
+        return mStoredCredentialType;
+    }
+
+
+    public CredentialHash readPasswordHash(int userId) {
+        byte[] stored = readFile(getLockPasswordFilename(userId));
+        if (stored != null && stored.length > 0) {
+            return new CredentialHash(stored, CredentialHash.VERSION_GATEKEEPER);
+        }
+
+        stored = readFile(getLegacyLockPasswordFilename(userId));
+        if (stored != null && stored.length > 0) {
+            return new CredentialHash(stored, CredentialHash.VERSION_LEGACY);
+        }
+
         return null;
     }
 
-    public byte[] readPatternHash(int userId) {
-        final byte[] stored = readFile(getLockPatternFilename(userId));
+    public CredentialHash readPatternHash(int userId) {
+        byte[] stored = readFile(getLockPatternFilename(userId));
         if (stored != null && stored.length > 0) {
-            return stored;
+            return new CredentialHash(stored, CredentialHash.VERSION_GATEKEEPER);
         }
+
+        stored = readFile(getLegacyLockPatternFilename(userId));
+        if (stored != null && stored.length > 0) {
+            return new CredentialHash(stored, CredentialHash.VERSION_LEGACY);
+        }
+
         return null;
     }
 
     public boolean hasPassword(int userId) {
-        return hasFile(getLockPasswordFilename(userId));
+        return hasFile(getLockPasswordFilename(userId)) ||
+            hasFile(getLegacyLockPasswordFilename(userId));
     }
 
     public boolean hasPattern(int userId) {
-        return hasFile(getLockPatternFilename(userId));
+        return hasFile(getLockPatternFilename(userId)) ||
+            hasFile(getLegacyLockPatternFilename(userId));
     }
 
     private boolean hasFile(String name) {
@@ -237,6 +302,9 @@
     }
 
     public void writePatternHash(byte[] hash, int userId) {
+        mStoredCredentialType = hash == null
+            ? CredentialHash.TYPE_NONE
+            : CredentialHash.TYPE_PATTERN;
         writeFile(getLockPatternFilename(userId), hash);
         clearPasswordHash(userId);
     }
@@ -246,6 +314,9 @@
     }
 
     public void writePasswordHash(byte[] hash, int userId) {
+        mStoredCredentialType = hash == null
+            ? CredentialHash.TYPE_NONE
+            : CredentialHash.TYPE_PASSWORD;
         writeFile(getLockPasswordFilename(userId), hash);
         clearPatternHash(userId);
     }
@@ -264,6 +335,16 @@
         return getLockCredentialFilePathForUser(userId, LOCK_PASSWORD_FILE);
     }
 
+    @VisibleForTesting
+    String getLegacyLockPatternFilename(int userId) {
+        return getLockCredentialFilePathForUser(userId, LEGACY_LOCK_PATTERN_FILE);
+    }
+
+    @VisibleForTesting
+    String getLegacyLockPasswordFilename(int userId) {
+        return getLockCredentialFilePathForUser(userId, LEGACY_LOCK_PASSWORD_FILE);
+    }
+
     private String getLockCredentialFilePathForUser(int userId, String basename) {
         userId = getUserParentOrSelfId(userId);
         String dataSystemDirectory =