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")
|
@Suppress("BlockingMethodInNonBlockingContext")
|
||||||
fun restore(backup: RestorableBackup) = flow {
|
fun restore(backup: RestorableBackup) = flow {
|
||||||
// filter out packages without APK and get total
|
// 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
|
val total = packages.size
|
||||||
var progress = 0
|
var progress = 0
|
||||||
|
|
||||||
|
|
|
@ -118,6 +118,7 @@ internal class ApkBackupRestoreTest : TransportTest() {
|
||||||
every { metadataManager.salt } returns salt
|
every { metadataManager.salt } returns salt
|
||||||
every { crypto.getNameForApk(salt, packageName) } returns name
|
every { crypto.getNameForApk(salt, packageName) } returns name
|
||||||
every { crypto.getNameForApk(salt, packageName, splitName) } returns suffixName
|
every { crypto.getNameForApk(salt, packageName, splitName) } returns suffixName
|
||||||
|
every { storagePlugin.providerPackageName } returns storageProviderPackageName
|
||||||
|
|
||||||
apkBackup.backupApkIfNecessary(packageInfo, PackageState.APK_AND_DATA, outputStreamGetter)
|
apkBackup.backupApkIfNecessary(packageInfo, PackageState.APK_AND_DATA, outputStreamGetter)
|
||||||
|
|
||||||
|
|
|
@ -97,6 +97,7 @@ internal class ApkRestoreTest : TransportTest() {
|
||||||
every { strictContext.cacheDir } returns File(tmpDir.toString())
|
every { strictContext.cacheDir } returns File(tmpDir.toString())
|
||||||
every { crypto.getNameForApk(salt, packageName, "") } returns name
|
every { crypto.getNameForApk(salt, packageName, "") } returns name
|
||||||
coEvery { storagePlugin.getInputStream(token, name) } returns apkInputStream
|
coEvery { storagePlugin.getInputStream(token, name) } returns apkInputStream
|
||||||
|
every { storagePlugin.providerPackageName } returns storageProviderPackageName
|
||||||
|
|
||||||
apkRestore.restore(backup).collectIndexed { i, value ->
|
apkRestore.restore(backup).collectIndexed { i, value ->
|
||||||
assertQueuedFailFinished(i, value)
|
assertQueuedFailFinished(i, value)
|
||||||
|
@ -112,6 +113,7 @@ internal class ApkRestoreTest : TransportTest() {
|
||||||
every { crypto.getNameForApk(salt, packageName, "") } returns name
|
every { crypto.getNameForApk(salt, packageName, "") } returns name
|
||||||
coEvery { storagePlugin.getInputStream(token, name) } returns apkInputStream
|
coEvery { storagePlugin.getInputStream(token, name) } returns apkInputStream
|
||||||
every { pm.getPackageArchiveInfo(any(), any()) } returns packageInfo
|
every { pm.getPackageArchiveInfo(any(), any()) } returns packageInfo
|
||||||
|
every { storagePlugin.providerPackageName } returns storageProviderPackageName
|
||||||
|
|
||||||
apkRestore.restore(backup).collectIndexed { i, value ->
|
apkRestore.restore(backup).collectIndexed { i, value ->
|
||||||
assertQueuedFailFinished(i, value)
|
assertQueuedFailFinished(i, value)
|
||||||
|
@ -124,6 +126,7 @@ internal class ApkRestoreTest : TransportTest() {
|
||||||
coEvery {
|
coEvery {
|
||||||
apkInstaller.install(match { it.size == 1 }, packageName, installerName, any())
|
apkInstaller.install(match { it.size == 1 }, packageName, installerName, any())
|
||||||
} throws SecurityException()
|
} throws SecurityException()
|
||||||
|
every { storagePlugin.providerPackageName } returns storageProviderPackageName
|
||||||
|
|
||||||
apkRestore.restore(backup).collectIndexed { i, value ->
|
apkRestore.restore(backup).collectIndexed { i, value ->
|
||||||
assertQueuedProgressFailFinished(i, value)
|
assertQueuedProgressFailFinished(i, value)
|
||||||
|
@ -146,6 +149,7 @@ internal class ApkRestoreTest : TransportTest() {
|
||||||
coEvery {
|
coEvery {
|
||||||
apkInstaller.install(match { it.size == 1 }, packageName, installerName, any())
|
apkInstaller.install(match { it.size == 1 }, packageName, installerName, any())
|
||||||
} returns installResult
|
} returns installResult
|
||||||
|
every { storagePlugin.providerPackageName } returns storageProviderPackageName
|
||||||
|
|
||||||
apkRestore.restore(backup).collectIndexed { i, value ->
|
apkRestore.restore(backup).collectIndexed { i, value ->
|
||||||
assertQueuedProgressSuccessFinished(i, value)
|
assertQueuedProgressSuccessFinished(i, value)
|
||||||
|
@ -184,6 +188,7 @@ internal class ApkRestoreTest : TransportTest() {
|
||||||
coEvery {
|
coEvery {
|
||||||
apkInstaller.install(match { it.size == 1 }, packageName, installerName, any())
|
apkInstaller.install(match { it.size == 1 }, packageName, installerName, any())
|
||||||
} returns installResult
|
} returns installResult
|
||||||
|
every { storagePlugin.providerPackageName } returns storageProviderPackageName
|
||||||
|
|
||||||
apkRestore.restore(backup).collectIndexed { i, value ->
|
apkRestore.restore(backup).collectIndexed { i, value ->
|
||||||
assertQueuedProgressSuccessFinished(i, value)
|
assertQueuedProgressSuccessFinished(i, value)
|
||||||
|
@ -202,6 +207,7 @@ internal class ApkRestoreTest : TransportTest() {
|
||||||
|
|
||||||
cacheBaseApkAndGetInfo(tmpDir)
|
cacheBaseApkAndGetInfo(tmpDir)
|
||||||
every { packageInfo.applicationInfo.loadIcon(pm) } returns icon
|
every { packageInfo.applicationInfo.loadIcon(pm) } returns icon
|
||||||
|
every { storagePlugin.providerPackageName } returns storageProviderPackageName
|
||||||
|
|
||||||
if (willFail) {
|
if (willFail) {
|
||||||
every {
|
every {
|
||||||
|
@ -281,6 +287,7 @@ internal class ApkRestoreTest : TransportTest() {
|
||||||
every {
|
every {
|
||||||
splitCompatChecker.isCompatible(deviceName, listOf(split1Name, split2Name))
|
splitCompatChecker.isCompatible(deviceName, listOf(split1Name, split2Name))
|
||||||
} returns false
|
} returns false
|
||||||
|
every { storagePlugin.providerPackageName } returns storageProviderPackageName
|
||||||
|
|
||||||
apkRestore.restore(backup).collectIndexed { i, value ->
|
apkRestore.restore(backup).collectIndexed { i, value ->
|
||||||
assertQueuedProgressFailFinished(i, value)
|
assertQueuedProgressFailFinished(i, value)
|
||||||
|
@ -303,6 +310,7 @@ internal class ApkRestoreTest : TransportTest() {
|
||||||
coEvery {
|
coEvery {
|
||||||
storagePlugin.getInputStream(token, suffixName)
|
storagePlugin.getInputStream(token, suffixName)
|
||||||
} returns ByteArrayInputStream(getRandomByteArray())
|
} returns ByteArrayInputStream(getRandomByteArray())
|
||||||
|
every { storagePlugin.providerPackageName } returns storageProviderPackageName
|
||||||
|
|
||||||
apkRestore.restore(backup).collectIndexed { i, value ->
|
apkRestore.restore(backup).collectIndexed { i, value ->
|
||||||
assertQueuedProgressFailFinished(i, value)
|
assertQueuedProgressFailFinished(i, value)
|
||||||
|
@ -325,6 +333,7 @@ internal class ApkRestoreTest : TransportTest() {
|
||||||
every { splitCompatChecker.isCompatible(deviceName, listOf(splitName)) } returns true
|
every { splitCompatChecker.isCompatible(deviceName, listOf(splitName)) } returns true
|
||||||
every { crypto.getNameForApk(salt, packageName, splitName) } returns suffixName
|
every { crypto.getNameForApk(salt, packageName, splitName) } returns suffixName
|
||||||
coEvery { storagePlugin.getInputStream(token, suffixName) } throws IOException()
|
coEvery { storagePlugin.getInputStream(token, suffixName) } throws IOException()
|
||||||
|
every { storagePlugin.providerPackageName } returns storageProviderPackageName
|
||||||
|
|
||||||
apkRestore.restore(backup).collectIndexed { i, value ->
|
apkRestore.restore(backup).collectIndexed { i, value ->
|
||||||
assertQueuedProgressFailFinished(i, value)
|
assertQueuedProgressFailFinished(i, value)
|
||||||
|
@ -363,6 +372,7 @@ internal class ApkRestoreTest : TransportTest() {
|
||||||
coEvery { storagePlugin.getInputStream(token, suffixName1) } returns split1InputStream
|
coEvery { storagePlugin.getInputStream(token, suffixName1) } returns split1InputStream
|
||||||
every { crypto.getNameForApk(salt, packageName, split2Name) } returns suffixName2
|
every { crypto.getNameForApk(salt, packageName, split2Name) } returns suffixName2
|
||||||
coEvery { storagePlugin.getInputStream(token, suffixName2) } returns split2InputStream
|
coEvery { storagePlugin.getInputStream(token, suffixName2) } returns split2InputStream
|
||||||
|
every { storagePlugin.providerPackageName } returns storageProviderPackageName
|
||||||
|
|
||||||
coEvery {
|
coEvery {
|
||||||
apkInstaller.install(match { it.size == 3 }, packageName, installerName, any())
|
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 {
|
private fun swapPackages(packageMetadataMap: PackageMetadataMap): RestorableBackup {
|
||||||
val metadata = metadata.copy(packageMetadataMap = packageMetadataMap)
|
val metadata = metadata.copy(packageMetadataMap = packageMetadataMap)
|
||||||
return backup.copy(backupMetadata = metadata)
|
return backup.copy(backupMetadata = metadata)
|
||||||
|
|
|
@ -61,6 +61,7 @@ internal abstract class TransportTest {
|
||||||
protected val salt = metadata.salt
|
protected val salt = metadata.salt
|
||||||
protected val name = getRandomString(12)
|
protected val name = getRandomString(12)
|
||||||
protected val name2 = getRandomString(23)
|
protected val name2 = getRandomString(23)
|
||||||
|
protected val storageProviderPackageName = getRandomString(23)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
mockkStatic(Log::class)
|
mockkStatic(Log::class)
|
||||||
|
|
Loading…
Reference in a new issue