From 4978d1ad10293900e9b5feea349abd09ceb6e710 Mon Sep 17 00:00:00 2001 From: Bin Wang Date: Mon, 30 May 2022 16:09:42 +0800 Subject: [PATCH] use SharedPreferences to save verify results If an app declares too much hosts for App Link, Statementservice will crash since it uses Data class of WorkManager to save verify result for all hosts while Data throws IllegalStateException if it occupies more than 10240 bytes when serialized. This fix uses SharedPreferences to save verify results instead of Data class of WorkManager. Test:Disable GMS core and reboot device, then install Google Map; Statementservice does not crash and framework receives host verify results from Statementservice Signed-off-by: Bin Wang Change-Id: I6d1b19fd8ed3158a621a2fb0089d92430482fd61 --- .../domain/DomainVerificationReceiverV1.kt | 4 +++ .../domain/worker/CollectV1Worker.kt | 31 ++++++++++++++++--- .../domain/worker/SingleV1RequestWorker.kt | 22 +++++++------ 3 files changed, 42 insertions(+), 15 deletions(-) diff --git a/packages/StatementService/src/com/android/statementservice/domain/DomainVerificationReceiverV1.kt b/packages/StatementService/src/com/android/statementservice/domain/DomainVerificationReceiverV1.kt index 0ec8ed3416b8..acb54f6093de 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 @@ class DomainVerificationReceiverV1 : BaseDomainVerificationReceiver() { } } + //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 3a3aea9288cd..36c81722b5d9 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 @@ class CollectV1Worker(appContext: Context, params: WorkerParameters) : 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 @@ class CollectV1Worker(appContext: Context, params: WorkerParameters) : 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 @@ class CollectV1Worker(appContext: Context, params: WorkerParameters) : val verificationId = inputData.getInt(VERIFICATION_ID_KEY, -1) val successfulHosts = mutableListOf() val failedHosts = mutableListOf() - 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 @@ class CollectV1Worker(appContext: Context, params: WorkerParameters) : } 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 @@ class CollectV1Worker(appContext: Context, params: WorkerParameters) : 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 cd8a18218004..7a198cb59ca4 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 @@ class SingleV1RequestWorker(appContext: Context, params: WorkerParameters) : // 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 } }