From a45d7d04d710c1bfc06fa0202a4878d5a14aa089 Mon Sep 17 00:00:00 2001 From: Filippo Galgani Date: Sun, 31 Jan 2021 20:15:42 -0800 Subject: [PATCH] New runtime flag to switch PackageMonitoringListener to use Arcs deletion propagation. Also set up a package.arcs manifest with an empty package Schema that can be used for foreign references. This is part of setting up chronicle to use the arcs automatic deletion propagation (next steps are the reconcile job and installing the foreign reference checker). PiperOrigin-RevId: 354858238 --- ...DatabaseGarbageCollectionPeriodicTaskV2.kt | 2 +- .../service/StorageServiceManagerEndpoint.kt | 85 +++--------------- .../StorageServiceManagerEndpointImpl.kt | 87 +++++++++++++++++++ .../integration/IntegrationEnvironment.kt | 6 +- ... StorageServiceManagerEndpointImplTest.kt} | 18 ++-- 5 files changed, 111 insertions(+), 87 deletions(-) create mode 100644 java/arcs/sdk/android/storage/service/StorageServiceManagerEndpointImpl.kt rename javatests/arcs/sdk/android/storage/service/{StorageServiceManagerEndpointTest.kt => StorageServiceManagerEndpointImplTest.kt} (87%) diff --git a/java/arcs/sdk/android/storage/service/DatabaseGarbageCollectionPeriodicTaskV2.kt b/java/arcs/sdk/android/storage/service/DatabaseGarbageCollectionPeriodicTaskV2.kt index 8eb1ae496f3..1ab4d1d3efc 100644 --- a/java/arcs/sdk/android/storage/service/DatabaseGarbageCollectionPeriodicTaskV2.kt +++ b/java/arcs/sdk/android/storage/service/DatabaseGarbageCollectionPeriodicTaskV2.kt @@ -48,7 +48,7 @@ class DatabaseGarbageCollectionPeriodicTaskV2( // work on any important threads that you're using elsewhere. override fun doWork(): Result = runBlocking { log.debug { "Running." } - val success = StorageServiceManagerEndpoint( + val success = StorageServiceManagerEndpointImpl( binderHelper, this, storageServiceClass.java diff --git a/java/arcs/sdk/android/storage/service/StorageServiceManagerEndpoint.kt b/java/arcs/sdk/android/storage/service/StorageServiceManagerEndpoint.kt index bf67e094d51..21c7e7bfccf 100644 --- a/java/arcs/sdk/android/storage/service/StorageServiceManagerEndpoint.kt +++ b/java/arcs/sdk/android/storage/service/StorageServiceManagerEndpoint.kt @@ -1,95 +1,32 @@ package arcs.sdk.android.storage.service -import arcs.android.storage.service.IHardReferencesRemovalCallback -import arcs.android.storage.service.IResultCallback -import arcs.android.storage.service.IStorageServiceManager import arcs.android.storage.service.StorageServiceManager -import arcs.android.storage.service.suspendForHardReferencesCallback -import arcs.android.storage.service.suspendForResultCallback import arcs.core.data.Schema -import arcs.core.storage.keys.ForeignStorageKey -import kotlinx.coroutines.CoroutineScope /** * A [StorageServiceManagerEndpoint] can be used to bind to an Android [StorageServiceManager] and * call its callback-style methods. */ -class StorageServiceManagerEndpoint( - private val bindHelper: BindHelper, - private val scope: CoroutineScope, - private val storageServiceClass: Class<*> = StorageService::class.java -) { +interface StorageServiceManagerEndpoint { /** - * Triggers a hard reference deletions for foreign hard references with the given Schema namespace - * and ID. + * Triggers a hard reference deletions for foreign hard references with the given Schema [namespace] + * and [id]. + * + * @return the number of entities removed. */ - suspend fun triggerForeignHardReferenceDeletion(namespace: Schema, id: String): Long { - return runOnStorageServiceManager { manager, result -> - manager.triggerHardReferenceDeletion(stringForeignStorageKey(namespace), id, result) - } - } + suspend fun triggerForeignHardReferenceDeletion(namespace: Schema, id: String): Long /** * Triggers a hard reference reconciliation for foreign hard references with the given Schema - * namespace and ID. + * [namespace] and [id]. + * + * @return the number of entities removed. */ - suspend fun reconcileForeignHardReference(namespace: Schema, idsToRetain: Set): Long { - return runOnStorageServiceManager { manager, result -> - manager.reconcileHardReferences( - stringForeignStorageKey(namespace), - idsToRetain.toList(), - result - ) - } - } + suspend fun reconcileForeignHardReference(namespace: Schema, idsToRetain: Set): Long /** * Binds to the IStorageServiceManager and starts a garbage collection run. */ - suspend fun runGarbageCollection(): Boolean { - return runIResultCallbackOnStorageServiceManager { manager, callback -> - manager.runGarbageCollection(callback) - } - } - - /** - * Binds to the IStorageServiceManager, and runs the given block on it. It can be used to run one - * of the methods that take a [IResultCallback]. - */ - private suspend fun runIResultCallbackOnStorageServiceManager( - block: (IStorageServiceManager, IResultCallback) -> Unit - ): Boolean { - return withBoundService { - suspendForResultCallback { resultCallback -> - block(it, resultCallback) - } - } - } - - private suspend fun runOnStorageServiceManager( - block: (IStorageServiceManager, IHardReferencesRemovalCallback) -> Unit - ): Long { - return withBoundService { - suspendForHardReferencesCallback { resultCallback -> - block(it, resultCallback) - } - } - } - - private suspend fun withBoundService(block: suspend (IStorageServiceManager) -> T): T { - val intent = StorageServiceIntentHelpers.managerIntent(bindHelper.context, storageServiceClass) - val boundService = bindHelper.bindForIntent( - intent, - scope, - IStorageServiceManager.Stub::asInterface - ) - try { - return block(boundService.service) - } finally { - boundService.disconnect() - } - } - - private fun stringForeignStorageKey(namespace: Schema) = ForeignStorageKey(namespace).toString() + suspend fun runGarbageCollection() } diff --git a/java/arcs/sdk/android/storage/service/StorageServiceManagerEndpointImpl.kt b/java/arcs/sdk/android/storage/service/StorageServiceManagerEndpointImpl.kt new file mode 100644 index 00000000000..c18738c0a86 --- /dev/null +++ b/java/arcs/sdk/android/storage/service/StorageServiceManagerEndpointImpl.kt @@ -0,0 +1,87 @@ +package arcs.sdk.android.storage.service + +import arcs.android.storage.service.IHardReferencesRemovalCallback +import arcs.android.storage.service.IResultCallback +import arcs.android.storage.service.IStorageServiceManager +import arcs.android.storage.service.StorageServiceManager +import arcs.android.storage.service.suspendForHardReferencesCallback +import arcs.android.storage.service.suspendForResultCallback +import arcs.core.data.Schema +import arcs.core.storage.keys.ForeignStorageKey +import kotlinx.coroutines.CoroutineScope + +/** + * Implementation of [StorageServiceManagerEndpoint] that binds to an Android [StorageServiceManager] and + * call its callback-style methods. + */ +class StorageServiceManagerEndpointImpl( + private val bindHelper: BindHelper, + private val scope: CoroutineScope, + private val storageServiceClass: Class<*> = StorageService::class.java +) : StorageServiceManagerEndpoint { + + override suspend fun triggerForeignHardReferenceDeletion(namespace: Schema, id: String): Long { + return runOnStorageServiceManager { manager, result -> + manager.triggerHardReferenceDeletion(stringForeignStorageKey(namespace), id, result) + } + } + + override suspend fun reconcileForeignHardReference( + namespace: Schema, + idsToRetain: Set + ): Long { + return runOnStorageServiceManager { manager, result -> + manager.reconcileHardReferences( + stringForeignStorageKey(namespace), + idsToRetain.toList(), + result + ) + } + } + + override suspend fun runGarbageCollection() { + runIResultCallbackOnStorageServiceManager { manager, callback -> + manager.runGarbageCollection(callback) + } + } + + /** + * Binds to the IStorageServiceManager, and runs the given block on it. It can be used to run one + * of the methods that take a [IResultCallback]. + */ + private suspend fun runIResultCallbackOnStorageServiceManager( + block: (IStorageServiceManager, IResultCallback) -> Unit + ): Boolean { + return withBoundService { + suspendForResultCallback { resultCallback -> + block(it, resultCallback) + } + } + } + + private suspend fun runOnStorageServiceManager( + block: (IStorageServiceManager, IHardReferencesRemovalCallback) -> Unit + ): Long { + return withBoundService { + suspendForHardReferencesCallback { resultCallback -> + block(it, resultCallback) + } + } + } + + private suspend fun withBoundService(block: suspend (IStorageServiceManager) -> T): T { + val intent = StorageServiceIntentHelpers.managerIntent(bindHelper.context, storageServiceClass) + val boundService = bindHelper.bindForIntent( + intent, + scope, + IStorageServiceManager.Stub::asInterface + ) + try { + return block(boundService.service) + } finally { + boundService.disconnect() + } + } + + private fun stringForeignStorageKey(namespace: Schema) = ForeignStorageKey(namespace).toString() +} diff --git a/javatests/arcs/android/integration/IntegrationEnvironment.kt b/javatests/arcs/android/integration/IntegrationEnvironment.kt index 88ea60fe8c0..e86165aeb72 100644 --- a/javatests/arcs/android/integration/IntegrationEnvironment.kt +++ b/javatests/arcs/android/integration/IntegrationEnvironment.kt @@ -33,7 +33,7 @@ import arcs.sdk.android.storage.AndroidStorageServiceEndpointManager import arcs.sdk.android.storage.service.DatabaseGarbageCollectionPeriodicTaskV2 import arcs.sdk.android.storage.service.StorageService import arcs.sdk.android.storage.service.StorageService.StorageServiceConfig -import arcs.sdk.android.storage.service.StorageServiceManagerEndpoint +import arcs.sdk.android.storage.service.StorageServiceManagerEndpointImpl import arcs.sdk.android.storage.service.testutil.TestBindHelper import arcs.sdk.android.storage.service.testutil.TestWorkerFactory import kotlin.coroutines.CoroutineContext @@ -322,14 +322,14 @@ class IntegrationEnvironment( } suspend fun triggerHardReferenceDelete(namespace: Schema, id: String): Long { - return StorageServiceManagerEndpoint( + return StorageServiceManagerEndpointImpl( TestBindHelper(ApplicationProvider.getApplicationContext()), testScope ).triggerForeignHardReferenceDeletion(namespace, id) } suspend fun reconcileHardReference(namespace: Schema, fullSet: Set): Long { - return StorageServiceManagerEndpoint( + return StorageServiceManagerEndpointImpl( TestBindHelper(ApplicationProvider.getApplicationContext()), testScope ).reconcileForeignHardReference(namespace, fullSet) diff --git a/javatests/arcs/sdk/android/storage/service/StorageServiceManagerEndpointTest.kt b/javatests/arcs/sdk/android/storage/service/StorageServiceManagerEndpointImplTest.kt similarity index 87% rename from javatests/arcs/sdk/android/storage/service/StorageServiceManagerEndpointTest.kt rename to javatests/arcs/sdk/android/storage/service/StorageServiceManagerEndpointImplTest.kt index 620482e73f2..7de217936dd 100644 --- a/javatests/arcs/sdk/android/storage/service/StorageServiceManagerEndpointTest.kt +++ b/javatests/arcs/sdk/android/storage/service/StorageServiceManagerEndpointImplTest.kt @@ -23,7 +23,7 @@ import org.junit.runner.RunWith @OptIn(ExperimentalCoroutinesApi::class) @RunWith(AndroidJUnit4::class) -class StorageServiceManagerEndpointTest { +class StorageServiceManagerEndpointImplTest { private lateinit var app: Application private val SCHEMA_NAME = "name" @@ -53,7 +53,7 @@ class StorageServiceManagerEndpointTest { @Test fun triggerForeignHardReferenceDeletion_propagatesToDatabase() = runBlocking { val testBindHelper = TestBindHelper(app) - val endpoint = StorageServiceManagerEndpoint(testBindHelper, this@runBlocking) + val endpoint = StorageServiceManagerEndpointImpl(testBindHelper, this@runBlocking) endpoint.triggerForeignHardReferenceDeletion(schema, "id") @@ -66,7 +66,7 @@ class StorageServiceManagerEndpointTest { @Test fun triggerForeignHardReferenceDeletion_sequenceOfCalls() = runBlocking { val testBindHelper = TestBindHelper(app) - val endpoint = StorageServiceManagerEndpoint(testBindHelper, this@runBlocking) + val endpoint = StorageServiceManagerEndpointImpl(testBindHelper, this@runBlocking) assertThat(database.hardReferenceDeletes).isEmpty() endpoint.triggerForeignHardReferenceDeletion(schema, "id") @@ -86,7 +86,7 @@ class StorageServiceManagerEndpointTest { @Test fun reconcileForeignHardReference_deletesOne() = runBlocking { val testBindHelper = TestBindHelper(app) - val endpoint = StorageServiceManagerEndpoint(testBindHelper, this@runBlocking) + val endpoint = StorageServiceManagerEndpointImpl(testBindHelper, this@runBlocking) database.allHardReferenceIds.add("id1") endpoint.reconcileForeignHardReference(schema, setOf("id2")) @@ -100,7 +100,7 @@ class StorageServiceManagerEndpointTest { @Test fun reconcileForeignHardReference_partialOvelap() = runBlocking { val testBindHelper = TestBindHelper(app) - val endpoint = StorageServiceManagerEndpoint(testBindHelper, this@runBlocking) + val endpoint = StorageServiceManagerEndpointImpl(testBindHelper, this@runBlocking) database.allHardReferenceIds.addAll(listOf("id1", "id2")) endpoint.reconcileForeignHardReference(schema, setOf("id2")) @@ -114,7 +114,7 @@ class StorageServiceManagerEndpointTest { @Test fun reconcileForeignHardReference_deletesNone() = runBlocking { val testBindHelper = TestBindHelper(app) - val endpoint = StorageServiceManagerEndpoint(testBindHelper, this@runBlocking) + val endpoint = StorageServiceManagerEndpointImpl(testBindHelper, this@runBlocking) database.allHardReferenceIds.add("id1") endpoint.reconcileForeignHardReference(schema, setOf("id1")) @@ -126,7 +126,7 @@ class StorageServiceManagerEndpointTest { @Test fun reconcileForeignHardReference_emptyValidSet() = runBlocking { val testBindHelper = TestBindHelper(app) - val endpoint = StorageServiceManagerEndpoint(testBindHelper, this@runBlocking) + val endpoint = StorageServiceManagerEndpointImpl(testBindHelper, this@runBlocking) database.allHardReferenceIds.add("id1") endpoint.reconcileForeignHardReference(schema, emptySet()) @@ -143,7 +143,7 @@ class StorageServiceManagerEndpointTest { val databaseManager = FakeDatabaseManager { dbManagerGcCalled = true } DriverAndKeyConfigurator.configure(databaseManager) val testBindHelper = TestBindHelper(app) - val endpoint = StorageServiceManagerEndpoint(testBindHelper, this@runBlocking) + val endpoint = StorageServiceManagerEndpointImpl(testBindHelper, this@runBlocking) endpoint.runGarbageCollection() @@ -158,7 +158,7 @@ class StorageServiceManagerEndpointTest { } DriverAndKeyConfigurator.configure(databaseManager) val testBindHelper = TestBindHelper(app) - val endpoint = StorageServiceManagerEndpoint(testBindHelper, this@runBlocking) + val endpoint = StorageServiceManagerEndpointImpl(testBindHelper, this@runBlocking) val e = assertFailsWith { endpoint.runGarbageCollection()