Skip to content

Commit

Permalink
Use WorkInfo for determining if a backup is already running
Browse files Browse the repository at this point in the history
Backup and restore is not possible when a backup is running. We used to check notifications for this, but now can use WorkManager's WorkInfo which should be more reliable.

Also, we used to prevent the "Backup now" action when app backup was disabled. But the user may want to do a storage backup. This is now possible.
  • Loading branch information
grote committed Feb 22, 2024
1 parent d797f8d commit 17b8b25
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,17 @@ class SettingsFragment : PreferenceFragmentCompat() {
super.onViewCreated(view, savedInstanceState)

viewModel.lastBackupTime.observe(viewLifecycleOwner) { time ->
setAppBackupStatusSummary(time, viewModel.nextScheduleTimeMillis.value)
setAppBackupStatusSummary(
lastBackupInMillis = time,
nextScheduleTimeMillis = viewModel.appBackupWorkInfo.value?.nextScheduleTimeMillis,
)
}
viewModel.nextScheduleTimeMillis.observe(viewLifecycleOwner) { time ->
setAppBackupStatusSummary(viewModel.lastBackupTime.value, time)
viewModel.appBackupWorkInfo.observe(viewLifecycleOwner) { workInfo ->
viewModel.onWorkerStateChanged()
setAppBackupStatusSummary(
lastBackupInMillis = viewModel.lastBackupTime.value,
nextScheduleTimeMillis = workInfo?.nextScheduleTimeMillis,
)
}

val backupFiles: Preference = findPreference("backup_files")!!
Expand All @@ -165,7 +172,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
setAutoRestoreState()
setAppBackupStatusSummary(
lastBackupInMillis = viewModel.lastBackupTime.value,
nextScheduleTimeMillis = viewModel.nextScheduleTimeMillis.value,
nextScheduleTimeMillis = viewModel.appBackupWorkInfo.value?.nextScheduleTimeMillis,
)
}

Expand Down Expand Up @@ -273,11 +280,6 @@ class SettingsFragment : PreferenceFragmentCompat() {
if (sb.isNotEmpty()) sb.append("\n")
// set time of next backup
when (nextScheduleTimeMillis) {
-1L -> {
val text = getString(R.string.settings_backup_last_backup_never)
sb.append(getString(R.string.settings_backup_status_next_backup, text))
}

Long.MAX_VALUE -> {
val text = if (backupManager.isBackupEnabled && storage?.isUsb != true) {
getString(R.string.notification_title)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import androidx.lifecycle.liveData
import androidx.lifecycle.map
import androidx.lifecycle.viewModelScope
import androidx.recyclerview.widget.DiffUtil.calculateDiff
import androidx.work.WorkInfo
import androidx.work.WorkManager
import com.stevesoltys.seedvault.R
import com.stevesoltys.seedvault.crypto.KeyManager
Expand Down Expand Up @@ -71,10 +72,9 @@ internal class SettingsViewModel(
val backupPossible: LiveData<Boolean> = mBackupPossible

internal val lastBackupTime = metadataManager.lastBackupTime
val nextScheduleTimeMillis =
internal val appBackupWorkInfo =
workManager.getWorkInfosForUniqueWorkLiveData(UNIQUE_WORK_NAME).map {
if (it.size > 0) it[0].nextScheduleTimeMillis
else -1L
it.getOrNull(0)
}

private val mAppStatusList = switchMap(lastBackupTime) {
Expand Down Expand Up @@ -139,6 +139,14 @@ internal class SettingsViewModel(
onStoragePropertiesChanged()
}

fun onWorkerStateChanged() {
viewModelScope.launch(Dispatchers.IO) {
val canDo = settingsManager.canDoBackupNow() &&
appBackupWorkInfo.value?.state != WorkInfo.State.RUNNING
mBackupPossible.postValue(canDo)
}
}

private fun onStoragePropertiesChanged() {
val storage = settingsManager.getStorage() ?: return

Expand All @@ -164,11 +172,8 @@ internal class SettingsViewModel(
connectivityManager.registerNetworkCallback(request, networkCallback)
networkCallback.registered = true
}

viewModelScope.launch(Dispatchers.IO) {
val canDo = settingsManager.canDoBackupNow()
mBackupPossible.postValue(canDo)
}
// update whether we can do backups right now or not
onWorkerStateChanged()
}

override fun onCleared() {
Expand All @@ -180,12 +185,7 @@ internal class SettingsViewModel(
}

internal fun backupNow() {
// maybe replace the check below with one that checks if our transport service is running
if (notificationManager.hasActiveBackupNotifications()) {
Toast.makeText(app, R.string.notification_backup_already_running, LENGTH_LONG).show()
} else if (!backupManager.isBackupEnabled) {
Toast.makeText(app, R.string.notification_backup_disabled, LENGTH_LONG).show()
} else viewModelScope.launch(Dispatchers.IO) {
viewModelScope.launch(Dispatchers.IO) {
if (settingsManager.isStorageBackupEnabled()) {
val i = Intent(app, StorageBackupService::class.java)
// this starts an app backup afterwards
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ force running with:
adb shell cmd jobscheduler run -f com.stevesoltys.seedvault 0
*/

internal class StorageBackupJobService : BackupJobService(StorageBackupService::class.java)

internal class StorageBackupService : BackupService() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,16 +192,6 @@ internal class BackupNotificationManager(private val context: Context) {
nm.notify(NOTIFICATION_ID_SUCCESS, notification)
}

fun hasActiveBackupNotifications(): Boolean {
nm.activeNotifications.forEach {
if (it.packageName == context.packageName) {
if (it.id == NOTIFICATION_ID_BACKGROUND) return true
if (it.id == NOTIFICATION_ID_OBSERVER) return it.isOngoing
}
}
return false
}

@SuppressLint("RestrictedApi")
fun onBackupError() {
val intent = Intent(context, SettingsActivity::class.java)
Expand Down

0 comments on commit 17b8b25

Please sign in to comment.