diff --git a/app/src/androidTest/java/com/stevesoltys/seedvault/PluginTest.kt b/app/src/androidTest/java/com/stevesoltys/seedvault/PluginTest.kt index bd92deeb..c9624eb5 100644 --- a/app/src/androidTest/java/com/stevesoltys/seedvault/PluginTest.kt +++ b/app/src/androidTest/java/com/stevesoltys/seedvault/PluginTest.kt @@ -10,7 +10,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.MediumTest import androidx.test.platform.app.InstrumentationRegistry import com.stevesoltys.seedvault.backend.LegacyStoragePlugin -import com.stevesoltys.seedvault.backend.getAvailableBackupFileHandles import com.stevesoltys.seedvault.backend.saf.DocumentsProviderLegacyPlugin import com.stevesoltys.seedvault.backend.saf.DocumentsStorage import com.stevesoltys.seedvault.settings.SettingsManager diff --git a/app/src/androidTest/java/com/stevesoltys/seedvault/transport/backup/KvBackupInstrumentationTest.kt b/app/src/androidTest/java/com/stevesoltys/seedvault/transport/backup/KvBackupInstrumentationTest.kt index b7190753..611d9974 100644 --- a/app/src/androidTest/java/com/stevesoltys/seedvault/transport/backup/KvBackupInstrumentationTest.kt +++ b/app/src/androidTest/java/com/stevesoltys/seedvault/transport/backup/KvBackupInstrumentationTest.kt @@ -13,7 +13,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.MediumTest import com.stevesoltys.seedvault.repo.BackupData import com.stevesoltys.seedvault.repo.BackupReceiver -import com.stevesoltys.seedvault.settings.SettingsManager import io.mockk.CapturingSlot import io.mockk.Runs import io.mockk.coEvery @@ -34,7 +33,6 @@ import kotlin.test.assertEquals @MediumTest class KvBackupInstrumentationTest : KoinComponent { - private val settingsManager: SettingsManager by inject() private val backupReceiver: BackupReceiver = mockk() private val inputFactory: InputFactory = mockk() private val dbManager: KvDbManager by inject() diff --git a/app/src/androidTest/java/com/stevesoltys/seedvault/worker/IconManagerTest.kt b/app/src/androidTest/java/com/stevesoltys/seedvault/worker/IconManagerTest.kt index a11321f3..d7b10437 100644 --- a/app/src/androidTest/java/com/stevesoltys/seedvault/worker/IconManagerTest.kt +++ b/app/src/androidTest/java/com/stevesoltys/seedvault/worker/IconManagerTest.kt @@ -13,9 +13,9 @@ import com.stevesoltys.seedvault.proto.SnapshotKt.blob import com.stevesoltys.seedvault.repo.AppBackupManager import com.stevesoltys.seedvault.repo.BackupData import com.stevesoltys.seedvault.repo.BackupReceiver -import com.stevesoltys.seedvault.transport.backup.PackageService -import com.stevesoltys.seedvault.repo.SnapshotCreatorFactory import com.stevesoltys.seedvault.repo.Loader +import com.stevesoltys.seedvault.repo.SnapshotCreatorFactory +import com.stevesoltys.seedvault.transport.backup.PackageService import io.mockk.Runs import io.mockk.coEvery import io.mockk.every diff --git a/app/src/main/java/com/stevesoltys/seedvault/App.kt b/app/src/main/java/com/stevesoltys/seedvault/App.kt index 0abc535b..1d3bfd2e 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/App.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/App.kt @@ -86,11 +86,9 @@ open class App : Application() { settingsManager = get(), keyManager = get(), backendManager = get(), - metadataManager = get(), appListRetriever = get(), storageBackup = get(), backupManager = get(), - backupInitializer = get(), backupStateManager = get(), ) } diff --git a/app/src/main/java/com/stevesoltys/seedvault/backend/BackendManager.kt b/app/src/main/java/com/stevesoltys/seedvault/backend/BackendManager.kt index 95fbbeb8..a4f2d01f 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/backend/BackendManager.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/backend/BackendManager.kt @@ -10,9 +10,9 @@ import android.util.Log import androidx.annotation.WorkerThread import com.stevesoltys.seedvault.getStorageContext import com.stevesoltys.seedvault.permitDiskReads +import com.stevesoltys.seedvault.repo.BlobCache import com.stevesoltys.seedvault.settings.SettingsManager import com.stevesoltys.seedvault.settings.StoragePluginType -import com.stevesoltys.seedvault.repo.BlobCache import org.calyxos.seedvault.core.backends.Backend import org.calyxos.seedvault.core.backends.BackendFactory import org.calyxos.seedvault.core.backends.BackendProperties @@ -89,6 +89,7 @@ class BackendManager( mBackend = backend mBackendProperties = storageProperties blobCache.clearLocalCache() + // TODO not critical, but nice to have: clear also local snapshot cache } /** diff --git a/app/src/main/java/com/stevesoltys/seedvault/backend/saf/DocumentsStorage.kt b/app/src/main/java/com/stevesoltys/seedvault/backend/saf/DocumentsStorage.kt index 1f61dbd0..48e10ede 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/backend/saf/DocumentsStorage.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/backend/saf/DocumentsStorage.kt @@ -29,7 +29,6 @@ import org.calyxos.seedvault.core.backends.saf.SafProperties import org.calyxos.seedvault.core.backends.saf.getTreeDocumentFile import java.io.IOException import java.io.InputStream -import java.io.OutputStream import kotlin.coroutines.resume @Deprecated("") @@ -51,7 +50,7 @@ internal class DocumentsStorage( private val context: Context get() = appContext.getStorageContext { safStorage.isUsb } private val contentResolver: ContentResolver get() = context.contentResolver - internal var rootBackupDir: DocumentFile? = null + private var rootBackupDir: DocumentFile? = null get() = runBlocking { if (field == null) { val parent = safStorage.getDocumentFile(context) @@ -94,16 +93,6 @@ internal class DocumentsStorage( } } - @Throws(IOException::class) - fun getOutputStream(file: DocumentFile): OutputStream { - return try { - contentResolver.openOutputStream(file.uri, "wt") ?: throw IOException() - } catch (e: Exception) { - // SAF can throw all sorts of exceptions, so wrap it in IOException - throw IOException(e) - } - } - } /** @@ -192,7 +181,7 @@ suspend fun DocumentFile.findFileBlocking(context: Context, displayName: String) @Throws(IOException::class, TimeoutCancellationException::class) internal suspend fun getLoadedCursor(timeout: Long = 15_000, query: () -> Cursor?) = withTimeout(timeout) { - suspendCancellableCoroutine { cont -> + suspendCancellableCoroutine { cont -> val cursor = query() ?: throw IOException() cont.invokeOnCancellation { cursor.close() } val loading = cursor.extras.getBoolean(EXTRA_LOADING, false) diff --git a/app/src/main/java/com/stevesoltys/seedvault/backend/saf/StorageRootResolver.kt b/app/src/main/java/com/stevesoltys/seedvault/backend/saf/StorageRootResolver.kt index 12dc1dc5..7e2e7c45 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/backend/saf/StorageRootResolver.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/backend/saf/StorageRootResolver.kt @@ -139,17 +139,6 @@ internal object StorageRootResolver { return if (index != -1) getInt(index) else 0 } - private fun Cursor.getLong(columnName: String): Long? { - val index = getColumnIndex(columnName) - if (index == -1) return null - val value = getString(index) ?: return null - return try { - java.lang.Long.parseLong(value) - } catch (e: NumberFormatException) { - null - } - } - fun getIcon(context: Context, authority: String, rootId: String, icon: Int): Drawable? { return getPackageIcon(context, authority, icon) ?: when { authority == AUTHORITY_STORAGE && rootId == ROOT_ID_DEVICE -> { diff --git a/app/src/main/java/com/stevesoltys/seedvault/crypto/Crypto.kt b/app/src/main/java/com/stevesoltys/seedvault/crypto/Crypto.kt index 675607bc..36f386ea 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/crypto/Crypto.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/crypto/Crypto.kt @@ -102,17 +102,6 @@ internal interface Crypto { @Deprecated("only for v1") fun getNameForApk(salt: String, packageName: String, suffix: String = ""): String - /** - * Returns a [AesGcmHkdfStreaming] encrypting stream - * that gets encrypted and authenticated the given associated data. - */ - @Deprecated("only for v1") - @Throws(IOException::class, GeneralSecurityException::class) - fun newEncryptingStreamV1( - outputStream: OutputStream, - associatedData: ByteArray, - ): OutputStream - /** * Returns a [AesGcmHkdfStreaming] decrypting stream * that gets decrypted and authenticated the given associated data. @@ -245,13 +234,6 @@ internal class CryptoImpl( return messageDigest.digest() } - @Deprecated("only for v1") - @Throws(IOException::class, GeneralSecurityException::class) - override fun newEncryptingStreamV1( - outputStream: OutputStream, - associatedData: ByteArray, - ): OutputStream = CoreCrypto.newEncryptingStream(keyV1, outputStream, associatedData) - @Deprecated("only for v1") @Throws(IOException::class, GeneralSecurityException::class) override fun newDecryptingStreamV1( diff --git a/app/src/main/java/com/stevesoltys/seedvault/metadata/MetadataWriter.kt b/app/src/main/java/com/stevesoltys/seedvault/metadata/MetadataWriter.kt index ce9c317b..f1f543ce 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/metadata/MetadataWriter.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/metadata/MetadataWriter.kt @@ -33,12 +33,6 @@ internal class MetadataWriterImpl : MetadataWriter { if (packageMetadata.size != null) { put(JSON_PACKAGE_SIZE, packageMetadata.size) } - if (packageMetadata.system) { - put(JSON_PACKAGE_SYSTEM, true) - } - if (packageMetadata.isLaunchableSystemApp) { - put(JSON_PACKAGE_SYSTEM_LAUNCHER, true) - } }) } return json.toString().toByteArray(Utf8) diff --git a/app/src/main/java/com/stevesoltys/seedvault/repo/AppBackupManager.kt b/app/src/main/java/com/stevesoltys/seedvault/repo/AppBackupManager.kt index 7eff9bd4..fae3b4db 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/repo/AppBackupManager.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/repo/AppBackupManager.kt @@ -144,6 +144,7 @@ internal class AppBackupManager( @Throws(IOException::class) suspend fun removeBackupRepo() { blobCache.clearLocalCache() + // TODO not critical, but nice to have: clear also local snapshot cache backendManager.backend.remove(TopLevelFolder(crypto.repoId)) } diff --git a/app/src/main/java/com/stevesoltys/seedvault/repo/RepoModule.kt b/app/src/main/java/com/stevesoltys/seedvault/repo/RepoModule.kt index c05ae656..8aa72064 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/repo/RepoModule.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/repo/RepoModule.kt @@ -19,6 +19,6 @@ val repoModule = module { val snapshotFolder = File(androidContext().filesDir, FOLDER_SNAPSHOTS) SnapshotManager(snapshotFolder, get(), get(), get()) } - factory { SnapshotCreatorFactory(androidContext(), get(), get(), get(), get()) } + factory { SnapshotCreatorFactory(androidContext(), get(), get(), get()) } factory { Pruner(get(), get(), get()) } } diff --git a/app/src/main/java/com/stevesoltys/seedvault/repo/SnapshotCreator.kt b/app/src/main/java/com/stevesoltys/seedvault/repo/SnapshotCreator.kt index 15d9df26..eda04826 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/repo/SnapshotCreator.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/repo/SnapshotCreator.kt @@ -23,7 +23,6 @@ import com.stevesoltys.seedvault.proto.Snapshot import com.stevesoltys.seedvault.proto.Snapshot.Apk import com.stevesoltys.seedvault.proto.Snapshot.App import com.stevesoltys.seedvault.proto.Snapshot.Blob -import com.stevesoltys.seedvault.settings.SettingsManager import com.stevesoltys.seedvault.transport.backup.PackageService import com.stevesoltys.seedvault.transport.backup.isSystemApp import io.github.oshai.kotlinlogging.KotlinLogging @@ -38,7 +37,6 @@ internal class SnapshotCreator( private val context: Context, private val clock: Clock, private val packageService: PackageService, - private val settingsManager: SettingsManager, private val metadataManager: MetadataManager, ) { diff --git a/app/src/main/java/com/stevesoltys/seedvault/repo/SnapshotCreatorFactory.kt b/app/src/main/java/com/stevesoltys/seedvault/repo/SnapshotCreatorFactory.kt index 905dc9ad..ac2abd4f 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/repo/SnapshotCreatorFactory.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/repo/SnapshotCreatorFactory.kt @@ -8,7 +8,6 @@ package com.stevesoltys.seedvault.repo import android.content.Context import com.stevesoltys.seedvault.Clock import com.stevesoltys.seedvault.metadata.MetadataManager -import com.stevesoltys.seedvault.settings.SettingsManager import com.stevesoltys.seedvault.transport.backup.PackageService /** @@ -18,9 +17,8 @@ internal class SnapshotCreatorFactory( private val context: Context, private val clock: Clock, private val packageService: PackageService, - private val settingsManager: SettingsManager, private val metadataManager: MetadataManager, ) { fun createSnapshotCreator() = - SnapshotCreator(context, clock, packageService, settingsManager, metadataManager) + SnapshotCreator(context, clock, packageService, metadataManager) } diff --git a/app/src/main/java/com/stevesoltys/seedvault/restore/AppDataRestoreManager.kt b/app/src/main/java/com/stevesoltys/seedvault/restore/AppDataRestoreManager.kt index 33c8333f..2180d140 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/restore/AppDataRestoreManager.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/restore/AppDataRestoreManager.kt @@ -27,7 +27,6 @@ import com.stevesoltys.seedvault.backend.BackendManager import com.stevesoltys.seedvault.metadata.PackageMetadataMap import com.stevesoltys.seedvault.metadata.PackageState import com.stevesoltys.seedvault.restore.install.isInstalled -import com.stevesoltys.seedvault.settings.SettingsManager import com.stevesoltys.seedvault.transport.TRANSPORT_ID import com.stevesoltys.seedvault.transport.restore.RestorableBackup import com.stevesoltys.seedvault.transport.restore.RestoreCoordinator @@ -55,7 +54,6 @@ internal data class AppRestoreResult( internal class AppDataRestoreManager( private val context: Context, private val backupManager: IBackupManager, - private val settingsManager: SettingsManager, private val restoreCoordinator: RestoreCoordinator, private val backendManager: BackendManager, ) { diff --git a/app/src/main/java/com/stevesoltys/seedvault/restore/AppSelectionManager.kt b/app/src/main/java/com/stevesoltys/seedvault/restore/AppSelectionManager.kt index df147077..52c03d3d 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/restore/AppSelectionManager.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/restore/AppSelectionManager.kt @@ -96,7 +96,7 @@ internal class AppSelectionManager( val backend = backendManager.backend val token = restorableBackup.token backend.load(LegacyAppBackupFile.IconsFile(token)).use { - iconManager.downloadIconsV1(restorableBackup.version, token, it) + iconManager.downloadIconsV1(token, it) } } else if (restorableBackup.version >= 2) { val repoId = restorableBackup.repoId ?: error("No repoId in v2 backup") diff --git a/app/src/main/java/com/stevesoltys/seedvault/restore/RestoreViewModel.kt b/app/src/main/java/com/stevesoltys/seedvault/restore/RestoreViewModel.kt index cad46317..f9112cb0 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/restore/RestoreViewModel.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/restore/RestoreViewModel.kt @@ -83,7 +83,7 @@ internal class RestoreViewModel( private val appSelectionManager = AppSelectionManager(app, backendManager, iconManager, viewModelScope) private val appDataRestoreManager = AppDataRestoreManager( - app, backupManager, settingsManager, restoreCoordinator, backendManager + app, backupManager, restoreCoordinator, backendManager ) private val mDisplayFragment = MutableLiveEvent() 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 b6ceed1d..0e82ee67 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 @@ -21,15 +21,15 @@ import com.stevesoltys.seedvault.crypto.Crypto import com.stevesoltys.seedvault.encodeBase64 import com.stevesoltys.seedvault.metadata.ApkSplit import com.stevesoltys.seedvault.metadata.PackageMetadata +import com.stevesoltys.seedvault.repo.Loader +import com.stevesoltys.seedvault.repo.getBlobHandles import com.stevesoltys.seedvault.restore.RestoreService import com.stevesoltys.seedvault.restore.install.ApkInstallState.FAILED import com.stevesoltys.seedvault.restore.install.ApkInstallState.FAILED_SYSTEM_APP import com.stevesoltys.seedvault.restore.install.ApkInstallState.IN_PROGRESS import com.stevesoltys.seedvault.restore.install.ApkInstallState.QUEUED import com.stevesoltys.seedvault.restore.install.ApkInstallState.SUCCEEDED -import com.stevesoltys.seedvault.repo.getBlobHandles import com.stevesoltys.seedvault.transport.backup.isSystemApp -import com.stevesoltys.seedvault.repo.Loader import com.stevesoltys.seedvault.transport.restore.RestorableBackup import com.stevesoltys.seedvault.worker.hashSignature import kotlinx.coroutines.TimeoutCancellationException diff --git a/app/src/main/java/com/stevesoltys/seedvault/restore/install/InstallProgressAdapter.kt b/app/src/main/java/com/stevesoltys/seedvault/restore/install/InstallProgressAdapter.kt index e92a4f7b..0a14703d 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/restore/install/InstallProgressAdapter.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/restore/install/InstallProgressAdapter.kt @@ -84,7 +84,7 @@ internal class InstallProgressAdapter( if (item.icon == null) iconJob = scope.launch { iconLoader(item, appIcon::setImageDrawable) } else appIcon.setImageDrawable(item.icon) - appName.text = item.name ?: getAppName(v.context, item.packageName.toString()) + appName.text = item.name ?: getAppName(v.context, item.packageName) appInfo.visibility = GONE when (item.state) { IN_PROGRESS -> { diff --git a/app/src/main/java/com/stevesoltys/seedvault/settings/AppListRetriever.kt b/app/src/main/java/com/stevesoltys/seedvault/settings/AppListRetriever.kt index 38336882..66a43275 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/settings/AppListRetriever.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/settings/AppListRetriever.kt @@ -80,8 +80,7 @@ internal class AppListRetriever( AppStatus( packageName = packageName, enabled = settingsManager.isBackupEnabled(packageName), - icon = data.iconRes?.let { getDrawable(context, it) } - ?: getIconFromPackageManager(packageName), + icon = getDrawable(context, data.iconRes) ?: getIconFromPackageManager(packageName), name = context.getString(data.nameRes), time = metadata?.time ?: 0, size = metadata?.size, diff --git a/app/src/main/java/com/stevesoltys/seedvault/settings/SchedulingFragment.kt b/app/src/main/java/com/stevesoltys/seedvault/settings/SchedulingFragment.kt index 387e440c..d36f3522 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/settings/SchedulingFragment.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/settings/SchedulingFragment.kt @@ -16,8 +16,8 @@ import androidx.preference.PreferenceManager import androidx.work.ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE import androidx.work.ExistingPeriodicWorkPolicy.UPDATE import com.stevesoltys.seedvault.R -import com.stevesoltys.seedvault.permitDiskReads import com.stevesoltys.seedvault.backend.BackendManager +import com.stevesoltys.seedvault.permitDiskReads import com.stevesoltys.seedvault.settings.preference.M3ListPreference import org.koin.android.ext.android.inject import org.koin.androidx.viewmodel.ext.android.sharedViewModel diff --git a/app/src/main/java/com/stevesoltys/seedvault/settings/SettingsViewModel.kt b/app/src/main/java/com/stevesoltys/seedvault/settings/SettingsViewModel.kt index bb1f10bb..872804a4 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/settings/SettingsViewModel.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/settings/SettingsViewModel.kt @@ -35,12 +35,10 @@ import androidx.work.ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE import androidx.work.WorkManager import com.stevesoltys.seedvault.BackupStateManager import com.stevesoltys.seedvault.R -import com.stevesoltys.seedvault.crypto.KeyManager -import com.stevesoltys.seedvault.metadata.MetadataManager -import com.stevesoltys.seedvault.permitDiskReads import com.stevesoltys.seedvault.backend.BackendManager +import com.stevesoltys.seedvault.crypto.KeyManager +import com.stevesoltys.seedvault.permitDiskReads import com.stevesoltys.seedvault.storage.StorageBackupJobService -import com.stevesoltys.seedvault.transport.backup.BackupInitializer import com.stevesoltys.seedvault.ui.LiveEvent import com.stevesoltys.seedvault.ui.MutableLiveEvent import com.stevesoltys.seedvault.ui.RequireProvisioningViewModel @@ -68,11 +66,9 @@ internal class SettingsViewModel( settingsManager: SettingsManager, keyManager: KeyManager, backendManager: BackendManager, - private val metadataManager: MetadataManager, private val appListRetriever: AppListRetriever, private val storageBackup: StorageBackup, private val backupManager: IBackupManager, - private val backupInitializer: BackupInitializer, backupStateManager: BackupStateManager, ) : RequireProvisioningViewModel(app, settingsManager, keyManager, backendManager) { diff --git a/app/src/main/java/com/stevesoltys/seedvault/storage/StorageModule.kt b/app/src/main/java/com/stevesoltys/seedvault/storage/StorageModule.kt index 72bc7c0b..490bb53e 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/storage/StorageModule.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/storage/StorageModule.kt @@ -5,8 +5,8 @@ package com.stevesoltys.seedvault.storage -import com.stevesoltys.seedvault.crypto.KeyManager import com.stevesoltys.seedvault.backend.BackendManager +import com.stevesoltys.seedvault.crypto.KeyManager import org.calyxos.backup.storage.api.StorageBackup import org.koin.dsl.module diff --git a/app/src/main/java/com/stevesoltys/seedvault/transport/ConfigurableBackupTransport.kt b/app/src/main/java/com/stevesoltys/seedvault/transport/ConfigurableBackupTransport.kt index e5dbe02c..02c8c5b3 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/transport/ConfigurableBackupTransport.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/transport/ConfigurableBackupTransport.kt @@ -17,7 +17,6 @@ import android.os.ParcelFileDescriptor import android.util.Log import com.stevesoltys.seedvault.R import com.stevesoltys.seedvault.settings.SettingsActivity -import com.stevesoltys.seedvault.settings.SettingsManager import com.stevesoltys.seedvault.transport.backup.BackupCoordinator import com.stevesoltys.seedvault.transport.restore.RestoreCoordinator import kotlinx.coroutines.runBlocking @@ -43,7 +42,6 @@ class ConfigurableBackupTransport internal constructor(private val context: Cont private val backupCoordinator by inject() private val restoreCoordinator by inject() - private val settingsManager by inject() override fun transportDirName(): String { return TRANSPORT_DIRECTORY_NAME 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 291c6df4..1fdcf070 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 @@ -20,7 +20,6 @@ import android.content.pm.PackageInfo import android.os.ParcelFileDescriptor import android.util.Log import androidx.annotation.WorkerThread -import com.stevesoltys.seedvault.Clock import com.stevesoltys.seedvault.backend.BackendManager import com.stevesoltys.seedvault.metadata.BackupType import com.stevesoltys.seedvault.metadata.MetadataManager @@ -64,14 +63,12 @@ internal class BackupCoordinator( private val appBackupManager: AppBackupManager, private val kv: KVBackup, private val full: FullBackup, - private val clock: Clock, private val packageService: PackageService, private val metadataManager: MetadataManager, private val settingsManager: SettingsManager, private val nm: BackupNotificationManager, ) { - private val backend get() = backendManager.backend private val snapshotCreator get() = appBackupManager.snapshotCreator ?: error("No SnapshotCreator") private val state = CoordinatorState( @@ -92,6 +89,8 @@ internal class BackupCoordinator( * * If the transport returns anything other than [TRANSPORT_OK] from this method, * the OS will halt the current initialize operation and schedule a retry in the near future. + * Attention: [finishBackup] will not be called in this case. + * * Even if the transport is in a state * such that attempting to "initialize" the backend storage is meaningless - * for example, if there is no current live data-set at all, @@ -103,12 +102,8 @@ internal class BackupCoordinator( * [TRANSPORT_ERROR] (to retry following network error or other failure). */ fun initializeDevice(): Int { - // we don't respect the intended system behavior here by always starting a new [RestoreSet] - // instead of simply deleting the current one Log.i(TAG, "Initialize Device!") - - // [finishBackup] will only be called when we return [TRANSPORT_OK] here - // so we remember that we initialized successfully + // we don't respect the intended system behavior of erasing all stored data state.calledInitialize = true return TRANSPORT_OK } diff --git a/app/src/main/java/com/stevesoltys/seedvault/transport/backup/BackupModule.kt b/app/src/main/java/com/stevesoltys/seedvault/transport/backup/BackupModule.kt index 318c7a16..dda4b55d 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/transport/backup/BackupModule.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/transport/backup/BackupModule.kt @@ -41,7 +41,6 @@ val backupModule = module { appBackupManager = get(), kv = get(), full = get(), - clock = get(), packageService = get(), metadataManager = get(), settingsManager = get(), diff --git a/app/src/main/java/com/stevesoltys/seedvault/transport/backup/FullBackup.kt b/app/src/main/java/com/stevesoltys/seedvault/transport/backup/FullBackup.kt index d23a6445..f90ca2f2 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/transport/backup/FullBackup.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/transport/backup/FullBackup.kt @@ -138,14 +138,15 @@ internal class FullBackup( suspend fun cancelFullBackup() { val state = this.state ?: error("No state when canceling") Log.i(TAG, "Cancel full backup for ${state.packageName}") - // TODO check if worth keeping the blobs. they've been uploaded already and may be re-usable - // so we could add them to the snapshot's blobMap or just let prune remove them at the end + // finalize the receiver try { backupReceiver.finalize(getOwner(state.packageName)) } catch (e: Exception) { // as the backup was cancelled anyway, we don't care if finalizing had an error Log.e(TAG, "Error finalizing backup in cancelFullBackup().", e) } + // If the transport receives this callback, it will *not* receive a call to [finishBackup]. + // It needs to tear down any ongoing backup state here. clearState() } diff --git a/app/src/main/java/com/stevesoltys/seedvault/transport/backup/PackageService.kt b/app/src/main/java/com/stevesoltys/seedvault/transport/backup/PackageService.kt index 4e0da947..0e072bdb 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/transport/backup/PackageService.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/transport/backup/PackageService.kt @@ -125,11 +125,6 @@ internal class PackageService( packageInfo.allowsBackup() } - /** - * A list of apps that do not allow backup. - */ - val userNotAllowedApps: List = emptyList() - val launchableSystemApps: List @WorkerThread get() { diff --git a/app/src/main/java/com/stevesoltys/seedvault/ui/notification/NotificationBackupObserver.kt b/app/src/main/java/com/stevesoltys/seedvault/ui/notification/NotificationBackupObserver.kt index fece4e96..ba0e2b54 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/ui/notification/NotificationBackupObserver.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/ui/notification/NotificationBackupObserver.kt @@ -18,11 +18,10 @@ import android.util.Log.isLoggable import com.stevesoltys.seedvault.ERROR_BACKUP_CANCELLED import com.stevesoltys.seedvault.MAGIC_PACKAGE_MANAGER import com.stevesoltys.seedvault.R -import com.stevesoltys.seedvault.metadata.MetadataManager -import com.stevesoltys.seedvault.settings.SettingsManager import com.stevesoltys.seedvault.repo.AppBackupManager -import com.stevesoltys.seedvault.transport.backup.PackageService import com.stevesoltys.seedvault.repo.hexFromProto +import com.stevesoltys.seedvault.settings.SettingsManager +import com.stevesoltys.seedvault.transport.backup.PackageService import com.stevesoltys.seedvault.worker.AppBackupPruneWorker import com.stevesoltys.seedvault.worker.BackupRequester import kotlinx.coroutines.runBlocking @@ -38,7 +37,6 @@ internal class NotificationBackupObserver( ) : IBackupObserver.Stub(), KoinComponent { private val nm: BackupNotificationManager by inject() - private val metadataManager: MetadataManager by inject() private val packageService: PackageService by inject() private val settingsManager: SettingsManager by inject() private val appBackupManager: AppBackupManager by inject() @@ -153,7 +151,7 @@ internal class NotificationBackupObserver( success = snapshot != null snapshot } - val size = if (snapshot != null) { // TODO count size of APKs separately + val size = if (snapshot != null) { // TODO for later: count size of APKs separately val chunkIds = snapshot.appsMap.values.flatMap { it.chunkIdsList } chunkIds.sumOf { snapshot.blobsMap[it.hexFromProto()]?.uncompressedLength?.toLong() ?: 0L diff --git a/app/src/main/java/com/stevesoltys/seedvault/ui/storage/BackupStorageViewModel.kt b/app/src/main/java/com/stevesoltys/seedvault/ui/storage/BackupStorageViewModel.kt index b3cf1cc4..c57c7250 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/ui/storage/BackupStorageViewModel.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/ui/storage/BackupStorageViewModel.kt @@ -16,7 +16,6 @@ import com.stevesoltys.seedvault.R import com.stevesoltys.seedvault.backend.BackendManager import com.stevesoltys.seedvault.backend.saf.SafHandler import com.stevesoltys.seedvault.backend.webdav.WebDavHandler -import org.calyxos.seedvault.core.backends.webdav.WebDavProperties import com.stevesoltys.seedvault.settings.SettingsManager import com.stevesoltys.seedvault.storage.StorageBackupJobService import com.stevesoltys.seedvault.transport.backup.BackupInitializer @@ -28,6 +27,7 @@ import org.calyxos.backup.storage.api.StorageBackup import org.calyxos.backup.storage.backup.BackupJobService import org.calyxos.seedvault.core.backends.Backend import org.calyxos.seedvault.core.backends.saf.SafProperties +import org.calyxos.seedvault.core.backends.webdav.WebDavProperties import java.io.IOException import java.util.concurrent.TimeUnit diff --git a/app/src/main/java/com/stevesoltys/seedvault/ui/storage/StorageActivity.kt b/app/src/main/java/com/stevesoltys/seedvault/ui/storage/StorageActivity.kt index f3f2244a..f4d607b9 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/ui/storage/StorageActivity.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/ui/storage/StorageActivity.kt @@ -24,8 +24,6 @@ import com.stevesoltys.seedvault.ui.INTENT_EXTRA_IS_RESTORE import com.stevesoltys.seedvault.ui.INTENT_EXTRA_IS_SETUP_WIZARD import org.koin.androidx.viewmodel.ext.android.getViewModel -private val TAG = StorageActivity::class.java.name - class StorageActivity : BackupActivity() { private lateinit var viewModel: StorageViewModel diff --git a/app/src/main/java/com/stevesoltys/seedvault/ui/storage/StorageViewModel.kt b/app/src/main/java/com/stevesoltys/seedvault/ui/storage/StorageViewModel.kt index 79a843fc..ed85bdde 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/ui/storage/StorageViewModel.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/ui/storage/StorageViewModel.kt @@ -16,7 +16,6 @@ import com.stevesoltys.seedvault.R import com.stevesoltys.seedvault.backend.BackendManager import com.stevesoltys.seedvault.backend.saf.SafHandler import com.stevesoltys.seedvault.backend.webdav.WebDavHandler -import org.calyxos.seedvault.core.backends.webdav.WebDavProperties import com.stevesoltys.seedvault.settings.SettingsManager import com.stevesoltys.seedvault.ui.LiveEvent import com.stevesoltys.seedvault.ui.MutableLiveEvent @@ -26,6 +25,7 @@ import kotlinx.coroutines.launch import org.calyxos.seedvault.core.backends.Backend import org.calyxos.seedvault.core.backends.saf.SafProperties import org.calyxos.seedvault.core.backends.webdav.WebDavConfig +import org.calyxos.seedvault.core.backends.webdav.WebDavProperties internal abstract class StorageViewModel( private val app: Application, @@ -48,8 +48,6 @@ internal abstract class StorageViewModel( private var safOption: SafOption? = null internal var isSetupWizard: Boolean = false - internal val hasStorageSet: Boolean - get() = backendManager.backendProperties != null abstract val isRestoreOperation: Boolean internal fun loadStorageRoots() { diff --git a/app/src/main/java/com/stevesoltys/seedvault/worker/ApkBackup.kt b/app/src/main/java/com/stevesoltys/seedvault/worker/ApkBackup.kt index 120f66c3..1176d194 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/worker/ApkBackup.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/worker/ApkBackup.kt @@ -17,11 +17,11 @@ import com.stevesoltys.seedvault.proto.Snapshot import com.stevesoltys.seedvault.proto.Snapshot.Apk import com.stevesoltys.seedvault.proto.Snapshot.Blob import com.stevesoltys.seedvault.proto.SnapshotKt.split -import com.stevesoltys.seedvault.settings.SettingsManager import com.stevesoltys.seedvault.repo.AppBackupManager import com.stevesoltys.seedvault.repo.BackupReceiver import com.stevesoltys.seedvault.repo.forProto import com.stevesoltys.seedvault.repo.hexFromProto +import com.stevesoltys.seedvault.settings.SettingsManager import com.stevesoltys.seedvault.transport.backup.isNotUpdatedSystemApp import com.stevesoltys.seedvault.transport.backup.isTestOnly import org.calyxos.seedvault.core.toHexString diff --git a/app/src/main/java/com/stevesoltys/seedvault/worker/AppBackupPruneWorker.kt b/app/src/main/java/com/stevesoltys/seedvault/worker/AppBackupPruneWorker.kt index 5ca30488..a7446326 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/worker/AppBackupPruneWorker.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/worker/AppBackupPruneWorker.kt @@ -8,7 +8,7 @@ package com.stevesoltys.seedvault.worker import android.content.Context import android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC import android.util.Log -import androidx.work.BackoffPolicy +import androidx.work.BackoffPolicy.EXPONENTIAL import androidx.work.CoroutineWorker import androidx.work.ExistingWorkPolicy.REPLACE import androidx.work.ForegroundInfo @@ -36,7 +36,7 @@ class AppBackupPruneWorker( fun scheduleNow(context: Context) { val workRequest = OneTimeWorkRequestBuilder() .setExpedited(RUN_AS_NON_EXPEDITED_WORK_REQUEST) - .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, Duration.ofSeconds(10)) + .setBackoffCriteria(EXPONENTIAL, Duration.ofSeconds(10)) .build() val workManager = WorkManager.getInstance(context) Log.i(TAG, "Asking to prune app backups now...") diff --git a/app/src/main/java/com/stevesoltys/seedvault/worker/AppBackupWorker.kt b/app/src/main/java/com/stevesoltys/seedvault/worker/AppBackupWorker.kt index f2cc6c4e..dd07d77e 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/worker/AppBackupWorker.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/worker/AppBackupWorker.kt @@ -24,8 +24,8 @@ import androidx.work.WorkManager import androidx.work.WorkerParameters import com.stevesoltys.seedvault.R import com.stevesoltys.seedvault.backend.BackendManager -import com.stevesoltys.seedvault.settings.SettingsManager import com.stevesoltys.seedvault.repo.AppBackupManager +import com.stevesoltys.seedvault.settings.SettingsManager import com.stevesoltys.seedvault.ui.notification.BackupNotificationManager import com.stevesoltys.seedvault.ui.notification.NOTIFICATION_ID_OBSERVER import org.koin.core.component.KoinComponent diff --git a/app/src/main/java/com/stevesoltys/seedvault/worker/IconManager.kt b/app/src/main/java/com/stevesoltys/seedvault/worker/IconManager.kt index fc1ffe5c..41598d00 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/worker/IconManager.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/worker/IconManager.kt @@ -20,8 +20,8 @@ import com.stevesoltys.seedvault.crypto.TYPE_ICONS import com.stevesoltys.seedvault.proto.Snapshot import com.stevesoltys.seedvault.repo.AppBackupManager import com.stevesoltys.seedvault.repo.BackupReceiver -import com.stevesoltys.seedvault.transport.backup.PackageService import com.stevesoltys.seedvault.repo.Loader +import com.stevesoltys.seedvault.transport.backup.PackageService import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.calyxos.backup.storage.crypto.StreamCrypto.toByteArray @@ -150,13 +150,13 @@ internal class IconManager( */ @Suppress("DEPRECATION") @Throws(IOException::class, SecurityException::class, GeneralSecurityException::class) - fun downloadIconsV1(version: Byte, token: Long, inputStream: InputStream): Set { + fun downloadIconsV1(token: Long, inputStream: InputStream): Set { Log.d(TAG, "Start downloading icons") val folder = File(context.cacheDir, CACHE_FOLDER) if (!folder.isDirectory && !folder.mkdirs()) throw IOException("Can't create cache folder for icons") val set = mutableSetOf() - crypto.newDecryptingStreamV1(inputStream, getAD(version, token)).use { cryptoStream -> + crypto.newDecryptingStreamV1(inputStream, getAD(1.toByte(), token)).use { cryptoStream -> ZipInputStream(cryptoStream).use { zip -> var entry = zip.nextEntry while (entry != null) { diff --git a/app/src/test/java/com/stevesoltys/seedvault/crypto/CryptoIntegrationTest.kt b/app/src/test/java/com/stevesoltys/seedvault/crypto/CryptoIntegrationTest.kt index 6062d5a2..ead162f0 100644 --- a/app/src/test/java/com/stevesoltys/seedvault/crypto/CryptoIntegrationTest.kt +++ b/app/src/test/java/com/stevesoltys/seedvault/crypto/CryptoIntegrationTest.kt @@ -21,7 +21,6 @@ import java.io.ByteArrayOutputStream import java.io.IOException import kotlin.random.Random -@Suppress("DEPRECATION") @TestInstance(PER_METHOD) class CryptoIntegrationTest { @@ -41,17 +40,6 @@ class CryptoIntegrationTest { assertThat(crypto.getRandomBytes(42), not(equalTo(crypto.getRandomBytes(42)))) } - @Test - fun `decrypting encrypted cleartext works v1`() { - val ad = Random.nextBytes(42) - val outputStream = ByteArrayOutputStream() - crypto.newEncryptingStreamV1(outputStream, ad).use { it.write(cleartext) } - val inputStream = ByteArrayInputStream(outputStream.toByteArray()) - crypto.newDecryptingStreamV1(inputStream, ad).use { - assertReadEquals(cleartext, it) - } - } - @Test fun `decrypting encrypted cleartext works v2`() { val ad = Random.nextBytes(42) @@ -63,18 +51,6 @@ class CryptoIntegrationTest { } } - @Test - fun `decrypting encrypted cleartext fails with different AD v1`() { - val outputStream = ByteArrayOutputStream() - crypto.newEncryptingStreamV1(outputStream, Random.nextBytes(42)).use { it.write(cleartext) } - val inputStream = ByteArrayInputStream(outputStream.toByteArray()) - assertThrows(IOException::class.java) { - crypto.newDecryptingStreamV1(inputStream, Random.nextBytes(41)).use { - it.read() - } - } - } - @Test fun `decrypting encrypted cleartext fails with different AD v2`() { val outputStream = ByteArrayOutputStream() diff --git a/app/src/test/java/com/stevesoltys/seedvault/crypto/KeyManagerImplTest.kt b/app/src/test/java/com/stevesoltys/seedvault/crypto/KeyManagerImplTest.kt index c91df607..c42b83f4 100644 --- a/app/src/test/java/com/stevesoltys/seedvault/crypto/KeyManagerImplTest.kt +++ b/app/src/test/java/com/stevesoltys/seedvault/crypto/KeyManagerImplTest.kt @@ -11,8 +11,8 @@ import io.mockk.every import io.mockk.just import io.mockk.mockk import io.mockk.slot -import junit.framework.Assert.assertTrue -import org.junit.Assert.assertArrayEquals +import org.junit.jupiter.api.Assertions.assertArrayEquals +import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.TestInstance.Lifecycle.PER_METHOD diff --git a/app/src/test/java/com/stevesoltys/seedvault/metadata/MetadataManagerTest.kt b/app/src/test/java/com/stevesoltys/seedvault/metadata/MetadataManagerTest.kt index 152d93d0..07355489 100644 --- a/app/src/test/java/com/stevesoltys/seedvault/metadata/MetadataManagerTest.kt +++ b/app/src/test/java/com/stevesoltys/seedvault/metadata/MetadataManagerTest.kt @@ -21,7 +21,6 @@ import com.stevesoltys.seedvault.metadata.PackageState.APK_AND_DATA import com.stevesoltys.seedvault.metadata.PackageState.NOT_ALLOWED import com.stevesoltys.seedvault.metadata.PackageState.NO_DATA import com.stevesoltys.seedvault.metadata.PackageState.WAS_STOPPED -import com.stevesoltys.seedvault.settings.SettingsManager import io.mockk.Runs import io.mockk.every import io.mockk.just @@ -49,7 +48,6 @@ class MetadataManagerTest { private val clock: Clock = mockk() private val metadataWriter: MetadataWriter = mockk() private val metadataReader: MetadataReader = mockk() - private val settingsManager: SettingsManager = mockk() private val manager = MetadataManager( context = context, diff --git a/app/src/test/java/com/stevesoltys/seedvault/repo/BackupReceiverTest.kt b/app/src/test/java/com/stevesoltys/seedvault/repo/BackupReceiverTest.kt index d7f72f4a..384dce23 100644 --- a/app/src/test/java/com/stevesoltys/seedvault/repo/BackupReceiverTest.kt +++ b/app/src/test/java/com/stevesoltys/seedvault/repo/BackupReceiverTest.kt @@ -86,7 +86,7 @@ internal class BackupReceiverTest : TransportTest() { } @Test - fun `readFromStream`() = runBlocking { + fun readFromStream() = runBlocking { val bytes = getRandomByteArray() val chunkBytes1 = getRandomByteArray() val chunkBytes2 = getRandomByteArray() diff --git a/app/src/test/java/com/stevesoltys/seedvault/repo/SnapshotCreatorTest.kt b/app/src/test/java/com/stevesoltys/seedvault/repo/SnapshotCreatorTest.kt index 6affd484..d4e4005a 100644 --- a/app/src/test/java/com/stevesoltys/seedvault/repo/SnapshotCreatorTest.kt +++ b/app/src/test/java/com/stevesoltys/seedvault/repo/SnapshotCreatorTest.kt @@ -38,8 +38,7 @@ internal class SnapshotCreatorTest : TransportTest() { private val ctx: Context = ApplicationProvider.getApplicationContext() private val packageService: PackageService = mockk() - private val snapshotCreator = - SnapshotCreator(ctx, clock, packageService, settingsManager, metadataManager) + private val snapshotCreator = SnapshotCreator(ctx, clock, packageService, metadataManager) @Test fun `test onApkBackedUp`() { diff --git a/app/src/test/java/com/stevesoltys/seedvault/restore/install/ApkBackupRestoreTest.kt b/app/src/test/java/com/stevesoltys/seedvault/restore/install/ApkBackupRestoreTest.kt index 1e291836..874b3ed2 100644 --- a/app/src/test/java/com/stevesoltys/seedvault/restore/install/ApkBackupRestoreTest.kt +++ b/app/src/test/java/com/stevesoltys/seedvault/restore/install/ApkBackupRestoreTest.kt @@ -22,16 +22,16 @@ import com.stevesoltys.seedvault.getRandomString import com.stevesoltys.seedvault.metadata.PackageMetadata import com.stevesoltys.seedvault.metadata.PackageMetadataMap import com.stevesoltys.seedvault.proto.Snapshot +import com.stevesoltys.seedvault.repo.AppBackupManager +import com.stevesoltys.seedvault.repo.BackupReceiver +import com.stevesoltys.seedvault.repo.Loader +import com.stevesoltys.seedvault.repo.SnapshotCreator +import com.stevesoltys.seedvault.repo.SnapshotManager +import com.stevesoltys.seedvault.repo.hexFromProto import com.stevesoltys.seedvault.restore.install.ApkInstallState.IN_PROGRESS import com.stevesoltys.seedvault.restore.install.ApkInstallState.QUEUED import com.stevesoltys.seedvault.restore.install.ApkInstallState.SUCCEEDED -import com.stevesoltys.seedvault.repo.SnapshotManager import com.stevesoltys.seedvault.transport.TransportTest -import com.stevesoltys.seedvault.repo.AppBackupManager -import com.stevesoltys.seedvault.repo.BackupReceiver -import com.stevesoltys.seedvault.repo.SnapshotCreator -import com.stevesoltys.seedvault.repo.hexFromProto -import com.stevesoltys.seedvault.repo.Loader import com.stevesoltys.seedvault.transport.restore.RestorableBackup import com.stevesoltys.seedvault.worker.ApkBackup import io.mockk.Runs @@ -41,7 +41,6 @@ import io.mockk.just import io.mockk.mockk import io.mockk.mockkStatic import io.mockk.slot - import kotlinx.coroutines.runBlocking import org.calyxos.seedvault.core.backends.AppBackupFileType import org.calyxos.seedvault.core.backends.Backend 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 13f446de..cd12237d 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 @@ -29,15 +29,15 @@ import com.stevesoltys.seedvault.metadata.PackageMetadataMap import com.stevesoltys.seedvault.proto.SnapshotKt.blob import com.stevesoltys.seedvault.proto.SnapshotKt.split import com.stevesoltys.seedvault.proto.copy -import com.stevesoltys.seedvault.transport.restore.RestorableBackup +import com.stevesoltys.seedvault.repo.Loader +import com.stevesoltys.seedvault.repo.hexFromProto import com.stevesoltys.seedvault.restore.install.ApkInstallState.FAILED import com.stevesoltys.seedvault.restore.install.ApkInstallState.FAILED_SYSTEM_APP import com.stevesoltys.seedvault.restore.install.ApkInstallState.IN_PROGRESS import com.stevesoltys.seedvault.restore.install.ApkInstallState.QUEUED import com.stevesoltys.seedvault.restore.install.ApkInstallState.SUCCEEDED import com.stevesoltys.seedvault.transport.TransportTest -import com.stevesoltys.seedvault.repo.hexFromProto -import com.stevesoltys.seedvault.repo.Loader +import com.stevesoltys.seedvault.transport.restore.RestorableBackup import io.mockk.Runs import io.mockk.coEvery import io.mockk.every diff --git a/app/src/test/java/com/stevesoltys/seedvault/restore/install/ApkRestoreV1Test.kt b/app/src/test/java/com/stevesoltys/seedvault/restore/install/ApkRestoreV1Test.kt index 82c40490..af11f10c 100644 --- a/app/src/test/java/com/stevesoltys/seedvault/restore/install/ApkRestoreV1Test.kt +++ b/app/src/test/java/com/stevesoltys/seedvault/restore/install/ApkRestoreV1Test.kt @@ -26,14 +26,14 @@ import com.stevesoltys.seedvault.getRandomString import com.stevesoltys.seedvault.metadata.ApkSplit import com.stevesoltys.seedvault.metadata.PackageMetadata import com.stevesoltys.seedvault.metadata.PackageMetadataMap -import com.stevesoltys.seedvault.transport.restore.RestorableBackup +import com.stevesoltys.seedvault.repo.Loader import com.stevesoltys.seedvault.restore.install.ApkInstallState.FAILED import com.stevesoltys.seedvault.restore.install.ApkInstallState.FAILED_SYSTEM_APP import com.stevesoltys.seedvault.restore.install.ApkInstallState.IN_PROGRESS import com.stevesoltys.seedvault.restore.install.ApkInstallState.QUEUED import com.stevesoltys.seedvault.restore.install.ApkInstallState.SUCCEEDED import com.stevesoltys.seedvault.transport.TransportTest -import com.stevesoltys.seedvault.repo.Loader +import com.stevesoltys.seedvault.transport.restore.RestorableBackup import io.mockk.Runs import io.mockk.coEvery import io.mockk.every diff --git a/app/src/test/java/com/stevesoltys/seedvault/restore/install/ApkSplitCompatibilityCheckerTest.kt b/app/src/test/java/com/stevesoltys/seedvault/restore/install/ApkSplitCompatibilityCheckerTest.kt index f142ba5f..996def8f 100644 --- a/app/src/test/java/com/stevesoltys/seedvault/restore/install/ApkSplitCompatibilityCheckerTest.kt +++ b/app/src/test/java/com/stevesoltys/seedvault/restore/install/ApkSplitCompatibilityCheckerTest.kt @@ -9,9 +9,9 @@ import com.stevesoltys.seedvault.getRandomString import com.stevesoltys.seedvault.transport.TransportTest import io.mockk.every import io.mockk.mockk -import org.junit.Assert.assertEquals -import org.junit.Assert.assertFalse -import org.junit.Assert.assertTrue +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test import kotlin.random.Random diff --git a/app/src/test/java/com/stevesoltys/seedvault/transport/CoordinatorIntegrationTest.kt b/app/src/test/java/com/stevesoltys/seedvault/transport/CoordinatorIntegrationTest.kt index f3d1f0f3..950451b2 100644 --- a/app/src/test/java/com/stevesoltys/seedvault/transport/CoordinatorIntegrationTest.kt +++ b/app/src/test/java/com/stevesoltys/seedvault/transport/CoordinatorIntegrationTest.kt @@ -93,16 +93,15 @@ internal class CoordinatorIntegrationTest : TransportTest() { ) private val packageService: PackageService = mockk() private val backup = BackupCoordinator( - context, - backendManager, - appBackupManager, - kvBackup, - fullBackup, - clock, - packageService, - metadataManager, - settingsManager, - notificationManager + context = context, + backendManager = backendManager, + appBackupManager = appBackupManager, + kv = kvBackup, + full = fullBackup, + packageService = packageService, + metadataManager = metadataManager, + settingsManager = settingsManager, + nm = notificationManager, ) private val kvRestore = KVRestore( diff --git a/app/src/test/java/com/stevesoltys/seedvault/transport/backup/BackupCoordinatorTest.kt b/app/src/test/java/com/stevesoltys/seedvault/transport/backup/BackupCoordinatorTest.kt index 30c5cf62..b2e40835 100644 --- a/app/src/test/java/com/stevesoltys/seedvault/transport/backup/BackupCoordinatorTest.kt +++ b/app/src/test/java/com/stevesoltys/seedvault/transport/backup/BackupCoordinatorTest.kt @@ -13,7 +13,6 @@ import android.os.ParcelFileDescriptor import com.stevesoltys.seedvault.backend.BackendManager import com.stevesoltys.seedvault.getRandomString import com.stevesoltys.seedvault.metadata.BackupType -import com.stevesoltys.seedvault.metadata.PackageMetadata import com.stevesoltys.seedvault.metadata.PackageState.NO_DATA import com.stevesoltys.seedvault.metadata.PackageState.QUOTA_EXCEEDED import com.stevesoltys.seedvault.metadata.PackageState.UNKNOWN_ERROR @@ -51,7 +50,6 @@ internal class BackupCoordinatorTest : BackupTest() { appBackupManager = appBackupManager, kv = kv, full = full, - clock = clock, packageService = packageService, metadataManager = metadataManager, settingsManager = settingsManager, @@ -60,7 +58,6 @@ internal class BackupCoordinatorTest : BackupTest() { private val backend = mockk() private val fileDescriptor: ParcelFileDescriptor = mockk() - private val packageMetadata: PackageMetadata = mockk() private val safProperties = SafProperties( config = Uri.EMPTY, name = getRandomString(), diff --git a/app/src/test/java/com/stevesoltys/seedvault/transport/backup/BackupCreationTest.kt b/app/src/test/java/com/stevesoltys/seedvault/transport/backup/BackupCreationTest.kt index 307c7acd..36900de7 100644 --- a/app/src/test/java/com/stevesoltys/seedvault/transport/backup/BackupCreationTest.kt +++ b/app/src/test/java/com/stevesoltys/seedvault/transport/backup/BackupCreationTest.kt @@ -66,7 +66,7 @@ internal class BackupCreationTest : BackupTest() { private val appBackupManager = mockk() private val packageService = mockk() private val snapshotCreator = - SnapshotCreator(context, clock, packageService, settingsManager, mockk(relaxed = true)) + SnapshotCreator(context, clock, packageService, mockk(relaxed = true)) private val notificationManager = mockk() private val db = TestKvDbManager() @@ -80,7 +80,6 @@ internal class BackupCreationTest : BackupTest() { appBackupManager = appBackupManager, kv = kvBackup, full = fullBackup, - clock = clock, packageService = packageService, metadataManager = metadataManager, settingsManager = settingsManager, diff --git a/app/src/test/java/com/stevesoltys/seedvault/transport/restore/RestoreCoordinatorTest.kt b/app/src/test/java/com/stevesoltys/seedvault/transport/restore/RestoreCoordinatorTest.kt index fd468f51..ece36c00 100644 --- a/app/src/test/java/com/stevesoltys/seedvault/transport/restore/RestoreCoordinatorTest.kt +++ b/app/src/test/java/com/stevesoltys/seedvault/transport/restore/RestoreCoordinatorTest.kt @@ -31,7 +31,6 @@ import io.mockk.coVerify import io.mockk.every import io.mockk.just import io.mockk.mockk -import io.mockk.mockkStatic import io.mockk.verify import kotlinx.coroutines.runBlocking import org.calyxos.seedvault.core.backends.AppBackupFileType @@ -90,28 +89,17 @@ internal class RestoreCoordinatorTest : TransportTest() { chunkIds = listOf(chunkId2), ) - mockkStatic("com.stevesoltys.seedvault.backend.BackendExtKt") every { backendManager.backend } returns backend } @Test fun `getAvailableRestoreSets() builds set from plugin response`() = runBlocking { - val info1 = FileInfo(LegacyAppBackupFile.Metadata(token), 1) - val info2 = FileInfo(LegacyAppBackupFile.Metadata(token + 1), 2) + val handle1 = LegacyAppBackupFile.Metadata(token) + val handle2 = LegacyAppBackupFile.Metadata(token + 1) - coEvery { - backend.list( - topLevelFolder = null, - AppBackupFileType.Snapshot::class, LegacyAppBackupFile.Metadata::class, - callback = captureLambda<(FileInfo) -> Unit>() - ) - } answers { - val callback = lambda<(FileInfo) -> Unit>().captured - callback(info1) - callback(info2) - } - coEvery { backend.load(info1.fileHandle) } returns inputStream - coEvery { backend.load(info2.fileHandle) } returns inputStream + coEvery { backend.getAvailableBackupFileHandles() } returns listOf(handle1, handle2) + coEvery { backend.load(handle1) } returns inputStream + coEvery { backend.load(handle2) } returns inputStream every { metadataReader.readMetadata(inputStream, token) } returns metadata every { metadataReader.readMetadata(inputStream, token + 1) } returns metadata every { inputStream.close() } just Runs @@ -146,22 +134,12 @@ internal class RestoreCoordinatorTest : TransportTest() { @Test fun `startRestore() fetches metadata if missing`() = runBlocking { - val info1 = FileInfo(LegacyAppBackupFile.Metadata(token), 1) - val info2 = FileInfo(LegacyAppBackupFile.Metadata(token + 1), 2) + val handle1 = LegacyAppBackupFile.Metadata(token) + val handle2 = LegacyAppBackupFile.Metadata(token + 1) - coEvery { - backend.list( - topLevelFolder = null, - AppBackupFileType.Snapshot::class, LegacyAppBackupFile.Metadata::class, - callback = captureLambda<(FileInfo) -> Unit>() - ) - } answers { - val callback = lambda<(FileInfo) -> Unit>().captured - callback(info1) - callback(info2) - } - coEvery { backend.load(info1.fileHandle) } returns inputStream - coEvery { backend.load(info2.fileHandle) } returns inputStream + coEvery { backend.getAvailableBackupFileHandles() } returns listOf(handle1, handle2) + coEvery { backend.load(handle1) } returns inputStream + coEvery { backend.load(handle2) } returns inputStream every { metadataReader.readMetadata(inputStream, token) } returns metadata every { metadataReader.readMetadata(inputStream, token + 1) } returns metadata every { inputStream.close() } just Runs @@ -273,21 +251,10 @@ internal class RestoreCoordinatorTest : TransportTest() { @Test fun `startRestore() errors when it can't find snapshots`() = runBlocking { val handle = AppBackupFileType.Snapshot(repoId, getRandomByteArray(32).toHexString()) - val info = FileInfo(handle, 1) every { backendManager.backendProperties } returns safStorage every { safStorage.isUnavailableUsb(context) } returns false - - coEvery { - backend.list( - topLevelFolder = null, - AppBackupFileType.Snapshot::class, LegacyAppBackupFile.Metadata::class, - callback = captureLambda<(FileInfo) -> Unit>() - ) - } answers { - val callback = lambda<(FileInfo) -> Unit>().captured - callback(info) - } + coEvery { backend.getAvailableBackupFileHandles() } returns listOf(handle) coEvery { snapshotManager.loadSnapshot(handle) } returns snapshot.copy { token = this@RestoreCoordinatorTest.token - 1 // unexpected token } diff --git a/app/src/test/java/com/stevesoltys/seedvault/worker/ApkBackupTest.kt b/app/src/test/java/com/stevesoltys/seedvault/worker/ApkBackupTest.kt index 05d6f125..2a2011da 100644 --- a/app/src/test/java/com/stevesoltys/seedvault/worker/ApkBackupTest.kt +++ b/app/src/test/java/com/stevesoltys/seedvault/worker/ApkBackupTest.kt @@ -23,8 +23,8 @@ import com.stevesoltys.seedvault.proto.copy import com.stevesoltys.seedvault.repo.AppBackupManager import com.stevesoltys.seedvault.repo.BackupData import com.stevesoltys.seedvault.repo.BackupReceiver -import com.stevesoltys.seedvault.transport.backup.BackupTest import com.stevesoltys.seedvault.repo.SnapshotCreator +import com.stevesoltys.seedvault.transport.backup.BackupTest import io.mockk.Runs import io.mockk.coEvery import io.mockk.coVerify diff --git a/core/src/main/java/org/calyxos/seedvault/core/backends/Constants.kt b/core/src/main/java/org/calyxos/seedvault/core/backends/Constants.kt index 717640ba..08854a55 100644 --- a/core/src/main/java/org/calyxos/seedvault/core/backends/Constants.kt +++ b/core/src/main/java/org/calyxos/seedvault/core/backends/Constants.kt @@ -23,6 +23,5 @@ public object Constants { public val appSnapshotRegex: Regex = Regex("(^[a-f0-9]{64})\\.snapshot$") public val fileSnapshotRegex: Regex = Regex("(^[0-9]{13})\\.SeedSnap$") // good until year 2286 public const val MIME_TYPE: String = "application/octet-stream" - public const val CHUNK_FOLDER_COUNT: Int = 256 } diff --git a/storage/demo/src/main/java/de/grobox/storagebackuptester/backup/BackupStats.kt b/storage/demo/src/main/java/de/grobox/storagebackuptester/backup/BackupStats.kt index e96ab4fd..51d6c91e 100644 --- a/storage/demo/src/main/java/de/grobox/storagebackuptester/backup/BackupStats.kt +++ b/storage/demo/src/main/java/de/grobox/storagebackuptester/backup/BackupStats.kt @@ -16,7 +16,6 @@ import org.calyxos.backup.storage.api.BackupFile import org.calyxos.backup.storage.api.StorageBackup import org.calyxos.backup.storage.backup.NotificationBackupObserver import kotlin.time.DurationUnit -import kotlin.time.ExperimentalTime import kotlin.time.toDuration data class BackupProgress( @@ -91,7 +90,6 @@ internal class BackupStats( liveData.postValue(BackupProgress(filesProcessed, totalFiles, null)) } - @OptIn(ExperimentalTime::class) override suspend fun onBackupComplete(backupDuration: Long?) { super.onBackupComplete(backupDuration) @@ -162,7 +160,6 @@ internal class BackupStats( liveData.postValue(BackupProgress(filesProcessed, totalFiles, text)) } - @OptIn(ExperimentalTime::class) override suspend fun onPruneComplete(pruneDuration: Long) { super.onPruneComplete(pruneDuration) diff --git a/storage/demo/src/main/java/de/grobox/storagebackuptester/crypto/KeyManager.kt b/storage/demo/src/main/java/de/grobox/storagebackuptester/crypto/KeyManager.kt index 3a0e077a..1554912c 100644 --- a/storage/demo/src/main/java/de/grobox/storagebackuptester/crypto/KeyManager.kt +++ b/storage/demo/src/main/java/de/grobox/storagebackuptester/crypto/KeyManager.kt @@ -10,17 +10,17 @@ import android.security.keystore.KeyProperties.PURPOSE_ENCRYPT import android.security.keystore.KeyProperties.PURPOSE_SIGN import android.security.keystore.KeyProperties.PURPOSE_VERIFY import android.security.keystore.KeyProtection +import org.calyxos.seedvault.core.crypto.CoreCrypto.ALGORITHM_HMAC import java.security.KeyStore import javax.crypto.SecretKey import javax.crypto.spec.SecretKeySpec -object KeyManager: org.calyxos.seedvault.core.crypto.KeyManager { +object KeyManager : org.calyxos.seedvault.core.crypto.KeyManager { private const val KEY_SIZE = 256 - internal const val KEY_SIZE_BYTES = KEY_SIZE / 8 + private const val KEY_SIZE_BYTES = KEY_SIZE / 8 private const val KEY_ALIAS_MASTER = "com.stevesoltys.seedvault.master" private const val ANDROID_KEY_STORE = "AndroidKeyStore" - private const val ALGORITHM_HMAC = "HmacSHA256" private const val FAKE_SEED = "This is a legacy backup key 1234" diff --git a/storage/demo/src/main/java/de/grobox/storagebackuptester/scanner/DocumentScanner.kt b/storage/demo/src/main/java/de/grobox/storagebackuptester/scanner/DocumentScanner.kt index ad44f046..fa19c358 100644 --- a/storage/demo/src/main/java/de/grobox/storagebackuptester/scanner/DocumentScanner.kt +++ b/storage/demo/src/main/java/de/grobox/storagebackuptester/scanner/DocumentScanner.kt @@ -14,10 +14,8 @@ import org.calyxos.backup.storage.api.BackupFile import org.calyxos.backup.storage.scanner.DocumentScanner import java.text.SimpleDateFormat import java.util.Date -import kotlin.time.ExperimentalTime import kotlin.time.measureTimedValue -@OptIn(ExperimentalTime::class) fun scanTree(context: Context, documentScanner: DocumentScanner, treeUri: Uri): String { val sb = StringBuilder() val timedResult = measureTimedValue { diff --git a/storage/demo/src/main/java/de/grobox/storagebackuptester/scanner/MediaScanner.kt b/storage/demo/src/main/java/de/grobox/storagebackuptester/scanner/MediaScanner.kt index dd4d4e0a..25a8f7ba 100644 --- a/storage/demo/src/main/java/de/grobox/storagebackuptester/scanner/MediaScanner.kt +++ b/storage/demo/src/main/java/de/grobox/storagebackuptester/scanner/MediaScanner.kt @@ -13,7 +13,6 @@ import org.calyxos.backup.storage.api.BackupFile import org.calyxos.backup.storage.scanner.MediaScanner import java.text.SimpleDateFormat import java.util.Date -import kotlin.time.ExperimentalTime import kotlin.time.TimedValue import kotlin.time.measureTimedValue @@ -27,7 +26,6 @@ data class ScanResult( } } -@OptIn(ExperimentalTime::class) fun scanUri(context: Context, mediaScanner: MediaScanner, uri: Uri): String { val sb = StringBuilder() val timedResult = measureTimedValue { @@ -57,7 +55,6 @@ fun dump(context: Context, mediaFiles: List, sb: StringBuilder? = nu return ScanResult(itemsFound, totalSize) } -@OptIn(ExperimentalTime::class) fun appendStats( context: Context, sb: StringBuilder, diff --git a/storage/demo/src/main/java/de/grobox/storagebackuptester/settings/SettingsFragment.kt b/storage/demo/src/main/java/de/grobox/storagebackuptester/settings/SettingsFragment.kt index 940a8331..ad68b18a 100644 --- a/storage/demo/src/main/java/de/grobox/storagebackuptester/settings/SettingsFragment.kt +++ b/storage/demo/src/main/java/de/grobox/storagebackuptester/settings/SettingsFragment.kt @@ -17,7 +17,6 @@ import android.view.View import android.view.ViewGroup import android.widget.Toast import android.widget.Toast.LENGTH_SHORT -import androidx.appcompat.app.AlertDialog import androidx.fragment.app.activityViewModels import com.google.android.material.dialog.MaterialAlertDialogBuilder import de.grobox.storagebackuptester.MainViewModel diff --git a/storage/demo/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/storage/demo/src/main/res/mipmap-anydpi-v26/ic_launcher.xml index a62b276d..66002d19 100644 --- a/storage/demo/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/storage/demo/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -6,4 +6,5 @@ + diff --git a/storage/demo/src/main/res/values-night/themes.xml b/storage/demo/src/main/res/values-night/themes.xml index fc987bfd..cf583c51 100644 --- a/storage/demo/src/main/res/values-night/themes.xml +++ b/storage/demo/src/main/res/values-night/themes.xml @@ -14,7 +14,7 @@ @color/teal_200 @color/black - ?attr/colorPrimaryVariant + ?attr/colorPrimaryVariant @color/matrix diff --git a/storage/demo/src/main/res/values/colors.xml b/storage/demo/src/main/res/values/colors.xml index 891610df..f6d4334b 100644 --- a/storage/demo/src/main/res/values/colors.xml +++ b/storage/demo/src/main/res/values/colors.xml @@ -4,8 +4,6 @@ SPDX-License-Identifier: Apache-2.0 --> - #FFBB86FC - #FF6200EE #FF3700B3 #FF03DAC5 #FF018786 diff --git a/storage/lib/src/main/java/org/calyxos/backup/storage/TimeUtils.kt b/storage/lib/src/main/java/org/calyxos/backup/storage/TimeUtils.kt index ef88077d..c598df92 100644 --- a/storage/lib/src/main/java/org/calyxos/backup/storage/TimeUtils.kt +++ b/storage/lib/src/main/java/org/calyxos/backup/storage/TimeUtils.kt @@ -11,7 +11,6 @@ import kotlin.contracts.InvocationKind import kotlin.contracts.contract import kotlin.time.Duration import kotlin.time.DurationUnit -import kotlin.time.ExperimentalTime import kotlin.time.toDuration /** @@ -20,7 +19,7 @@ import kotlin.time.toDuration * So when building with AOSP 11, things will blow up. */ -@OptIn(ExperimentalContracts::class, ExperimentalTime::class) +@OptIn(ExperimentalContracts::class) internal inline fun measure(block: () -> Unit): Duration { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) @@ -30,7 +29,7 @@ internal inline fun measure(block: () -> Unit): Duration { return (System.currentTimeMillis() - start).toDuration(DurationUnit.MILLISECONDS) } -@OptIn(ExperimentalContracts::class, ExperimentalTime::class) +@OptIn(ExperimentalContracts::class) internal inline fun measure(text: String, block: () -> T): T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE)