Always run storage backups in a foreground service
otherwise we get killed for using too much CPU
This commit is contained in:
parent
056bdc3bf3
commit
d13b9ea3fd
5 changed files with 39 additions and 11 deletions
|
@ -19,6 +19,7 @@ import com.stevesoltys.seedvault.metadata.MetadataManager
|
|||
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 org.koin.core.context.KoinContextHandler.get
|
||||
|
@ -57,14 +58,15 @@ class UsbIntentReceiver : UsbMonitor() {
|
|||
|
||||
override fun onStatusChanged(context: Context, action: String, device: UsbDevice) {
|
||||
if (settingsManager.isStorageBackupEnabled()) {
|
||||
// TODO is it safe to start this at the same time as app backup?
|
||||
val i = Intent(context, StorageBackupService::class.java)
|
||||
// this starts an app backup afterwards
|
||||
i.putExtra(EXTRA_START_APP_BACKUP, true)
|
||||
startForegroundService(context, i)
|
||||
} else {
|
||||
Thread {
|
||||
requestBackup(context)
|
||||
}.start()
|
||||
}
|
||||
|
||||
Thread {
|
||||
requestBackup(context)
|
||||
}.start()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.stevesoltys.seedvault.settings
|
|||
import android.app.Application
|
||||
import android.app.job.JobInfo.NETWORK_TYPE_NONE
|
||||
import android.app.job.JobInfo.NETWORK_TYPE_UNMETERED
|
||||
import android.content.Intent
|
||||
import android.database.ContentObserver
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.Network
|
||||
|
@ -14,6 +15,7 @@ import android.util.Log
|
|||
import android.widget.Toast
|
||||
import android.widget.Toast.LENGTH_LONG
|
||||
import androidx.annotation.UiThread
|
||||
import androidx.core.content.ContextCompat.startForegroundService
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.Transformations.switchMap
|
||||
|
@ -25,6 +27,8 @@ import com.stevesoltys.seedvault.crypto.KeyManager
|
|||
import com.stevesoltys.seedvault.metadata.MetadataManager
|
||||
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
|
||||
|
@ -32,7 +36,6 @@ import kotlinx.coroutines.Dispatchers
|
|||
import kotlinx.coroutines.launch
|
||||
import org.calyxos.backup.storage.api.StorageBackup
|
||||
import org.calyxos.backup.storage.backup.BackupJobService
|
||||
import org.calyxos.backup.storage.backup.NotificationBackupObserver
|
||||
import java.util.concurrent.TimeUnit.HOURS
|
||||
|
||||
private const val TAG = "SettingsViewModel"
|
||||
|
@ -156,10 +159,13 @@ internal class SettingsViewModel(
|
|||
Toast.makeText(app, R.string.notification_backup_already_running, LENGTH_LONG).show()
|
||||
} else viewModelScope.launch(Dispatchers.IO) {
|
||||
if (settingsManager.isStorageBackupEnabled()) {
|
||||
val backupObserver = NotificationBackupObserver(app)
|
||||
storageBackup.runBackup(backupObserver)
|
||||
val i = Intent(app, StorageBackupService::class.java)
|
||||
// this starts an app backup afterwards
|
||||
i.putExtra(EXTRA_START_APP_BACKUP, true)
|
||||
startForegroundService(app, i)
|
||||
} else {
|
||||
requestBackup(app)
|
||||
}
|
||||
requestBackup(app)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.stevesoltys.seedvault.storage
|
||||
|
||||
import android.content.Intent
|
||||
import com.stevesoltys.seedvault.transport.requestBackup
|
||||
import org.calyxos.backup.storage.api.BackupObserver
|
||||
import org.calyxos.backup.storage.api.RestoreObserver
|
||||
import org.calyxos.backup.storage.api.StorageBackup
|
||||
|
@ -24,12 +26,23 @@ force running with:
|
|||
internal class StorageBackupJobService : BackupJobService(StorageBackupService::class.java)
|
||||
|
||||
internal class StorageBackupService : BackupService() {
|
||||
|
||||
companion object {
|
||||
internal const val EXTRA_START_APP_BACKUP = "startAppBackup"
|
||||
}
|
||||
|
||||
override val storageBackup: StorageBackup by inject()
|
||||
|
||||
// use lazy delegate because context isn't available during construction time
|
||||
override val backupObserver: BackupObserver by lazy {
|
||||
NotificationBackupObserver(applicationContext)
|
||||
}
|
||||
|
||||
override fun onBackupFinished(intent: Intent, success: Boolean) {
|
||||
if (intent.getBooleanExtra(EXTRA_START_APP_BACKUP, false)) {
|
||||
requestBackup(applicationContext)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class StorageRestoreService : RestoreService() {
|
||||
|
|
|
@ -68,6 +68,8 @@ class MainViewModel(application: Application) : BackupContentViewModel(applicati
|
|||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val text = storageBackup.getUriSummaryString()
|
||||
_backupLog.postValue(BackupProgress(0, 0, "Scanning: $text\n"))
|
||||
// FIXME: This might get killed if we navigate away from the activity.
|
||||
// A foreground service would avoid that.
|
||||
if (storageBackup.runBackup(backupObserver)) {
|
||||
// only prune old backups when backup run was successful
|
||||
storageBackup.pruneOldBackups(backupObserver)
|
||||
|
|
|
@ -21,14 +21,15 @@ public abstract class BackupService : Service() {
|
|||
protected abstract val storageBackup: StorageBackup
|
||||
protected abstract val backupObserver: BackupObserver?
|
||||
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
|
||||
Log.d(TAG, "onStartCommand $intent $flags $startId")
|
||||
startForeground(
|
||||
NOTIFICATION_ID_BACKUP,
|
||||
n.getBackupNotification(R.string.notification_backup_scanning)
|
||||
)
|
||||
GlobalScope.launch {
|
||||
if (storageBackup.runBackup(backupObserver)) {
|
||||
val success = storageBackup.runBackup(backupObserver)
|
||||
if (success) {
|
||||
// only prune old backups when backup run was successful
|
||||
startForeground(
|
||||
NOTIFICATION_ID_PRUNE,
|
||||
|
@ -36,11 +37,15 @@ public abstract class BackupService : Service() {
|
|||
)
|
||||
storageBackup.pruneOldBackups(backupObserver)
|
||||
}
|
||||
onBackupFinished(intent, success)
|
||||
stopSelf(startId)
|
||||
}
|
||||
return super.onStartCommand(intent, flags, startId)
|
||||
}
|
||||
|
||||
protected open fun onBackupFinished(intent: Intent, success: Boolean) {
|
||||
}
|
||||
|
||||
override fun onBind(intent: Intent?): IBinder? {
|
||||
return null
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue