Properly schedule/cancel backup workers when backup destination changes
When the user changes to USB storage, we need to cancel current schedulings, because the storage is not always available (maybe can use a trigger URI?). And if moving to a non-USB storage, we need to schedule backups again. Unfortunately, there are two places in the code where we handle storage location changes. Ideally, those get unified at some point.
This commit is contained in:
parent
e615402458
commit
0c1898c198
4 changed files with 57 additions and 13 deletions
|
@ -23,7 +23,6 @@ import com.stevesoltys.seedvault.R
|
|||
import com.stevesoltys.seedvault.permitDiskReads
|
||||
import com.stevesoltys.seedvault.restore.RestoreActivity
|
||||
import com.stevesoltys.seedvault.ui.toRelativeTime
|
||||
import com.stevesoltys.seedvault.worker.AppBackupWorker
|
||||
import org.koin.android.ext.android.inject
|
||||
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
|
||||
|
||||
|
@ -128,7 +127,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
|||
val disable = !(newValue as Boolean)
|
||||
// TODO this should really get moved out off the UI layer
|
||||
if (disable) {
|
||||
viewModel.cancelBackupWorkers()
|
||||
viewModel.cancelFilesBackup()
|
||||
return@OnPreferenceChangeListener true
|
||||
}
|
||||
onEnablingStorageBackup()
|
||||
|
@ -215,10 +214,10 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
|||
return try {
|
||||
backupManager.isBackupEnabled = enabled
|
||||
if (enabled) {
|
||||
AppBackupWorker.schedule(requireContext())
|
||||
viewModel.scheduleAppBackup()
|
||||
viewModel.enableCallLogBackup()
|
||||
} else {
|
||||
AppBackupWorker.unschedule(requireContext())
|
||||
viewModel.cancelAppBackup()
|
||||
}
|
||||
backup.isChecked = enabled
|
||||
true
|
||||
|
@ -280,7 +279,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
|||
}
|
||||
|
||||
Long.MAX_VALUE -> {
|
||||
val text = if (backupManager.isBackupEnabled) {
|
||||
val text = if (backupManager.isBackupEnabled && storage?.isUsb != true) {
|
||||
getString(R.string.notification_title)
|
||||
} else {
|
||||
getString(R.string.settings_backup_last_backup_never)
|
||||
|
@ -315,7 +314,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
|||
LENGTH_LONG
|
||||
).show()
|
||||
}
|
||||
viewModel.scheduleBackupWorkers()
|
||||
viewModel.scheduleFilesBackup()
|
||||
backupStorage.isChecked = true
|
||||
dialog.dismiss()
|
||||
}
|
||||
|
|
|
@ -129,11 +129,13 @@ internal class SettingsViewModel(
|
|||
Log.i(TAG, "onStorageLocationChanged")
|
||||
if (storage.isUsb) {
|
||||
// disable storage backup if new storage is on USB
|
||||
cancelBackupWorkers()
|
||||
cancelAppBackup()
|
||||
cancelFilesBackup()
|
||||
} else {
|
||||
// enable it, just in case the previous storage was on USB,
|
||||
// also to update the network requirement of the new storage
|
||||
scheduleBackupWorkers()
|
||||
scheduleAppBackup()
|
||||
scheduleFilesBackup()
|
||||
}
|
||||
onStoragePropertiesChanged()
|
||||
}
|
||||
|
@ -245,11 +247,15 @@ internal class SettingsViewModel(
|
|||
return keyManager.hasMainKey()
|
||||
}
|
||||
|
||||
fun scheduleBackupWorkers() {
|
||||
fun scheduleAppBackup() {
|
||||
val storage = settingsManager.getStorage() ?: error("no storage available")
|
||||
if (!storage.isUsb) {
|
||||
if (backupManager.isBackupEnabled) AppBackupWorker.schedule(app)
|
||||
if (settingsManager.isStorageBackupEnabled()) BackupJobService.scheduleJob(
|
||||
if (!storage.isUsb && backupManager.isBackupEnabled) AppBackupWorker.schedule(app)
|
||||
}
|
||||
|
||||
fun scheduleFilesBackup() {
|
||||
val storage = settingsManager.getStorage() ?: error("no storage available")
|
||||
if (!storage.isUsb && settingsManager.isStorageBackupEnabled()) {
|
||||
BackupJobService.scheduleJob(
|
||||
context = app,
|
||||
jobServiceClass = StorageBackupJobService::class.java,
|
||||
periodMillis = HOURS.toMillis(24),
|
||||
|
@ -261,8 +267,11 @@ internal class SettingsViewModel(
|
|||
}
|
||||
}
|
||||
|
||||
fun cancelBackupWorkers() {
|
||||
fun cancelAppBackup() {
|
||||
AppBackupWorker.unschedule(app)
|
||||
}
|
||||
|
||||
fun cancelFilesBackup() {
|
||||
BackupJobService.cancelJob(app)
|
||||
}
|
||||
|
||||
|
|
|
@ -102,6 +102,7 @@ internal class RecoveryCodeViewModel(
|
|||
*/
|
||||
fun reinitializeBackupLocation() {
|
||||
Log.d(TAG, "Re-initializing backup location...")
|
||||
// TODO this code is almost identical to BackupStorageViewModel#onLocationSet(), unify?
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
// remove old storage snapshots and clear cache
|
||||
storageBackup.deleteAllSnapshots()
|
||||
|
|
|
@ -4,6 +4,7 @@ import android.app.Application
|
|||
import android.app.backup.BackupProgress
|
||||
import android.app.backup.IBackupManager
|
||||
import android.app.backup.IBackupObserver
|
||||
import android.app.job.JobInfo
|
||||
import android.net.Uri
|
||||
import android.os.UserHandle
|
||||
import android.util.Log
|
||||
|
@ -11,12 +12,15 @@ import androidx.annotation.WorkerThread
|
|||
import androidx.lifecycle.viewModelScope
|
||||
import com.stevesoltys.seedvault.R
|
||||
import com.stevesoltys.seedvault.settings.SettingsManager
|
||||
import com.stevesoltys.seedvault.storage.StorageBackupJobService
|
||||
import com.stevesoltys.seedvault.transport.TRANSPORT_ID
|
||||
import com.stevesoltys.seedvault.worker.AppBackupWorker
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import org.calyxos.backup.storage.api.StorageBackup
|
||||
import org.calyxos.backup.storage.backup.BackupJobService
|
||||
import java.io.IOException
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
private val TAG = BackupStorageViewModel::class.java.simpleName
|
||||
|
||||
|
@ -31,8 +35,18 @@ internal class BackupStorageViewModel(
|
|||
|
||||
override fun onLocationSet(uri: Uri) {
|
||||
val isUsb = saveStorage(uri)
|
||||
if (isUsb) {
|
||||
// disable storage backup if new storage is on USB
|
||||
cancelBackupWorkers()
|
||||
} else {
|
||||
// enable it, just in case the previous storage was on USB,
|
||||
// also to update the network requirement of the new storage
|
||||
scheduleBackupWorkers()
|
||||
}
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
// remove old storage snapshots and clear cache
|
||||
// TODO is this needed? It also does create all 255 chunk folders which takes time
|
||||
// pass a flag to getCurrentBackupSnapshots() to not create missing folders?
|
||||
storageBackup.deleteAllSnapshots()
|
||||
storageBackup.clearCache()
|
||||
try {
|
||||
|
@ -52,6 +66,27 @@ internal class BackupStorageViewModel(
|
|||
}
|
||||
}
|
||||
|
||||
private fun scheduleBackupWorkers() {
|
||||
val storage = settingsManager.getStorage() ?: error("no storage available")
|
||||
if (!storage.isUsb) {
|
||||
if (backupManager.isBackupEnabled) AppBackupWorker.schedule(app)
|
||||
if (settingsManager.isStorageBackupEnabled()) BackupJobService.scheduleJob(
|
||||
context = app,
|
||||
jobServiceClass = StorageBackupJobService::class.java,
|
||||
periodMillis = TimeUnit.HOURS.toMillis(24),
|
||||
networkType = if (storage.requiresNetwork) JobInfo.NETWORK_TYPE_UNMETERED
|
||||
else JobInfo.NETWORK_TYPE_NONE,
|
||||
deviceIdle = false,
|
||||
charging = true
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun cancelBackupWorkers() {
|
||||
AppBackupWorker.unschedule(app)
|
||||
BackupJobService.cancelJob(app)
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
private inner class InitializationObserver(val requestBackup: Boolean) :
|
||||
IBackupObserver.Stub() {
|
||||
|
|
Loading…
Reference in a new issue