Merge pull request #422 from t-m-w/do-not-restore-storage-provider
Exclude storage provider from restore
This commit is contained in:
commit
3aa1b9f03d
4 changed files with 39 additions and 1 deletions
|
@ -41,7 +41,12 @@ internal class ApkRestore(
|
|||
@Suppress("BlockingMethodInNonBlockingContext")
|
||||
fun restore(backup: RestorableBackup) = flow {
|
||||
// filter out packages without APK and get total
|
||||
val packages = backup.packageMetadataMap.filter { it.value.hasApk() }
|
||||
val packages = backup.packageMetadataMap.filter {
|
||||
// We also need to exclude the DocumentsProvider used to retrieve backup data.
|
||||
// Otherwise, it gets killed when we install it, terminating our restoration.
|
||||
val isStorageProvider = it.key == storagePlugin.providerPackageName
|
||||
it.value.hasApk() && !isStorageProvider
|
||||
}
|
||||
val total = packages.size
|
||||
var progress = 0
|
||||
|
||||
|
|
|
@ -118,6 +118,7 @@ internal class ApkBackupRestoreTest : TransportTest() {
|
|||
every { metadataManager.salt } returns salt
|
||||
every { crypto.getNameForApk(salt, packageName) } returns name
|
||||
every { crypto.getNameForApk(salt, packageName, splitName) } returns suffixName
|
||||
every { storagePlugin.providerPackageName } returns storageProviderPackageName
|
||||
|
||||
apkBackup.backupApkIfNecessary(packageInfo, PackageState.APK_AND_DATA, outputStreamGetter)
|
||||
|
||||
|
|
|
@ -97,6 +97,7 @@ internal class ApkRestoreTest : TransportTest() {
|
|||
every { strictContext.cacheDir } returns File(tmpDir.toString())
|
||||
every { crypto.getNameForApk(salt, packageName, "") } returns name
|
||||
coEvery { storagePlugin.getInputStream(token, name) } returns apkInputStream
|
||||
every { storagePlugin.providerPackageName } returns storageProviderPackageName
|
||||
|
||||
apkRestore.restore(backup).collectIndexed { i, value ->
|
||||
assertQueuedFailFinished(i, value)
|
||||
|
@ -112,6 +113,7 @@ internal class ApkRestoreTest : TransportTest() {
|
|||
every { crypto.getNameForApk(salt, packageName, "") } returns name
|
||||
coEvery { storagePlugin.getInputStream(token, name) } returns apkInputStream
|
||||
every { pm.getPackageArchiveInfo(any(), any()) } returns packageInfo
|
||||
every { storagePlugin.providerPackageName } returns storageProviderPackageName
|
||||
|
||||
apkRestore.restore(backup).collectIndexed { i, value ->
|
||||
assertQueuedFailFinished(i, value)
|
||||
|
@ -124,6 +126,7 @@ internal class ApkRestoreTest : TransportTest() {
|
|||
coEvery {
|
||||
apkInstaller.install(match { it.size == 1 }, packageName, installerName, any())
|
||||
} throws SecurityException()
|
||||
every { storagePlugin.providerPackageName } returns storageProviderPackageName
|
||||
|
||||
apkRestore.restore(backup).collectIndexed { i, value ->
|
||||
assertQueuedProgressFailFinished(i, value)
|
||||
|
@ -146,6 +149,7 @@ internal class ApkRestoreTest : TransportTest() {
|
|||
coEvery {
|
||||
apkInstaller.install(match { it.size == 1 }, packageName, installerName, any())
|
||||
} returns installResult
|
||||
every { storagePlugin.providerPackageName } returns storageProviderPackageName
|
||||
|
||||
apkRestore.restore(backup).collectIndexed { i, value ->
|
||||
assertQueuedProgressSuccessFinished(i, value)
|
||||
|
@ -184,6 +188,7 @@ internal class ApkRestoreTest : TransportTest() {
|
|||
coEvery {
|
||||
apkInstaller.install(match { it.size == 1 }, packageName, installerName, any())
|
||||
} returns installResult
|
||||
every { storagePlugin.providerPackageName } returns storageProviderPackageName
|
||||
|
||||
apkRestore.restore(backup).collectIndexed { i, value ->
|
||||
assertQueuedProgressSuccessFinished(i, value)
|
||||
|
@ -202,6 +207,7 @@ internal class ApkRestoreTest : TransportTest() {
|
|||
|
||||
cacheBaseApkAndGetInfo(tmpDir)
|
||||
every { packageInfo.applicationInfo.loadIcon(pm) } returns icon
|
||||
every { storagePlugin.providerPackageName } returns storageProviderPackageName
|
||||
|
||||
if (willFail) {
|
||||
every {
|
||||
|
@ -281,6 +287,7 @@ internal class ApkRestoreTest : TransportTest() {
|
|||
every {
|
||||
splitCompatChecker.isCompatible(deviceName, listOf(split1Name, split2Name))
|
||||
} returns false
|
||||
every { storagePlugin.providerPackageName } returns storageProviderPackageName
|
||||
|
||||
apkRestore.restore(backup).collectIndexed { i, value ->
|
||||
assertQueuedProgressFailFinished(i, value)
|
||||
|
@ -303,6 +310,7 @@ internal class ApkRestoreTest : TransportTest() {
|
|||
coEvery {
|
||||
storagePlugin.getInputStream(token, suffixName)
|
||||
} returns ByteArrayInputStream(getRandomByteArray())
|
||||
every { storagePlugin.providerPackageName } returns storageProviderPackageName
|
||||
|
||||
apkRestore.restore(backup).collectIndexed { i, value ->
|
||||
assertQueuedProgressFailFinished(i, value)
|
||||
|
@ -325,6 +333,7 @@ internal class ApkRestoreTest : TransportTest() {
|
|||
every { splitCompatChecker.isCompatible(deviceName, listOf(splitName)) } returns true
|
||||
every { crypto.getNameForApk(salt, packageName, splitName) } returns suffixName
|
||||
coEvery { storagePlugin.getInputStream(token, suffixName) } throws IOException()
|
||||
every { storagePlugin.providerPackageName } returns storageProviderPackageName
|
||||
|
||||
apkRestore.restore(backup).collectIndexed { i, value ->
|
||||
assertQueuedProgressFailFinished(i, value)
|
||||
|
@ -363,6 +372,7 @@ internal class ApkRestoreTest : TransportTest() {
|
|||
coEvery { storagePlugin.getInputStream(token, suffixName1) } returns split1InputStream
|
||||
every { crypto.getNameForApk(salt, packageName, split2Name) } returns suffixName2
|
||||
coEvery { storagePlugin.getInputStream(token, suffixName2) } returns split2InputStream
|
||||
every { storagePlugin.providerPackageName } returns storageProviderPackageName
|
||||
|
||||
coEvery {
|
||||
apkInstaller.install(match { it.size == 3 }, packageName, installerName, any())
|
||||
|
@ -381,6 +391,27 @@ internal class ApkRestoreTest : TransportTest() {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `storage provider app does not get reinstalled`(@TempDir tmpDir: Path) = runBlocking {
|
||||
// set the storage provider package name to match our current package name,
|
||||
// and ensure that the current package is therefore skipped.
|
||||
every { storagePlugin.providerPackageName } returns packageName
|
||||
|
||||
apkRestore.restore(backup).collectIndexed { i, value ->
|
||||
when (i) {
|
||||
0 -> {
|
||||
assertFalse(value.isFinished)
|
||||
}
|
||||
1 -> {
|
||||
// the only package provided should have been filtered, leaving 0 packages.
|
||||
assertEquals(0, value.total)
|
||||
assertTrue(value.isFinished)
|
||||
}
|
||||
else -> fail("more values emitted")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun swapPackages(packageMetadataMap: PackageMetadataMap): RestorableBackup {
|
||||
val metadata = metadata.copy(packageMetadataMap = packageMetadataMap)
|
||||
return backup.copy(backupMetadata = metadata)
|
||||
|
|
|
@ -61,6 +61,7 @@ internal abstract class TransportTest {
|
|||
protected val salt = metadata.salt
|
||||
protected val name = getRandomString(12)
|
||||
protected val name2 = getRandomString(23)
|
||||
protected val storageProviderPackageName = getRandomString(23)
|
||||
|
||||
init {
|
||||
mockkStatic(Log::class)
|
||||
|
|
Loading…
Reference in a new issue