Merge "SyntheticPasswordManager: consolidate hex encoding logic"
diff --git a/packages/StatementService/src/com/android/statementservice/domain/DomainVerificationReceiverV1.kt b/packages/StatementService/src/com/android/statementservice/domain/DomainVerificationReceiverV1.kt
index 0ec8ed3..acb54f6 100644
--- a/packages/StatementService/src/com/android/statementservice/domain/DomainVerificationReceiverV1.kt
+++ b/packages/StatementService/src/com/android/statementservice/domain/DomainVerificationReceiverV1.kt
@@ -67,6 +67,10 @@
             }
         }
 
+        //clear sp before enqueue unique work since policy is REPLACE
+        val deContext = context.createDeviceProtectedStorageContext()
+        val editor = deContext?.getSharedPreferences(packageName, Context.MODE_PRIVATE)?.edit()
+        editor?.clear()?.apply()
         WorkManager.getInstance(context)
             .beginUniqueWork(
                 "$PACKAGE_WORK_PREFIX_V1$packageName",
diff --git a/packages/StatementService/src/com/android/statementservice/domain/worker/CollectV1Worker.kt b/packages/StatementService/src/com/android/statementservice/domain/worker/CollectV1Worker.kt
index 3a3aea9..36c81722 100644
--- a/packages/StatementService/src/com/android/statementservice/domain/worker/CollectV1Worker.kt
+++ b/packages/StatementService/src/com/android/statementservice/domain/worker/CollectV1Worker.kt
@@ -41,9 +41,7 @@
                     Data.Builder()
                         .putInt(VERIFICATION_ID_KEY, verificationId)
                         .apply {
-                            if (DEBUG) {
-                                putString(PACKAGE_NAME_KEY, packageName)
-                            }
+                            putString(PACKAGE_NAME_KEY, packageName)
                         }
                         .build()
                 )
@@ -52,6 +50,18 @@
 
     override suspend fun doWork() = coroutineScope {
         if (!AndroidUtils.isReceiverV1Enabled(appContext)) {
+            //clear sp and commit here
+            val inputData = params.inputData
+            val packageName = inputData.getString(PACKAGE_NAME_KEY)
+            val deContext = appContext.createDeviceProtectedStorageContext()
+            val sp = deContext?.getSharedPreferences(packageName, Context.MODE_PRIVATE)
+            val editor = sp?.edit()
+            editor?.clear()?.commit()
+            //delete sp file
+            val retOfDel = deContext?.deleteSharedPreferences(packageName)
+            if (DEBUG) {
+                Log.d(TAG, "delete sp for $packageName return $retOfDel")
+            }
             return@coroutineScope Result.success()
         }
 
@@ -59,7 +69,10 @@
         val verificationId = inputData.getInt(VERIFICATION_ID_KEY, -1)
         val successfulHosts = mutableListOf<String>()
         val failedHosts = mutableListOf<String>()
-        inputData.keyValueMap.entries.forEach { (key, _) ->
+        val packageName = inputData.getString(PACKAGE_NAME_KEY)
+        val deContext = appContext.createDeviceProtectedStorageContext()
+        val sp = deContext?.getSharedPreferences(packageName, Context.MODE_PRIVATE)
+        sp?.all?.entries?.forEach { (key, _) ->
             when {
                 key.startsWith(SingleV1RequestWorker.HOST_SUCCESS_PREFIX) ->
                     successfulHosts += key.removePrefix(SingleV1RequestWorker.HOST_SUCCESS_PREFIX)
@@ -69,7 +82,6 @@
         }
 
         if (DEBUG) {
-            val packageName = inputData.getString(PACKAGE_NAME_KEY)
             Log.d(
                 TAG, "Domain verification v1 request for $packageName: " +
                         "success = $successfulHosts, failed = $failedHosts"
@@ -84,6 +96,15 @@
 
         appContext.packageManager.verifyIntentFilter(verificationId, resultCode, failedHosts)
 
+        //clear sp and commit here
+        val editor = sp?.edit()
+        editor?.clear()?.commit()
+        //delete sp file
+        val retOfDel = deContext?.deleteSharedPreferences(packageName)
+        if (DEBUG) {
+            Log.d(TAG, "delete sp for $packageName return $retOfDel")
+        }
+
         Result.success()
     }
 }
diff --git a/packages/StatementService/src/com/android/statementservice/domain/worker/SingleV1RequestWorker.kt b/packages/StatementService/src/com/android/statementservice/domain/worker/SingleV1RequestWorker.kt
index cd8a182..7a198cb 100644
--- a/packages/StatementService/src/com/android/statementservice/domain/worker/SingleV1RequestWorker.kt
+++ b/packages/StatementService/src/com/android/statementservice/domain/worker/SingleV1RequestWorker.kt
@@ -71,16 +71,18 @@
 
         // Coerce failure results into success so that final collection task gets a chance to run
         when (result) {
-            is Result.Success -> Result.success(
-                Data.Builder()
-                    .putInt("$HOST_SUCCESS_PREFIX$host", status.value)
-                    .build()
-            )
-            is Result.Failure -> Result.success(
-                Data.Builder()
-                    .putInt("$HOST_FAILURE_PREFIX$host", status.value)
-                    .build()
-            )
+            is Result.Success -> {
+                val deContext = appContext.createDeviceProtectedStorageContext()
+                val sp = deContext?.getSharedPreferences(packageName, Context.MODE_PRIVATE)
+                sp?.edit()?.putInt("$HOST_SUCCESS_PREFIX$host", status.value)?.apply()
+                Result.success()
+            }
+            is Result.Failure -> {
+                val deContext = appContext.createDeviceProtectedStorageContext()
+                val sp = deContext?.getSharedPreferences(packageName, Context.MODE_PRIVATE)
+                sp?.edit()?.putInt("$HOST_FAILURE_PREFIX$host", status.value)?.apply()
+                Result.success()
+            }
             else -> result
         }
     }
diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
index 5fdfe19..4631570 100644
--- a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
+++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
@@ -116,9 +116,9 @@
     // 256-bit synthetic password
     private static final byte SYNTHETIC_PASSWORD_LENGTH = 256 / 8;
 
-    private static final int PASSWORD_SCRYPT_N = 11;
-    private static final int PASSWORD_SCRYPT_R = 3;
-    private static final int PASSWORD_SCRYPT_P = 1;
+    private static final int PASSWORD_SCRYPT_LOG_N = 11;
+    private static final int PASSWORD_SCRYPT_LOG_R = 3;
+    private static final int PASSWORD_SCRYPT_LOG_P = 1;
     private static final int PASSWORD_SALT_LENGTH = 16;
     private static final int PASSWORD_TOKEN_LENGTH = 32;
     private static final String TAG = "SyntheticPasswordManager";
@@ -307,9 +307,9 @@
     }
 
     static class PasswordData {
-        byte scryptN;
-        byte scryptR;
-        byte scryptP;
+        byte scryptLogN;
+        byte scryptLogR;
+        byte scryptLogP;
         public int credentialType;
         byte[] salt;
         // For GateKeeper-based credential, this is the password handle returned by GK,
@@ -318,9 +318,9 @@
 
         public static PasswordData create(int passwordType) {
             PasswordData result = new PasswordData();
-            result.scryptN = PASSWORD_SCRYPT_N;
-            result.scryptR = PASSWORD_SCRYPT_R;
-            result.scryptP = PASSWORD_SCRYPT_P;
+            result.scryptLogN = PASSWORD_SCRYPT_LOG_N;
+            result.scryptLogR = PASSWORD_SCRYPT_LOG_R;
+            result.scryptLogP = PASSWORD_SCRYPT_LOG_P;
             result.credentialType = passwordType;
             result.salt = secureRandom(PASSWORD_SALT_LENGTH);
             return result;
@@ -332,9 +332,9 @@
             buffer.put(data, 0, data.length);
             buffer.flip();
             result.credentialType = buffer.getInt();
-            result.scryptN = buffer.get();
-            result.scryptR = buffer.get();
-            result.scryptP = buffer.get();
+            result.scryptLogN = buffer.get();
+            result.scryptLogR = buffer.get();
+            result.scryptLogP = buffer.get();
             int saltLen = buffer.getInt();
             result.salt = new byte[saltLen];
             buffer.get(result.salt);
@@ -354,9 +354,9 @@
                     + Integer.BYTES + salt.length + Integer.BYTES +
                     (passwordHandle != null ? passwordHandle.length : 0));
             buffer.putInt(credentialType);
-            buffer.put(scryptN);
-            buffer.put(scryptR);
-            buffer.put(scryptP);
+            buffer.put(scryptLogN);
+            buffer.put(scryptLogR);
+            buffer.put(scryptLogP);
             buffer.putInt(salt.length);
             buffer.put(salt);
             if (passwordHandle != null && passwordHandle.length > 0) {
@@ -1372,8 +1372,8 @@
 
     private byte[] computePasswordToken(LockscreenCredential credential, PasswordData data) {
         final byte[] password = credential.isNone() ? DEFAULT_PASSWORD : credential.getCredential();
-        return scrypt(password, data.salt, 1 << data.scryptN, 1 << data.scryptR, 1 << data.scryptP,
-                PASSWORD_TOKEN_LENGTH);
+        return scrypt(password, data.salt, 1 << data.scryptLogN, 1 << data.scryptLogR,
+                1 << data.scryptLogP, PASSWORD_TOKEN_LENGTH);
     }
 
     private byte[] passwordTokenToGkInput(byte[] token) {
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
index b5eea70..09d3b48 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
@@ -461,18 +461,18 @@
     @Test
     public void testPasswordData_serializeDeserialize() {
         PasswordData data = new PasswordData();
-        data.scryptN = 11;
-        data.scryptR = 22;
-        data.scryptP = 33;
+        data.scryptLogN = 11;
+        data.scryptLogR = 22;
+        data.scryptLogP = 33;
         data.credentialType = CREDENTIAL_TYPE_PASSWORD;
         data.salt = PAYLOAD;
         data.passwordHandle = PAYLOAD2;
 
         PasswordData deserialized = PasswordData.fromBytes(data.toBytes());
 
-        assertEquals(11, deserialized.scryptN);
-        assertEquals(22, deserialized.scryptR);
-        assertEquals(33, deserialized.scryptP);
+        assertEquals(11, deserialized.scryptLogN);
+        assertEquals(22, deserialized.scryptLogR);
+        assertEquals(33, deserialized.scryptLogP);
         assertEquals(CREDENTIAL_TYPE_PASSWORD, deserialized.credentialType);
         assertArrayEquals(PAYLOAD, deserialized.salt);
         assertArrayEquals(PAYLOAD2, deserialized.passwordHandle);
@@ -484,9 +484,9 @@
         // wire format.
         byte[] serialized = new byte[] {
                 0, 0, 0, 2, /* CREDENTIAL_TYPE_PASSWORD_OR_PIN */
-                11, /* scryptN */
-                22, /* scryptR */
-                33, /* scryptP */
+                11, /* scryptLogN */
+                22, /* scryptLogR */
+                33, /* scryptLogP */
                 0, 0, 0, 5, /* salt.length */
                 1, 2, -1, -2, 55, /* salt */
                 0, 0, 0, 6, /* passwordHandle.length */
@@ -494,9 +494,9 @@
         };
         PasswordData deserialized = PasswordData.fromBytes(serialized);
 
-        assertEquals(11, deserialized.scryptN);
-        assertEquals(22, deserialized.scryptR);
-        assertEquals(33, deserialized.scryptP);
+        assertEquals(11, deserialized.scryptLogN);
+        assertEquals(22, deserialized.scryptLogR);
+        assertEquals(33, deserialized.scryptLogP);
         assertEquals(CREDENTIAL_TYPE_PASSWORD_OR_PIN, deserialized.credentialType);
         assertArrayEquals(PAYLOAD, deserialized.salt);
         assertArrayEquals(PAYLOAD2, deserialized.passwordHandle);