diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 6bc9213ab..c3bd194cc 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -156,6 +156,11 @@
+
+
(
- repeatInterval = 24,
- repeatIntervalTimeUnit = TimeUnit.HOURS,
- flexTimeInterval = 2,
- flexTimeIntervalUnit = TimeUnit.HOURS,
- ).setConstraints(backupConstraints)
- .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 1, TimeUnit.HOURS)
- .build()
- val workManager = WorkManager.getInstance(appContext)
- workManager.enqueueUniquePeriodicWork(UNIQUE_WORK_NAME, UPDATE, backupWorkRequest)
- }
-
- fun unschedule(appContext: Context) {
- val workManager = WorkManager.getInstance(appContext)
- workManager.cancelUniqueWork(UNIQUE_WORK_NAME)
- }
- }
-
- override fun doWork(): Result {
- // TODO once we make this the default, we should do storage backup here as well
- // or have two workers and ensure they never run at the same time
- return if (requestBackup(applicationContext)) Result.success()
- else Result.retry()
- }
-}
diff --git a/app/src/main/java/com/stevesoltys/seedvault/UsbIntentReceiver.kt b/app/src/main/java/com/stevesoltys/seedvault/UsbIntentReceiver.kt
index 4800fcefb..ff5208b03 100644
--- a/app/src/main/java/com/stevesoltys/seedvault/UsbIntentReceiver.kt
+++ b/app/src/main/java/com/stevesoltys/seedvault/UsbIntentReceiver.kt
@@ -20,8 +20,8 @@ import com.stevesoltys.seedvault.settings.FlashDrive
import com.stevesoltys.seedvault.settings.SettingsManager
import com.stevesoltys.seedvault.storage.StorageBackupService
import com.stevesoltys.seedvault.storage.StorageBackupService.Companion.EXTRA_START_APP_BACKUP
-import com.stevesoltys.seedvault.transport.requestBackup
import com.stevesoltys.seedvault.ui.storage.AUTHORITY_STORAGE
+import com.stevesoltys.seedvault.worker.AppBackupWorker
import org.koin.core.context.GlobalContext.get
import java.util.concurrent.TimeUnit.HOURS
@@ -63,9 +63,7 @@ class UsbIntentReceiver : UsbMonitor() {
i.putExtra(EXTRA_START_APP_BACKUP, true)
startForegroundService(context, i)
} else {
- Thread {
- requestBackup(context)
- }.start()
+ AppBackupWorker.scheduleNow(context)
}
}
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 e03e55e80..6e6b0c5b6 100644
--- a/app/src/main/java/com/stevesoltys/seedvault/restore/RestoreViewModel.kt
+++ b/app/src/main/java/com/stevesoltys/seedvault/restore/RestoreViewModel.kt
@@ -39,7 +39,7 @@ import com.stevesoltys.seedvault.restore.install.isInstalled
import com.stevesoltys.seedvault.settings.SettingsManager
import com.stevesoltys.seedvault.storage.StorageRestoreService
import com.stevesoltys.seedvault.transport.TRANSPORT_ID
-import com.stevesoltys.seedvault.transport.backup.NUM_PACKAGES_PER_TRANSACTION
+import com.stevesoltys.seedvault.worker.NUM_PACKAGES_PER_TRANSACTION
import com.stevesoltys.seedvault.transport.restore.RestoreCoordinator
import com.stevesoltys.seedvault.ui.AppBackupState
import com.stevesoltys.seedvault.ui.AppBackupState.FAILED
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 e220462c3..afb056879 100644
--- a/app/src/main/java/com/stevesoltys/seedvault/settings/SettingsViewModel.kt
+++ b/app/src/main/java/com/stevesoltys/seedvault/settings/SettingsViewModel.kt
@@ -25,7 +25,7 @@ import androidx.lifecycle.Transformations.switchMap
import androidx.lifecycle.liveData
import androidx.lifecycle.viewModelScope
import androidx.recyclerview.widget.DiffUtil.calculateDiff
-import com.stevesoltys.seedvault.BackupWorker
+import androidx.work.ExistingPeriodicWorkPolicy
import com.stevesoltys.seedvault.R
import com.stevesoltys.seedvault.crypto.KeyManager
import com.stevesoltys.seedvault.metadata.MetadataManager
@@ -33,9 +33,9 @@ import com.stevesoltys.seedvault.permitDiskReads
import com.stevesoltys.seedvault.storage.StorageBackupJobService
import com.stevesoltys.seedvault.storage.StorageBackupService
import com.stevesoltys.seedvault.storage.StorageBackupService.Companion.EXTRA_START_APP_BACKUP
-import com.stevesoltys.seedvault.transport.requestBackup
import com.stevesoltys.seedvault.ui.RequireProvisioningViewModel
import com.stevesoltys.seedvault.ui.notification.BackupNotificationManager
+import com.stevesoltys.seedvault.worker.AppBackupWorker
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@@ -174,7 +174,7 @@ internal class SettingsViewModel(
i.putExtra(EXTRA_START_APP_BACKUP, true)
startForegroundService(app, i)
} else {
- requestBackup(app)
+ AppBackupWorker.scheduleNow(app)
}
}
}
@@ -266,9 +266,9 @@ internal class SettingsViewModel(
fun onD2dChanged(enabled: Boolean) {
backupManager.setFrameworkSchedulingEnabledForUser(UserHandle.myUserId(), !enabled)
if (enabled) {
- BackupWorker.schedule(app)
+ AppBackupWorker.schedule(app)
} else {
- BackupWorker.unschedule(app)
+ AppBackupWorker.unschedule(app)
}
}
diff --git a/app/src/main/java/com/stevesoltys/seedvault/storage/Services.kt b/app/src/main/java/com/stevesoltys/seedvault/storage/Services.kt
index 1c54beb27..e42da2d3f 100644
--- a/app/src/main/java/com/stevesoltys/seedvault/storage/Services.kt
+++ b/app/src/main/java/com/stevesoltys/seedvault/storage/Services.kt
@@ -1,7 +1,7 @@
package com.stevesoltys.seedvault.storage
import android.content.Intent
-import com.stevesoltys.seedvault.transport.requestBackup
+import com.stevesoltys.seedvault.worker.AppBackupWorker
import org.calyxos.backup.storage.api.BackupObserver
import org.calyxos.backup.storage.api.RestoreObserver
import org.calyxos.backup.storage.api.StorageBackup
@@ -40,7 +40,7 @@ internal class StorageBackupService : BackupService() {
override fun onBackupFinished(intent: Intent, success: Boolean) {
if (intent.getBooleanExtra(EXTRA_START_APP_BACKUP, false)) {
- requestBackup(applicationContext)
+ AppBackupWorker.scheduleNow(applicationContext)
}
}
}
diff --git a/app/src/main/java/com/stevesoltys/seedvault/transport/ConfigurableBackupTransportService.kt b/app/src/main/java/com/stevesoltys/seedvault/transport/ConfigurableBackupTransportService.kt
index 1b9fe3b6c..9d81d3e5e 100644
--- a/app/src/main/java/com/stevesoltys/seedvault/transport/ConfigurableBackupTransportService.kt
+++ b/app/src/main/java/com/stevesoltys/seedvault/transport/ConfigurableBackupTransportService.kt
@@ -2,18 +2,13 @@ package com.stevesoltys.seedvault.transport
import android.app.Service
import android.app.backup.IBackupManager
-import android.content.Context
import android.content.Intent
import android.os.IBinder
import android.util.Log
-import androidx.annotation.WorkerThread
import com.stevesoltys.seedvault.crypto.KeyManager
-import com.stevesoltys.seedvault.transport.backup.BackupRequester
-import com.stevesoltys.seedvault.transport.backup.PackageService
import com.stevesoltys.seedvault.ui.notification.BackupNotificationManager
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
-import org.koin.core.context.GlobalContext.get
private val TAG = ConfigurableBackupTransportService::class.java.simpleName
@@ -56,23 +51,3 @@ class ConfigurableBackupTransportService : Service(), KoinComponent {
}
}
-
-/**
- * Requests the system to initiate a backup.
- *
- * @return true iff backups was requested successfully (backup itself can still fail).
- */
-@WorkerThread
-fun requestBackup(context: Context): Boolean {
- val backupManager: IBackupManager = get().get()
- return if (backupManager.isBackupEnabled) {
- val packageService: PackageService = get().get()
-
- Log.d(TAG, "Backup is enabled, request backup...")
- val backupRequester = BackupRequester(context, backupManager, packageService)
- return backupRequester.requestBackup()
- } else {
- Log.i(TAG, "Backup is not enabled")
- true // this counts as success
- }
-}
diff --git a/app/src/main/java/com/stevesoltys/seedvault/ui/notification/BackupNotificationManager.kt b/app/src/main/java/com/stevesoltys/seedvault/ui/notification/BackupNotificationManager.kt
index 0a8bc09da..ec450d780 100644
--- a/app/src/main/java/com/stevesoltys/seedvault/ui/notification/BackupNotificationManager.kt
+++ b/app/src/main/java/com/stevesoltys/seedvault/ui/notification/BackupNotificationManager.kt
@@ -30,17 +30,15 @@ import com.stevesoltys.seedvault.settings.SettingsActivity
import kotlin.math.min
private const val CHANNEL_ID_OBSERVER = "NotificationBackupObserver"
-private const val CHANNEL_ID_APK = "NotificationApkBackup"
private const val CHANNEL_ID_SUCCESS = "NotificationBackupSuccess"
private const val CHANNEL_ID_ERROR = "NotificationError"
private const val CHANNEL_ID_RESTORE_ERROR = "NotificationRestoreError"
-private const val NOTIFICATION_ID_OBSERVER = 1
-internal const val NOTIFICATION_ID_APK = 2
-private const val NOTIFICATION_ID_SUCCESS = 3
-private const val NOTIFICATION_ID_ERROR = 4
-private const val NOTIFICATION_ID_RESTORE_ERROR = 5
-private const val NOTIFICATION_ID_BACKGROUND = 6
-private const val NOTIFICATION_ID_NO_MAIN_KEY_ERROR = 7
+internal const val NOTIFICATION_ID_OBSERVER = 1
+private const val NOTIFICATION_ID_SUCCESS = 2
+private const val NOTIFICATION_ID_ERROR = 3
+private const val NOTIFICATION_ID_RESTORE_ERROR = 4
+private const val NOTIFICATION_ID_BACKGROUND = 5
+private const val NOTIFICATION_ID_NO_MAIN_KEY_ERROR = 6
private val TAG = BackupNotificationManager::class.java.simpleName
@@ -48,7 +46,6 @@ internal class BackupNotificationManager(private val context: Context) {
private val nm = context.getSystemService(NotificationManager::class.java)!!.apply {
createNotificationChannel(getObserverChannel())
- createNotificationChannel(getApkChannel())
createNotificationChannel(getSuccessChannel())
createNotificationChannel(getErrorChannel())
createNotificationChannel(getRestoreErrorChannel())
@@ -61,13 +58,6 @@ internal class BackupNotificationManager(private val context: Context) {
}
}
- private fun getApkChannel(): NotificationChannel {
- val title = context.getString(R.string.notification_apk_channel_title)
- return NotificationChannel(CHANNEL_ID_APK, title, IMPORTANCE_LOW).apply {
- enableVibration(false)
- }
- }
-
private fun getSuccessChannel(): NotificationChannel {
val title = context.getString(R.string.notification_success_channel_title)
return NotificationChannel(CHANNEL_ID_SUCCESS, title, IMPORTANCE_LOW).apply {
@@ -91,8 +81,7 @@ internal class BackupNotificationManager(private val context: Context) {
fun onApkBackup(packageName: String, name: CharSequence, transferred: Int, expected: Int) {
Log.i(TAG, "$transferred/$expected - $name ($packageName)")
val text = context.getString(R.string.notification_apk_text, name)
- val notification = getApkBackupNotification(text, transferred, expected)
- nm.notify(NOTIFICATION_ID_APK, notification)
+ updateBackupNotification(text, transferred, expected)
}
/**
@@ -100,32 +89,15 @@ internal class BackupNotificationManager(private val context: Context) {
*/
fun onAppsNotBackedUp() {
Log.i(TAG, "onAppsNotBackedUp")
- val notification =
- getApkBackupNotification(context.getString(R.string.notification_apk_not_backed_up))
- nm.notify(NOTIFICATION_ID_APK, notification)
+ val text = context.getString(R.string.notification_apk_not_backed_up)
+ updateBackupNotification(text)
}
- fun getApkBackupNotification(
- text: String?,
- expected: Int = 0,
- transferred: Int = 0,
- ): Notification = Builder(context, CHANNEL_ID_APK).apply {
- setSmallIcon(R.drawable.ic_cloud_upload)
- setContentTitle(context.getString(R.string.notification_title))
- setContentText(text)
- setOngoing(true)
- setShowWhen(false)
- setWhen(System.currentTimeMillis())
- setProgress(expected, transferred, false)
- priority = PRIORITY_DEFAULT
- foregroundServiceBehavior = FOREGROUND_SERVICE_IMMEDIATE
- }.build()
-
/**
* Call after [onApkBackup] or [onAppsNotBackedUp] were called.
*/
fun onApkBackupDone() {
- nm.cancel(NOTIFICATION_ID_APK)
+ nm.cancel(NOTIFICATION_ID_OBSERVER)
}
/**
@@ -133,7 +105,7 @@ internal class BackupNotificationManager(private val context: Context) {
*/
fun onBackupStarted(expectedPackages: Int) {
updateBackupNotification(
- appName = "", // This passes quickly, no need to show something here
+ text = "", // This passes quickly, no need to show something here
transferred = 0,
expected = expectedPackages
)
@@ -145,32 +117,33 @@ internal class BackupNotificationManager(private val context: Context) {
* this type is is expected to get called after [onApkBackup].
*/
fun onBackupUpdate(app: CharSequence, transferred: Int, total: Int) {
- updateBackupNotification(
- appName = app,
- transferred = min(transferred, total),
- expected = total
- )
+ updateBackupNotification(app, min(transferred, total), total)
}
private fun updateBackupNotification(
- appName: CharSequence,
- transferred: Int,
- expected: Int,
+ text: CharSequence,
+ transferred: Int = 0,
+ expected: Int = 0,
) {
- val notification = Builder(context, CHANNEL_ID_OBSERVER).apply {
+ val notification = getBackupNotification(text, transferred, expected)
+ nm.notify(NOTIFICATION_ID_OBSERVER, notification)
+ }
+
+ fun getBackupNotification(text: CharSequence, progress: Int = 0, total: Int = 0): Notification {
+ return Builder(context, CHANNEL_ID_OBSERVER).apply {
setSmallIcon(R.drawable.ic_cloud_upload)
setContentTitle(context.getString(R.string.notification_title))
- setContentText(appName)
+ setContentText(text)
setOngoing(true)
setShowWhen(false)
setWhen(System.currentTimeMillis())
- setProgress(expected, transferred, false)
+ setProgress(progress, total, false)
priority = PRIORITY_DEFAULT
foregroundServiceBehavior = FOREGROUND_SERVICE_IMMEDIATE
}.build()
- nm.notify(NOTIFICATION_ID_OBSERVER, notification)
}
+ // TODO where was this used?
private fun updateBackgroundBackupNotification(infoText: CharSequence) {
Log.i(TAG, "$infoText")
val notification = Builder(context, CHANNEL_ID_OBSERVER).apply {
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 ff2982075..5f5eaea4f 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
@@ -10,7 +10,7 @@ import android.util.Log.isLoggable
import com.stevesoltys.seedvault.MAGIC_PACKAGE_MANAGER
import com.stevesoltys.seedvault.R
import com.stevesoltys.seedvault.metadata.MetadataManager
-import com.stevesoltys.seedvault.transport.backup.BackupRequester
+import com.stevesoltys.seedvault.worker.BackupRequester
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
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 4595468b0..33fe51b80 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
@@ -12,8 +12,7 @@ import androidx.lifecycle.viewModelScope
import com.stevesoltys.seedvault.R
import com.stevesoltys.seedvault.settings.SettingsManager
import com.stevesoltys.seedvault.transport.TRANSPORT_ID
-import com.stevesoltys.seedvault.transport.backup.BackupCoordinator
-import com.stevesoltys.seedvault.transport.requestBackup
+import com.stevesoltys.seedvault.worker.AppBackupWorker
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.calyxos.backup.storage.api.StorageBackup
@@ -24,7 +23,6 @@ private val TAG = BackupStorageViewModel::class.java.simpleName
internal class BackupStorageViewModel(
private val app: Application,
private val backupManager: IBackupManager,
- private val backupCoordinator: BackupCoordinator,
private val storageBackup: StorageBackup,
settingsManager: SettingsManager,
) : StorageViewModel(app, settingsManager) {
@@ -73,7 +71,7 @@ internal class BackupStorageViewModel(
// notify the UI that the location has been set
mLocationChecked.postEvent(LocationResult())
if (requestBackup) {
- requestBackup(app)
+ AppBackupWorker.scheduleNow(app)
}
} else {
// notify the UI that the location was invalid
diff --git a/app/src/main/java/com/stevesoltys/seedvault/worker/AppBackupWorker.kt b/app/src/main/java/com/stevesoltys/seedvault/worker/AppBackupWorker.kt
new file mode 100644
index 000000000..f6cc1b459
--- /dev/null
+++ b/app/src/main/java/com/stevesoltys/seedvault/worker/AppBackupWorker.kt
@@ -0,0 +1,118 @@
+/*
+ * SPDX-FileCopyrightText: 2024 The Calyx Institute
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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.Constraints
+import androidx.work.CoroutineWorker
+import androidx.work.ExistingPeriodicWorkPolicy
+import androidx.work.ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE
+import androidx.work.ExistingPeriodicWorkPolicy.UPDATE
+import androidx.work.ExistingWorkPolicy.REPLACE
+import androidx.work.ForegroundInfo
+import androidx.work.NetworkType
+import androidx.work.OneTimeWorkRequestBuilder
+import androidx.work.OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST
+import androidx.work.PeriodicWorkRequestBuilder
+import androidx.work.WorkManager
+import androidx.work.WorkerParameters
+import com.stevesoltys.seedvault.ui.notification.BackupNotificationManager
+import com.stevesoltys.seedvault.ui.notification.NOTIFICATION_ID_OBSERVER
+import org.koin.core.component.KoinComponent
+import org.koin.core.component.inject
+import java.util.concurrent.TimeUnit
+
+class AppBackupWorker(
+ appContext: Context,
+ workerParams: WorkerParameters,
+) : CoroutineWorker(appContext, workerParams), KoinComponent {
+
+ companion object {
+ private val TAG = AppBackupWorker::class.simpleName
+ private const val UNIQUE_WORK_NAME = "com.stevesoltys.seedvault.APP_BACKUP"
+ private const val TAG_NOW = "com.stevesoltys.seedvault.TAG_NOW"
+
+ fun schedule(context: Context, existingWorkPolicy: ExistingPeriodicWorkPolicy = UPDATE) {
+ val constraints = Constraints.Builder()
+ .setRequiredNetworkType(NetworkType.UNMETERED)
+ .setRequiresCharging(true)
+ .build()
+ val workRequest = PeriodicWorkRequestBuilder(
+ repeatInterval = 24,
+ repeatIntervalTimeUnit = TimeUnit.HOURS,
+ flexTimeInterval = 2,
+ flexTimeIntervalUnit = TimeUnit.HOURS,
+ ).setConstraints(constraints)
+ .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 5, TimeUnit.MINUTES)
+ .build()
+ val workManager = WorkManager.getInstance(context)
+ Log.i(TAG, "Scheduling app backup: $workRequest")
+ workManager.enqueueUniquePeriodicWork(UNIQUE_WORK_NAME, existingWorkPolicy, workRequest)
+ }
+
+ fun scheduleNow(context: Context) {
+ val workRequest = OneTimeWorkRequestBuilder()
+ .setExpedited(RUN_AS_NON_EXPEDITED_WORK_REQUEST)
+ .addTag(TAG_NOW)
+ .build()
+ val workManager = WorkManager.getInstance(context)
+ Log.i(TAG, "Asking to do app backup now...")
+ workManager.enqueueUniqueWork(UNIQUE_WORK_NAME, REPLACE, workRequest)
+ }
+
+ fun unschedule(context: Context) {
+ Log.i(TAG, "Unscheduling app backup...")
+ val workManager = WorkManager.getInstance(context)
+ workManager.cancelUniqueWork(UNIQUE_WORK_NAME)
+ }
+ }
+
+ private val backupRequester: BackupRequester by inject()
+ private val apkBackupManager: ApkBackupManager by inject()
+ private val nm: BackupNotificationManager by inject()
+
+ override suspend fun doWork(): Result {
+ try {
+ setForeground(createForegroundInfo())
+ } catch (e: Exception) {
+ Log.e(TAG, "Error while running setForeground: ", e)
+ }
+ var result: Result = Result.success()
+ try {
+ Log.i(TAG, "Starting APK backup...")
+ apkBackupManager.backup()
+ } catch (e: Exception) {
+ Log.e(TAG, "Error backing up APKs: ", e)
+ result = Result.retry()
+ } finally {
+ Log.i(TAG, "Requesting app data backup...")
+ val requestSuccess = try {
+ if (backupRequester.isBackupEnabled) {
+ Log.d(TAG, "Backup is enabled, request backup...")
+ backupRequester.requestBackup()
+ } else true
+ } finally {
+ // schedule next backup, because the old one gets lost
+ // when scheduling a OneTimeWorkRequest with the same unique name via scheduleNow()
+ if (tags.contains(TAG_NOW)) {
+ // needs to use CANCEL_AND_REENQUEUE otherwise it doesn't get scheduled
+ schedule(applicationContext, CANCEL_AND_REENQUEUE)
+ }
+ }
+ if (!requestSuccess) result = Result.retry()
+ }
+ return result
+ }
+
+ private fun createForegroundInfo() = ForegroundInfo(
+ NOTIFICATION_ID_OBSERVER,
+ nm.getBackupNotification(""),
+ FOREGROUND_SERVICE_TYPE_DATA_SYNC,
+ )
+}
diff --git a/app/src/main/java/com/stevesoltys/seedvault/transport/backup/BackupRequester.kt b/app/src/main/java/com/stevesoltys/seedvault/worker/BackupRequester.kt
similarity index 95%
rename from app/src/main/java/com/stevesoltys/seedvault/transport/backup/BackupRequester.kt
rename to app/src/main/java/com/stevesoltys/seedvault/worker/BackupRequester.kt
index 209db7622..9eac74069 100644
--- a/app/src/main/java/com/stevesoltys/seedvault/transport/backup/BackupRequester.kt
+++ b/app/src/main/java/com/stevesoltys/seedvault/worker/BackupRequester.kt
@@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
-package com.stevesoltys.seedvault.transport.backup
+package com.stevesoltys.seedvault.worker
import android.app.backup.BackupManager
import android.app.backup.IBackupManager
@@ -12,6 +12,7 @@ import android.os.RemoteException
import android.util.Log
import androidx.annotation.WorkerThread
import com.stevesoltys.seedvault.BackupMonitor
+import com.stevesoltys.seedvault.transport.backup.PackageService
import com.stevesoltys.seedvault.ui.notification.BackupNotificationManager
import com.stevesoltys.seedvault.ui.notification.NotificationBackupObserver
import org.koin.core.component.KoinComponent
@@ -34,6 +35,8 @@ internal class BackupRequester(
val packageService: PackageService,
) : KoinComponent {
+ val isBackupEnabled: Boolean get() = backupManager.isBackupEnabled
+
private val packages = packageService.eligiblePackages
private val observer = NotificationBackupObserver(
context = context,
diff --git a/app/src/main/java/com/stevesoltys/seedvault/worker/WorkerModule.kt b/app/src/main/java/com/stevesoltys/seedvault/worker/WorkerModule.kt
index ed18a6352..dce45be2d 100644
--- a/app/src/main/java/com/stevesoltys/seedvault/worker/WorkerModule.kt
+++ b/app/src/main/java/com/stevesoltys/seedvault/worker/WorkerModule.kt
@@ -9,6 +9,13 @@ import org.koin.android.ext.koin.androidContext
import org.koin.dsl.module
val workerModule = module {
+ factory {
+ BackupRequester(
+ context = androidContext(),
+ backupManager = get(),
+ packageService = get(),
+ )
+ }
single {
ApkBackup(
pm = androidContext().packageManager,