Skip to content

Commit

Permalink
WIP: to test: Don't allow running app data check while backup is running
Browse files Browse the repository at this point in the history
  • Loading branch information
grote committed Oct 29, 2024
1 parent 4cb418e commit c0cd2ed
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 30 deletions.
25 changes: 18 additions & 7 deletions app/src/main/java/com/stevesoltys/seedvault/BackupStateManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import com.stevesoltys.seedvault.storage.StorageBackupService
import com.stevesoltys.seedvault.transport.ConfigurableBackupTransportService
import com.stevesoltys.seedvault.worker.AppBackupPruneWorker
import com.stevesoltys.seedvault.worker.AppBackupWorker.Companion.UNIQUE_WORK_NAME
import com.stevesoltys.seedvault.worker.AppCheckerWorker
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine

Expand All @@ -32,18 +33,28 @@ class BackupStateManager(
flow = ConfigurableBackupTransportService.isRunning,
flow2 = StorageBackupService.isRunning,
flow3 = workManager.getWorkInfosForUniqueWorkFlow(UNIQUE_WORK_NAME),
flow4 = workManager.getWorkInfosForUniqueWorkFlow(AppBackupPruneWorker.UNIQUE_WORK_NAME),
) { appBackupRunning, filesBackupRunning, workInfo1, workInfo2 ->
) { appBackupRunning, filesBackupRunning, workInfo1 ->
val workInfoState1 = workInfo1.getOrNull(0)?.state
val workInfoState2 = workInfo2.getOrNull(0)?.state
Log.i(
TAG, "appBackupRunning: $appBackupRunning, " +
"filesBackupRunning: $filesBackupRunning, " +
"appBackupWorker: ${workInfoState1?.name}, " +
"pruneBackupWorker: ${workInfoState2?.name}"
"appBackupWorker: ${workInfoState1?.name}"
)
appBackupRunning || filesBackupRunning ||
workInfoState1 == RUNNING || workInfoState2 == RUNNING
appBackupRunning || filesBackupRunning || workInfoState1 == RUNNING
}

val isCheckOrPruneRunning: Flow<Boolean> = combine(
flow = workManager.getWorkInfosForUniqueWorkFlow(AppBackupPruneWorker.UNIQUE_WORK_NAME),
flow2 = workManager.getWorkInfosForUniqueWorkFlow(AppCheckerWorker.UNIQUE_WORK_NAME),
) { pruneInfo, checkInfo ->
val pruneInfoState = pruneInfo.getOrNull(0)?.state
val checkInfoState = checkInfo.getOrNull(0)?.state
Log.i(
TAG,
"pruneBackupWorker: ${pruneInfoState?.name}, " +
"appCheckerWorker: ${checkInfoState?.name}"
)
pruneInfoState == RUNNING || checkInfoState == RUNNING
}

val isAutoRestoreEnabled: Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
private lateinit var backupLocation: Preference
private lateinit var backupStatus: Preference
private lateinit var backupScheduling: Preference
private lateinit var backupAppCheck: Preference
private lateinit var backupStorage: TwoStatePreference
private lateinit var backupRecoveryCode: Preference

Expand Down Expand Up @@ -92,14 +93,8 @@ class SettingsFragment : PreferenceFragmentCompat() {

backupLocation = findPreference("backup_location")!!
backupLocation.setOnPreferenceClickListener {
if (viewModel.isBackupRunning.value) {
// don't allow changing backup destination while backup is running
// TODO we could show toast or snackbar here
false
} else {
viewModel.chooseBackupLocation()
true
}
viewModel.chooseBackupLocation()
true
}

autoRestore = findPreference(PREF_KEY_AUTO_RESTORE)!!
Expand All @@ -117,6 +112,7 @@ class SettingsFragment : PreferenceFragmentCompat() {

backupStatus = findPreference("backup_status")!!
backupScheduling = findPreference("backup_scheduling")!!
backupAppCheck = findPreference("backup_app_check")!!

backupStorage = findPreference("backup_storage")!!
backupStorage.onPreferenceChangeListener = OnPreferenceChangeListener { _, newValue ->
Expand Down Expand Up @@ -148,6 +144,8 @@ class SettingsFragment : PreferenceFragmentCompat() {
viewModel.backupPossible.observe(viewLifecycleOwner) { possible ->
toolbar.menu.findItem(R.id.action_backup)?.isEnabled = possible
toolbar.menu.findItem(R.id.action_restore)?.isEnabled = possible
backupLocation.isEnabled = possible
backupAppCheck.isEnabled = possible
}

viewModel.lastBackupTime.observe(viewLifecycleOwner) { time ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ internal class SettingsViewModel(
override val isRestoreOperation = false
val isFirstStart get() = settingsManager.isFirstStart

val isBackupRunning: StateFlow<Boolean>
private val isBackupRunning: StateFlow<Boolean>
private val isCheckOrPruneRunning: StateFlow<Boolean>
private val mBackupPossible = MutableLiveData(false)
val backupPossible: LiveData<Boolean> = mBackupPossible

Expand Down Expand Up @@ -144,12 +145,23 @@ internal class SettingsViewModel(
started = SharingStarted.Eagerly,
initialValue = false,
)
isCheckOrPruneRunning = backupStateManager.isCheckOrPruneRunning.stateIn(
scope = viewModelScope,
started = SharingStarted.Eagerly,
initialValue = false,
)
scope.launch {
// update running state
isBackupRunning.collect {
onBackupRunningStateChanged()
}
}
scope.launch {
// update running state
isCheckOrPruneRunning.collect {
onBackupRunningStateChanged()
}
}
onStoragePropertiesChanged()
loadFilesSummary()
}
Expand All @@ -172,11 +184,11 @@ internal class SettingsViewModel(
}

private fun onBackupRunningStateChanged() {
if (isBackupRunning.value) mBackupPossible.postValue(false)
else viewModelScope.launch(Dispatchers.IO) {
val canDo = !isBackupRunning.value && !backendManager.isOnUnavailableUsb()
val backupAllowed = !isBackupRunning.value && !isCheckOrPruneRunning.value
if (backupAllowed) viewModelScope.launch(Dispatchers.IO) {
val canDo = !backendManager.isOnUnavailableUsb()
mBackupPossible.postValue(canDo)
}
} else mBackupPossible.postValue(false)
}

private fun onStoragePropertiesChanged() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ 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.BackupStateManager
import com.stevesoltys.seedvault.R
import com.stevesoltys.seedvault.backend.BackendManager
import com.stevesoltys.seedvault.repo.AppBackupManager
import com.stevesoltys.seedvault.settings.SettingsManager
import com.stevesoltys.seedvault.ui.notification.BackupNotificationManager
import com.stevesoltys.seedvault.ui.notification.NOTIFICATION_ID_OBSERVER
import kotlinx.coroutines.flow.first
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import java.util.concurrent.TimeUnit
Expand Down Expand Up @@ -100,6 +102,7 @@ class AppBackupWorker(
}
}

private val backupStateManager: BackupStateManager by inject()
private val backupRequester: BackupRequester by inject()
private val settingsManager: SettingsManager by inject()
private val apkBackupManager: ApkBackupManager by inject()
Expand All @@ -109,6 +112,10 @@ class AppBackupWorker(

override suspend fun doWork(): Result {
Log.i(TAG, "Start worker $this ($id)")
if (backupStateManager.isCheckOrPruneRunning.first()) {
Log.i(TAG, "isCheckOrPruneRunning was true, so retrying later...")
return Result.retry()
}
try {
setForeground(createForegroundInfo())
} catch (e: Exception) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST
import androidx.work.WorkManager
import androidx.work.WorkerParameters
import com.stevesoltys.seedvault.BackupStateManager
import com.stevesoltys.seedvault.repo.Checker
import com.stevesoltys.seedvault.ui.notification.BackupNotificationManager
import com.stevesoltys.seedvault.ui.notification.NOTIFICATION_ID_CHECKING
import io.github.oshai.kotlinlogging.KotlinLogging
import kotlinx.coroutines.flow.first
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import java.time.Duration
Expand Down Expand Up @@ -50,12 +52,16 @@ class AppCheckerWorker(
}

private val log = KotlinLogging.logger {}
private val backupStateManager: BackupStateManager by inject()
private val checker: Checker by inject()
private val nm: BackupNotificationManager by inject()

override suspend fun doWork(): Result {
// TODO don't let backup/restore happen while we check
log.info { "Start worker $this ($id)" }
if (backupStateManager.isBackupRunning.first()) {
Log.i(TAG, "isBackupRunning was true, so retrying later...")
return Result.retry()
}
try {
setForeground(createForegroundInfo())
} catch (e: Exception) {
Expand All @@ -64,14 +70,8 @@ class AppCheckerWorker(
val percent = inputData.getInt(PERCENT, -1)
check(percent in 0..100) { "Percent $percent out of bounds." }

return try {
checker.check(percent)
Result.success()
} catch (e: Exception) {
// TODO maybe show error notification
log.error(e) { "Error while checking data: " }
Result.retry()
}
checker.check(percent)
return Result.success()
}

private fun createForegroundInfo() = ForegroundInfo(
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/xml/settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
<androidx.preference.Preference
app:fragment="com.stevesoltys.seedvault.ui.check.AppCheckFragment"
app:icon="@drawable/ic_cloud_search"
app:key="backup_scheduling"
app:key="backup_app_check"
app:summary="@string/settings_backup_app_check_summary"
app:title="@string/settings_backup_app_check_title" />

Expand Down

0 comments on commit c0cd2ed

Please sign in to comment.