From 911a8dabf4e3625321671d19c585cdd64d0c760c Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Wed, 21 Feb 2024 14:53:15 -0300 Subject: [PATCH] Expose time of next backup in UI to help debugging scheduling issues --- .../seedvault/settings/SettingsFragment.kt | 49 +++++++++++++++++-- .../seedvault/settings/SettingsViewModel.kt | 9 ++++ .../seedvault/worker/AppBackupWorker.kt | 2 +- app/src/main/res/values/strings.xml | 2 + 4 files changed, 56 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/stevesoltys/seedvault/settings/SettingsFragment.kt b/app/src/main/java/com/stevesoltys/seedvault/settings/SettingsFragment.kt index 8115c533..466107c0 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/settings/SettingsFragment.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/settings/SettingsFragment.kt @@ -140,7 +140,10 @@ class SettingsFragment : PreferenceFragmentCompat() { super.onViewCreated(view, savedInstanceState) viewModel.lastBackupTime.observe(viewLifecycleOwner) { time -> - setAppBackupStatusSummary(time) + setAppBackupStatusSummary(time, viewModel.nextScheduleTimeMillis.value) + } + viewModel.nextScheduleTimeMillis.observe(viewLifecycleOwner) { time -> + setAppBackupStatusSummary(viewModel.lastBackupTime.value, time) } val backupFiles: Preference = findPreference("backup_files")!! @@ -159,6 +162,10 @@ class SettingsFragment : PreferenceFragmentCompat() { setBackupEnabledState() setBackupLocationSummary() setAutoRestoreState() + setAppBackupStatusSummary( + lastBackupInMillis = viewModel.lastBackupTime.value, + nextScheduleTimeMillis = viewModel.nextScheduleTimeMillis.value, + ) } override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { @@ -244,10 +251,42 @@ class SettingsFragment : PreferenceFragmentCompat() { backupLocation.summary = storage?.name ?: getString(R.string.settings_backup_location_none) } - private fun setAppBackupStatusSummary(lastBackupInMillis: Long) { - // set time of last backup - val lastBackup = lastBackupInMillis.toRelativeTime(requireContext()) - backupStatus.summary = getString(R.string.settings_backup_status_summary, lastBackup) + private fun setAppBackupStatusSummary( + lastBackupInMillis: Long?, + nextScheduleTimeMillis: Long?, + ) { + val sb = StringBuilder() + if (lastBackupInMillis != null) { + // set time of last backup + val lastBackup = lastBackupInMillis.toRelativeTime(requireContext()) + sb.append(getString(R.string.settings_backup_status_summary, lastBackup)) + } + if (nextScheduleTimeMillis != null) { + // insert linebreak, if we have text before + 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) { + getString(R.string.notification_title) + } else { + getString(R.string.settings_backup_last_backup_never) + } + sb.append(getString(R.string.settings_backup_status_next_backup, text)) + } + + else -> { + val text = nextScheduleTimeMillis.toRelativeTime(requireContext()) + sb.append(getString(R.string.settings_backup_status_next_backup_estimate, text)) + } + } + } + backupStatus.summary = sb.toString() } private fun onEnablingStorageBackup() { 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 6508aa7c..d241e919 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/settings/SettingsViewModel.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/settings/SettingsViewModel.kt @@ -22,9 +22,11 @@ import androidx.core.content.ContextCompat.startForegroundService import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.liveData +import androidx.lifecycle.map import androidx.lifecycle.switchMap import androidx.lifecycle.viewModelScope import androidx.recyclerview.widget.DiffUtil.calculateDiff +import androidx.work.WorkManager import com.stevesoltys.seedvault.R import com.stevesoltys.seedvault.crypto.KeyManager import com.stevesoltys.seedvault.metadata.MetadataManager @@ -35,6 +37,7 @@ import com.stevesoltys.seedvault.storage.StorageBackupService.Companion.EXTRA_ST import com.stevesoltys.seedvault.ui.RequireProvisioningViewModel import com.stevesoltys.seedvault.ui.notification.BackupNotificationManager import com.stevesoltys.seedvault.worker.AppBackupWorker +import com.stevesoltys.seedvault.worker.AppBackupWorker.Companion.UNIQUE_WORK_NAME import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -61,6 +64,7 @@ internal class SettingsViewModel( private val contentResolver = app.contentResolver private val connectivityManager: ConnectivityManager? = app.getSystemService(ConnectivityManager::class.java) + private val workManager = WorkManager.getInstance(app) override val isRestoreOperation = false @@ -68,6 +72,11 @@ internal class SettingsViewModel( val backupPossible: LiveData = mBackupPossible internal val lastBackupTime = metadataManager.lastBackupTime + val nextScheduleTimeMillis = + workManager.getWorkInfosForUniqueWorkLiveData(UNIQUE_WORK_NAME).map { + if (it.size > 0) it[0].nextScheduleTimeMillis + else -1L + } private val mAppStatusList = lastBackupTime.switchMap { // updates app list when lastBackupTime changes diff --git a/app/src/main/java/com/stevesoltys/seedvault/worker/AppBackupWorker.kt b/app/src/main/java/com/stevesoltys/seedvault/worker/AppBackupWorker.kt index f6cc1b45..43f53d95 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/worker/AppBackupWorker.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/worker/AppBackupWorker.kt @@ -35,7 +35,7 @@ class AppBackupWorker( companion object { private val TAG = AppBackupWorker::class.simpleName - private const val UNIQUE_WORK_NAME = "com.stevesoltys.seedvault.APP_BACKUP" + internal 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) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 44097e71..13c09436 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -30,6 +30,8 @@ Disable app backup Backup status Last backup: %1$s + Next backup: %1$s + Next backup (estimate): %1$s Exclude apps Backup now Storage backup (beta)