diff --git a/app/src/main/java/com/stevesoltys/seedvault/restore/install/ApkRestore.kt b/app/src/main/java/com/stevesoltys/seedvault/restore/install/ApkRestore.kt index 168ff7e5..85013361 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/restore/install/ApkRestore.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/restore/install/ApkRestore.kt @@ -63,6 +63,9 @@ internal class ApkRestore( // The @pm@ package needs to be included in [backup], but can't be installed like an app if (packageName == MAGIC_PACKAGE_MANAGER) return@mapNotNull null // we don't filter out apps without APK, so the user can manually install them + // exception is system apps without APK, as those can usually not be installed manually + if (metadata.system && !metadata.hasApk()) return@mapNotNull null + // apps that made it here get a state class for tracking ApkInstallResult( packageName = packageName, state = if (isAllowedToInstallApks) QUEUED else FAILED, diff --git a/app/src/test/java/com/stevesoltys/seedvault/restore/install/ApkRestoreTest.kt b/app/src/test/java/com/stevesoltys/seedvault/restore/install/ApkRestoreTest.kt index dd31e429..2cb74bd5 100644 --- a/app/src/test/java/com/stevesoltys/seedvault/restore/install/ApkRestoreTest.kt +++ b/app/src/test/java/com/stevesoltys/seedvault/restore/install/ApkRestoreTest.kt @@ -427,6 +427,32 @@ internal class ApkRestoreTest : TransportTest() { } } + @Test + fun `system app without APK get filtered out`() = runBlocking { + // only backed up package is a system app without an APK + packageMetadataMap[packageName] = PackageMetadata( + time = 23L, + system = true, + isLaunchableSystemApp = Random.nextBoolean(), + ).also { assertFalse(it.hasApk()) } + + every { installRestriction.isAllowedToInstallApks() } returns true + every { storagePlugin.providerPackageName } returns storageProviderPackageName + + apkRestore.installResult.test { + awaitItem() // initial empty state + apkRestore.restore(backup) + + awaitItem().also { finishedItem -> + println(finishedItem.installResults.values.toList()) + // the only package provided should have been filtered, leaving 0 packages. + assertEquals(0, finishedItem.total) + assertTrue(finishedItem.isFinished) + } + ensureAllEventsConsumed() + } + } + @Test fun `no apks get installed when blocked by policy`() = runBlocking { every { installRestriction.isAllowedToInstallApks() } returns false