From fc2c465bacafcedb2a3499fd4ed4d335e3cdfa98 Mon Sep 17 00:00:00 2001 From: arkon Date: Tue, 21 Apr 2020 21:34:22 -0400 Subject: [PATCH] Prevent multiple concurrent backups/restores --- .../tachiyomi/data/backup/BackupConst.kt | 10 ++-- .../tachiyomi/data/backup/BackupManager.kt | 4 +- .../data/backup/BackupRestoreService.kt | 6 +-- .../ui/setting/SettingsBackupController.kt | 51 ++++++++++++++----- app/src/main/res/values/strings.xml | 2 + 5 files changed, 49 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupConst.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupConst.kt index 9a34744b8..228e8c1b0 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupConst.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupConst.kt @@ -5,11 +5,11 @@ import eu.kanade.tachiyomi.BuildConfig.APPLICATION_ID as ID object BackupConst { const val INTENT_FILTER = "SettingsBackupFragment" - const val ACTION_BACKUP_COMPLETED_DIALOG = "$ID.$INTENT_FILTER.ACTION_BACKUP_COMPLETED_DIALOG" - const val ACTION_SET_PROGRESS_DIALOG = "$ID.$INTENT_FILTER.ACTION_SET_PROGRESS_DIALOG" - const val ACTION_ERROR_BACKUP_DIALOG = "$ID.$INTENT_FILTER.ACTION_ERROR_BACKUP_DIALOG" - const val ACTION_ERROR_RESTORE_DIALOG = "$ID.$INTENT_FILTER.ACTION_ERROR_RESTORE_DIALOG" - const val ACTION_RESTORE_COMPLETED_DIALOG = "$ID.$INTENT_FILTER.ACTION_RESTORE_COMPLETED_DIALOG" + const val ACTION_BACKUP_COMPLETED = "$ID.$INTENT_FILTER.ACTION_BACKUP_COMPLETED" + const val ACTION_BACKUP_ERROR = "$ID.$INTENT_FILTER.ACTION_BACKUP_ERROR" + const val ACTION_RESTORE_PROGRESS = "$ID.$INTENT_FILTER.ACTION_RESTORE_PROGRESS" + const val ACTION_RESTORE_COMPLETED = "$ID.$INTENT_FILTER.ACTION_RESTORE_COMPLETED" + const val ACTION_RESTORE_ERROR = "$ID.$INTENT_FILTER.ACTION_RESTORE_ERROR" const val ACTION = "$ID.$INTENT_FILTER.ACTION" const val EXTRA_PROGRESS = "$ID.$INTENT_FILTER.EXTRA_PROGRESS" const val EXTRA_AMOUNT = "$ID.$INTENT_FILTER.EXTRA_AMOUNT" diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupManager.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupManager.kt index 82238578e..41a8abe7f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupManager.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupManager.kt @@ -179,7 +179,7 @@ class BackupManager(val context: Context, version: Int = CURRENT_VERSION) { // Show completed dialog val intent = Intent(BackupConst.INTENT_FILTER).apply { - putExtra(BackupConst.ACTION, BackupConst.ACTION_BACKUP_COMPLETED_DIALOG) + putExtra(BackupConst.ACTION, BackupConst.ACTION_BACKUP_COMPLETED) putExtra(BackupConst.EXTRA_URI, file.uri.toString()) } context.sendLocalBroadcast(intent) @@ -189,7 +189,7 @@ class BackupManager(val context: Context, version: Int = CURRENT_VERSION) { if (!isJob) { // Show error dialog val intent = Intent(BackupConst.INTENT_FILTER).apply { - putExtra(BackupConst.ACTION, BackupConst.ACTION_ERROR_BACKUP_DIALOG) + putExtra(BackupConst.ACTION, BackupConst.ACTION_BACKUP_ERROR) putExtra(BackupConst.EXTRA_ERROR_MESSAGE, e.message) } context.sendLocalBroadcast(intent) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt index 0d95ef45e..234c10ac6 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt @@ -251,7 +251,7 @@ class BackupRestoreService : Service() { putExtra(BackupConst.EXTRA_ERRORS, errors.size) putExtra(BackupConst.EXTRA_ERROR_FILE_PATH, logFile.parent) putExtra(BackupConst.EXTRA_ERROR_FILE, logFile.name) - putExtra(BackupConst.ACTION, BackupConst.ACTION_RESTORE_COMPLETED_DIALOG) + putExtra(BackupConst.ACTION, BackupConst.ACTION_RESTORE_COMPLETED) } sendLocalBroadcast(completeIntent) } @@ -259,7 +259,7 @@ class BackupRestoreService : Service() { Timber.e(error) writeErrorLog() val errorIntent = Intent(BackupConst.INTENT_FILTER).apply { - putExtra(BackupConst.ACTION, BackupConst.ACTION_ERROR_RESTORE_DIALOG) + putExtra(BackupConst.ACTION, BackupConst.ACTION_RESTORE_ERROR) putExtra(BackupConst.EXTRA_ERROR_MESSAGE, error.message) } sendLocalBroadcast(errorIntent) @@ -463,7 +463,7 @@ class BackupRestoreService : Service() { putExtra(BackupConst.EXTRA_AMOUNT, amount) putExtra(BackupConst.EXTRA_CONTENT, content) putExtra(BackupConst.EXTRA_ERRORS, errors) - putExtra(BackupConst.ACTION, BackupConst.ACTION_SET_PROGRESS_DIALOG) + putExtra(BackupConst.ACTION, BackupConst.ACTION_RESTORE_PROGRESS) } sendLocalBroadcast(intent) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsBackupController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsBackupController.kt index e4e5d9468..de820dac8 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsBackupController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsBackupController.kt @@ -73,9 +73,13 @@ class SettingsBackupController : SettingsController() { summaryRes = R.string.pref_create_backup_summ onClick { - val ctrl = CreateBackupDialog() - ctrl.targetController = this@SettingsBackupController - ctrl.showDialog(router) + if (!isBackupStarted) { + val ctrl = CreateBackupDialog() + ctrl.targetController = this@SettingsBackupController + ctrl.showDialog(router) + } else { + context.toast(R.string.backup_in_progress) + } } } preference { @@ -83,12 +87,16 @@ class SettingsBackupController : SettingsController() { summaryRes = R.string.pref_restore_backup_summ onClick { - val intent = Intent(Intent.ACTION_GET_CONTENT) - intent.addCategory(Intent.CATEGORY_OPENABLE) - intent.type = "application/*" - val title = resources?.getString(R.string.file_select_backup) - val chooser = Intent.createChooser(intent, title) - startActivityForResult(chooser, CODE_BACKUP_RESTORE) + if (!isRestoreStarted) { + val intent = Intent(Intent.ACTION_GET_CONTENT) + intent.addCategory(Intent.CATEGORY_OPENABLE) + intent.type = "application/*" + val title = resources?.getString(R.string.file_select_backup) + val chooser = Intent.createChooser(intent, title) + startActivityForResult(chooser, CODE_BACKUP_RESTORE) + } else { + context.toast(R.string.restore_in_progress) + } } } preferenceCategory { @@ -183,6 +191,8 @@ class SettingsBackupController : SettingsController() { notifier.showBackupProgress() BackupCreateService.makeBackup(activity, file.uri, backupFlags) + + isBackupStarted = true } CODE_BACKUP_RESTORE -> if (data != null && resultCode == Activity.RESULT_OK) { val uri = data.data @@ -260,6 +270,8 @@ class SettingsBackupController : SettingsController() { if (context != null) { RestoringBackupDialog().showDialog(router, TAG_RESTORING_BACKUP_DIALOG) BackupRestoreService.start(context, args.getParcelable(KEY_URI)!!) + + isRestoreStarted = true } } .build() @@ -308,22 +320,28 @@ class SettingsBackupController : SettingsController() { inner class BackupBroadcastReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { when (intent.getStringExtra(BackupConst.ACTION)) { - BackupConst.ACTION_BACKUP_COMPLETED_DIALOG -> { + BackupConst.ACTION_BACKUP_COMPLETED -> { + isBackupStarted = false + val uri = Uri.parse(intent.getStringExtra(BackupConst.EXTRA_URI)) val unifile = UniFile.fromUri(activity, uri) notifier.showBackupComplete(unifile) } - BackupConst.ACTION_ERROR_BACKUP_DIALOG -> { + BackupConst.ACTION_BACKUP_ERROR -> { + isBackupStarted = false + notifier.showBackupError(intent.getStringExtra(BackupConst.EXTRA_ERROR_MESSAGE)) } - BackupConst.ACTION_SET_PROGRESS_DIALOG -> { + BackupConst.ACTION_RESTORE_PROGRESS -> { val progress = intent.getIntExtra(BackupConst.EXTRA_PROGRESS, 0) val amount = intent.getIntExtra(BackupConst.EXTRA_AMOUNT, 0) val content = intent.getStringExtra(BackupConst.EXTRA_CONTENT) (router.getControllerWithTag(TAG_RESTORING_BACKUP_DIALOG) as? RestoringBackupDialog)?.updateProgress(content, progress, amount) } - BackupConst.ACTION_RESTORE_COMPLETED_DIALOG -> { + BackupConst.ACTION_RESTORE_COMPLETED -> { + isRestoreStarted = false + router.popControllerWithTag(TAG_RESTORING_BACKUP_DIALOG) val time = intent.getLongExtra(BackupConst.EXTRA_TIME, 0) val errorCount = intent.getIntExtra(BackupConst.EXTRA_ERRORS, 0) @@ -331,7 +349,9 @@ class SettingsBackupController : SettingsController() { val file = intent.getStringExtra(BackupConst.EXTRA_ERROR_FILE) notifier.showRestoreComplete(time, errorCount, path, file) } - BackupConst.ACTION_ERROR_RESTORE_DIALOG -> { + BackupConst.ACTION_RESTORE_ERROR -> { + isRestoreStarted = false + router.popControllerWithTag(TAG_RESTORING_BACKUP_DIALOG) notifier.showRestoreError(intent.getStringExtra(BackupConst.EXTRA_ERROR_MESSAGE)) } @@ -345,5 +365,8 @@ class SettingsBackupController : SettingsController() { const val CODE_BACKUP_DIR = 503 const val TAG_RESTORING_BACKUP_DIALOG = "RestoringBackupDialog" + + var isBackupStarted = false + var isRestoreStarted = false } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d80cc824e..b50074408 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -323,9 +323,11 @@ Restore took %1$s with %2$s errors Restore uses sources to fetch data, carrier costs may apply.\n\nMake sure you have installed all necessary extensions and are logged in to sources and tracking services before restoring. File saved at %1$s + Backup is already in progress What do you want to backup? Creating backup Backup failed + Restore is already in progress Restoring backup Restoring backup failed