diff --git a/app/src/androidTest/java/com/stevesoltys/seedvault/KoinInstrumentationTestApp.kt b/app/src/androidTest/java/com/stevesoltys/seedvault/KoinInstrumentationTestApp.kt index ce730a04..d5f98989 100644 --- a/app/src/androidTest/java/com/stevesoltys/seedvault/KoinInstrumentationTestApp.kt +++ b/app/src/androidTest/java/com/stevesoltys/seedvault/KoinInstrumentationTestApp.kt @@ -31,7 +31,7 @@ class KoinInstrumentationTestApp : App() { single { spyk(SettingsManager(context)) } single { spyk(BackupNotificationManager(context)) } - single { spyk(FullBackup(get(), get(), get(), get())) } + single { spyk(FullBackup(get(), get(), get(), get(), get())) } single { spyk(KVBackup(get(), get(), get(), get(), get())) } single { spyk(InputFactory()) } diff --git a/app/src/main/java/com/stevesoltys/seedvault/plugins/StorageProperties.kt b/app/src/main/java/com/stevesoltys/seedvault/plugins/StorageProperties.kt index eca9fb7f..8187d312 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/plugins/StorageProperties.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/plugins/StorageProperties.kt @@ -9,6 +9,7 @@ import android.content.Context import android.net.ConnectivityManager import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET import androidx.annotation.WorkerThread +import java.io.IOException abstract class StorageProperties { abstract val config: T @@ -34,3 +35,7 @@ abstract class StorageProperties { return capabilities.hasCapability(NET_CAPABILITY_INTERNET) && (allowMetered || !isMetered) } } + +fun Exception.isOutOfSpace(): Boolean { + return this is IOException && message?.contains("No space left on device") == true +} 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 59213eb4..bacd39a6 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 @@ -26,6 +26,7 @@ import com.stevesoltys.seedvault.metadata.PackageState.QUOTA_EXCEEDED import com.stevesoltys.seedvault.metadata.PackageState.UNKNOWN_ERROR import com.stevesoltys.seedvault.plugins.StoragePlugin import com.stevesoltys.seedvault.plugins.StoragePluginManager +import com.stevesoltys.seedvault.plugins.isOutOfSpace import com.stevesoltys.seedvault.plugins.saf.FILE_BACKUP_METADATA import com.stevesoltys.seedvault.settings.SettingsManager import com.stevesoltys.seedvault.ui.notification.BackupNotificationManager @@ -360,9 +361,7 @@ internal class BackupCoordinator( onPackageBackedUp(packageInfo, BackupType.KV, size) } catch (e: Exception) { Log.e(TAG, "Error calling onPackageBackedUp for $packageName", e) - if (e is IOException && - e.message?.contains("No space left on device") == true - ) nm.onInsufficientSpaceError() + if (e.isOutOfSpace()) nm.onInsufficientSpaceError() result = TRANSPORT_PACKAGE_REJECTED } } 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 6128c1e7..f600c8b0 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 @@ -28,6 +28,7 @@ val backupModule = module { FullBackup( pluginManager = get(), settingsManager = get(), + nm = get(), inputFactory = get(), crypto = 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 5b76abb5..8fdc6591 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 @@ -12,7 +12,9 @@ import com.stevesoltys.seedvault.crypto.Crypto import com.stevesoltys.seedvault.header.VERSION import com.stevesoltys.seedvault.header.getADForFull import com.stevesoltys.seedvault.plugins.StoragePluginManager +import com.stevesoltys.seedvault.plugins.isOutOfSpace import com.stevesoltys.seedvault.settings.SettingsManager +import com.stevesoltys.seedvault.ui.notification.BackupNotificationManager import libcore.io.IoUtils.closeQuietly import java.io.EOFException import java.io.IOException @@ -41,6 +43,7 @@ private val TAG = FullBackup::class.java.simpleName internal class FullBackup( private val pluginManager: StoragePluginManager, private val settingsManager: SettingsManager, + private val nm: BackupNotificationManager, private val inputFactory: InputFactory, private val crypto: Crypto, ) { @@ -170,6 +173,7 @@ internal class FullBackup( TRANSPORT_OK } catch (e: IOException) { Log.e(TAG, "Error handling backup data for ${state.packageName}: ", e) + if (e.isOutOfSpace()) nm.onInsufficientSpaceError() TRANSPORT_ERROR } } diff --git a/app/src/main/java/com/stevesoltys/seedvault/worker/ApkBackupManager.kt b/app/src/main/java/com/stevesoltys/seedvault/worker/ApkBackupManager.kt index 1471d16f..3dd6f10d 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/worker/ApkBackupManager.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/worker/ApkBackupManager.kt @@ -13,6 +13,7 @@ import com.stevesoltys.seedvault.metadata.PackageState.NOT_ALLOWED import com.stevesoltys.seedvault.metadata.PackageState.WAS_STOPPED import com.stevesoltys.seedvault.plugins.StoragePlugin import com.stevesoltys.seedvault.plugins.StoragePluginManager +import com.stevesoltys.seedvault.plugins.isOutOfSpace import com.stevesoltys.seedvault.plugins.saf.FILE_BACKUP_METADATA import com.stevesoltys.seedvault.settings.SettingsManager import com.stevesoltys.seedvault.transport.backup.PackageService @@ -110,9 +111,7 @@ internal class ApkBackupManager( } ?: false } catch (e: IOException) { Log.e(TAG, "Error while writing APK for $packageName", e) - if (e.message?.contains("No space left on device") == true) { - nm.onInsufficientSpaceError() - } + if (e.isOutOfSpace()) nm.onInsufficientSpaceError() false } } 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 70b8b35d..347641f1 100644 --- a/app/src/test/java/com/stevesoltys/seedvault/transport/CoordinatorIntegrationTest.kt +++ b/app/src/test/java/com/stevesoltys/seedvault/transport/CoordinatorIntegrationTest.kt @@ -65,8 +65,13 @@ internal class CoordinatorIntegrationTest : TransportTest() { private val backupPlugin = mockk>() private val kvBackup = KVBackup(storagePluginManager, settingsManager, inputFactory, cryptoImpl, dbManager) - private val fullBackup = - FullBackup(storagePluginManager, settingsManager, inputFactory, cryptoImpl) + private val fullBackup = FullBackup( + pluginManager = storagePluginManager, + settingsManager = settingsManager, + nm = notificationManager, + inputFactory = inputFactory, + crypto = cryptoImpl, + ) private val apkBackup = mockk() private val packageService: PackageService = mockk() private val backup = BackupCoordinator( diff --git a/app/src/test/java/com/stevesoltys/seedvault/transport/backup/FullBackupTest.kt b/app/src/test/java/com/stevesoltys/seedvault/transport/backup/FullBackupTest.kt index 1681b6f5..b1a738d2 100644 --- a/app/src/test/java/com/stevesoltys/seedvault/transport/backup/FullBackupTest.kt +++ b/app/src/test/java/com/stevesoltys/seedvault/transport/backup/FullBackupTest.kt @@ -8,6 +8,7 @@ import com.stevesoltys.seedvault.header.VERSION import com.stevesoltys.seedvault.header.getADForFull import com.stevesoltys.seedvault.plugins.StoragePlugin import com.stevesoltys.seedvault.plugins.StoragePluginManager +import com.stevesoltys.seedvault.ui.notification.BackupNotificationManager import io.mockk.Runs import io.mockk.coEvery import io.mockk.every @@ -26,7 +27,14 @@ internal class FullBackupTest : BackupTest() { private val storagePluginManager: StoragePluginManager = mockk() private val plugin = mockk>() - private val backup = FullBackup(storagePluginManager, settingsManager, inputFactory, crypto) + private val notificationManager = mockk() + private val backup = FullBackup( + pluginManager = storagePluginManager, + settingsManager = settingsManager, + nm = notificationManager, + inputFactory = inputFactory, + crypto = crypto, + ) private val bytes = ByteArray(23).apply { Random.nextBytes(this) } private val inputStream = mockk()