diff --git a/app/src/androidTest/java/com/stevesoltys/seedvault/PluginTest.kt b/app/src/androidTest/java/com/stevesoltys/seedvault/PluginTest.kt index 0176688f..2ba8932a 100644 --- a/app/src/androidTest/java/com/stevesoltys/seedvault/PluginTest.kt +++ b/app/src/androidTest/java/com/stevesoltys/seedvault/PluginTest.kt @@ -36,7 +36,6 @@ import org.junit.runner.RunWith import org.koin.core.KoinComponent import org.koin.core.inject import java.io.IOException -import kotlin.random.Random @RunWith(AndroidJUnit4::class) @Suppress("BlockingMethodInNonBlockingContext") @@ -63,7 +62,7 @@ class PluginTest : KoinComponent { private val restorePlugin: RestorePlugin = DocumentsProviderRestorePlugin(context, storage, kvRestorePlugin, fullRestorePlugin) - private val token = Random.nextLong() + private val token = System.currentTimeMillis() - 365L * 24L * 60L * 60L * 1000L private val packageInfo = PackageInfoBuilder.newBuilder().setPackageName("org.example").build() private val packageInfo2 = PackageInfoBuilder.newBuilder().setPackageName("net.example").build() @@ -117,14 +116,14 @@ class PluginTest : KoinComponent { // initializing again (with another restore set) does add a restore set backupPlugin.startNewRestoreSet(token + 1) backupPlugin.initializeDevice() - backupPlugin.getOutputStream(token, FILE_BACKUP_METADATA) + backupPlugin.getOutputStream(token + 1, FILE_BACKUP_METADATA) .writeAndClose(getRandomByteArray()) assertEquals(2, backupPlugin.getAvailableBackups()?.toList()?.size) assertTrue(backupPlugin.hasBackup(uri)) // initializing again (without new restore set) doesn't change number of restore sets backupPlugin.initializeDevice() - backupPlugin.getOutputStream(token, FILE_BACKUP_METADATA) + backupPlugin.getOutputStream(token + 1, FILE_BACKUP_METADATA) .writeAndClose(getRandomByteArray()) assertEquals(2, backupPlugin.getAvailableBackups()?.toList()?.size) @@ -172,7 +171,7 @@ class PluginTest : KoinComponent { // write random bytes as APK val apk1 = getRandomByteArray(1337 * 1024) - backupPlugin.getApkOutputStream(packageInfo, "").writeAndClose(apk1) + backupPlugin.getOutputStream(token, "${packageInfo.packageName}.apk").writeAndClose(apk1) // assert that read APK bytes match what was written assertReadEquals(apk1, restorePlugin.getApkInputStream(token, packageInfo.packageName, "")) @@ -180,7 +179,9 @@ class PluginTest : KoinComponent { // write random bytes as another APK val suffix2 = getRandomBase64(23) val apk2 = getRandomByteArray(23 * 1024 * 1024) - backupPlugin.getApkOutputStream(packageInfo2, suffix2).writeAndClose(apk2) + + backupPlugin.getOutputStream(token, "${packageInfo2.packageName}$suffix2.apk") + .writeAndClose(apk2) // assert that read APK bytes match what was written assertReadEquals( diff --git a/app/src/main/java/com/stevesoltys/seedvault/plugins/saf/DocumentsProviderBackupPlugin.kt b/app/src/main/java/com/stevesoltys/seedvault/plugins/saf/DocumentsProviderBackupPlugin.kt index d302bece..3135c74f 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/plugins/saf/DocumentsProviderBackupPlugin.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/plugins/saf/DocumentsProviderBackupPlugin.kt @@ -1,7 +1,6 @@ package com.stevesoltys.seedvault.plugins.saf import android.content.Context -import android.content.pm.PackageInfo import android.content.pm.PackageManager import android.net.Uri import android.util.Log @@ -16,7 +15,6 @@ import java.io.InputStream import java.io.OutputStream private val TAG = DocumentsProviderBackupPlugin::class.java.simpleName -private const val MIME_TYPE_APK = "application/vnd.android.package-archive" @Suppress("BlockingMethodInNonBlockingContext") internal class DocumentsProviderBackupPlugin( @@ -78,13 +76,6 @@ internal class DocumentsProviderBackupPlugin( if (!file.delete()) throw IOException("Failed to delete $name") } - @Throws(IOException::class) - override suspend fun getMetadataOutputStream(token: Long): OutputStream { - val setDir = storage.getSetDir(token) ?: throw IOException() - val metadataFile = setDir.createOrGetFile(context, FILE_BACKUP_METADATA) - return storage.getOutputStream(metadataFile) - } - @Throws(IOException::class) override suspend fun hasBackup(uri: Uri): Boolean { val parent = DocumentFile.fromTreeUri(context, uri) ?: throw AssertionError() @@ -106,17 +97,6 @@ internal class DocumentsProviderBackupPlugin( } } - @Throws(IOException::class) - override suspend fun getApkOutputStream( - packageInfo: PackageInfo, - suffix: String - ): OutputStream { - val setDir = storage.getSetDir() ?: throw IOException() - val name = "${packageInfo.packageName}$suffix.apk" - val file = setDir.createOrGetFile(context, name, MIME_TYPE_APK) - return storage.getOutputStream(file) - } - override val providerPackageName: String? by lazy { val authority = storage.getAuthority() ?: return@lazy null val providerInfo = packageManager.resolveContentProvider(authority, 0) ?: return@lazy null diff --git a/app/src/main/java/com/stevesoltys/seedvault/transport/backup/BackupCoordinator.kt b/app/src/main/java/com/stevesoltys/seedvault/transport/backup/BackupCoordinator.kt index aa4cd21b..3b934aff 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/transport/backup/BackupCoordinator.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/transport/backup/BackupCoordinator.kt @@ -441,7 +441,9 @@ internal class BackupCoordinator( val packageName = packageInfo.packageName return try { apkBackup.backupApkIfNecessary(packageInfo, packageState) { suffix -> - plugin.getApkOutputStream(packageInfo, suffix) + val token = settingsManager.getToken() ?: throw IOException("no current token") + val name = "${packageInfo.packageName}$suffix.apk" + plugin.getOutputStream(token, name) }?.let { packageMetadata -> plugin.getMetadataOutputStream().use { metadataManager.onApkBackedUp(packageInfo, packageMetadata, it) @@ -494,9 +496,9 @@ internal class BackupCoordinator( } } - private suspend fun BackupPlugin.getMetadataOutputStream(): OutputStream { - val token = settingsManager.getToken() ?: throw IOException("no current token") - return getOutputStream(token, FILE_BACKUP_METADATA) + private suspend fun BackupPlugin.getMetadataOutputStream(token: Long? = null): OutputStream { + val t = token ?: settingsManager.getToken() ?: throw IOException("no current token") + return getOutputStream(t, FILE_BACKUP_METADATA) } } diff --git a/app/src/main/java/com/stevesoltys/seedvault/transport/backup/BackupPlugin.kt b/app/src/main/java/com/stevesoltys/seedvault/transport/backup/BackupPlugin.kt index 31ba5f31..33d2024e 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/transport/backup/BackupPlugin.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/transport/backup/BackupPlugin.kt @@ -1,7 +1,6 @@ package com.stevesoltys.seedvault.transport.backup import android.app.backup.RestoreSet -import android.content.pm.PackageInfo import android.net.Uri import androidx.annotation.WorkerThread import java.io.IOException @@ -54,13 +53,6 @@ interface BackupPlugin { @Throws(IOException::class) suspend fun removeData(token: Long, name: String) - /** - * Returns an [OutputStream] for writing backup metadata. - */ - @Throws(IOException::class) - @Deprecated("use getOutputStream(token, FILE_BACKUP_METADATA) instead") - suspend fun getMetadataOutputStream(token: Long): OutputStream - /** * Searches if there's really a backup available in the given location. * Returns true if at least one was found and false otherwise. @@ -79,13 +71,6 @@ interface BackupPlugin { **/ suspend fun getAvailableBackups(): Sequence? - /** - * Returns an [OutputStream] for writing an APK to be backed up. - */ - @Throws(IOException::class) - @Deprecated("Use getOutputStream() instead") - suspend fun getApkOutputStream(packageInfo: PackageInfo, suffix: String): OutputStream - /** * Returns the package name of the app that provides the backend storage * which is used for the current backup location.