From ee46c74994dc9737a76e17673bbea92fe77bcfda Mon Sep 17 00:00:00 2001 From: Alex Baker Date: Wed, 9 Sep 2020 14:43:19 -0500 Subject: [PATCH] Update Android Backup Service implementation --- app/src/main/AndroidManifest.xml | 1 + .../java/org/tasks/backup/TasksBackupAgent.kt | 62 +--------------- .../org/tasks/backup/TasksFileBackupHelper.kt | 72 +++++++++++++++++++ .../java/org/tasks/preferences/Preferences.kt | 2 + 4 files changed, 77 insertions(+), 60 deletions(-) create mode 100644 app/src/main/java/org/tasks/backup/TasksFileBackupHelper.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5c84ef813..f5cd60844 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -124,6 +124,7 @@ android:allowBackup="true" android:backupAgent="org.tasks.backup.TasksBackupAgent" android:backupInForeground="true" + android:fullBackupOnly="false" android:networkSecurityConfig="@xml/network_security_config" android:icon="@mipmap/ic_launcher_blue" android:label="@string/app_name" diff --git a/app/src/main/java/org/tasks/backup/TasksBackupAgent.kt b/app/src/main/java/org/tasks/backup/TasksBackupAgent.kt index c2e33652d..d87004df8 100644 --- a/app/src/main/java/org/tasks/backup/TasksBackupAgent.kt +++ b/app/src/main/java/org/tasks/backup/TasksBackupAgent.kt @@ -1,74 +1,16 @@ package org.tasks.backup import android.app.backup.BackupAgentHelper -import android.app.backup.BackupDataInput -import android.app.backup.BackupDataOutput -import android.app.backup.FileBackupHelper -import android.net.Uri -import android.os.ParcelFileDescriptor -import com.todoroo.andlib.utility.DateUtilities.now -import com.todoroo.astrid.backup.BackupConstants -import dagger.hilt.EntryPoint -import dagger.hilt.InstallIn -import dagger.hilt.android.EntryPointAccessors -import dagger.hilt.android.components.ApplicationComponent -import kotlinx.coroutines.runBlocking -import org.tasks.R -import org.tasks.preferences.Preferences import timber.log.Timber -import java.io.File -import java.io.IOException class TasksBackupAgent : BackupAgentHelper() { - @EntryPoint - @InstallIn(ApplicationComponent::class) - internal interface TasksBackupAgentEntryPoint { - val tasksJsonImporter: TasksJsonImporter - val preferences: Preferences - } - - private lateinit var importer: TasksJsonImporter - private lateinit var preferences: Preferences - - private val enabled: Boolean - get() = preferences.getBoolean(R.string.p_backups_android_backup_enabled, true) override fun onCreate() { - EntryPointAccessors - .fromApplication(applicationContext, TasksBackupAgentEntryPoint::class.java) - .let { - importer = it.tasksJsonImporter - preferences = it.preferences - } - if (enabled) { - addHelper(BACKUP_KEY, FileBackupHelper(this, BackupConstants.INTERNAL_BACKUP)) - } - } - - @Throws(IOException::class) - override fun onRestore(data: BackupDataInput, appVersionCode: Int, newState: ParcelFileDescriptor) { - super.onRestore(data, appVersionCode, newState) - val backup = File(String.format( - "%s/%s", filesDir.absolutePath, BackupConstants.INTERNAL_BACKUP)) - if (backup.exists()) { - runBlocking { - importer.importTasks(this@TasksBackupAgent, Uri.fromFile(backup), null) - } - } else { - Timber.w("%s not found", backup.absolutePath) - } - } - - override fun onBackup(oldState: ParcelFileDescriptor?, data: BackupDataOutput?, newState: ParcelFileDescriptor?) { - super.onBackup(oldState, data, newState) - - if (enabled) { - preferences.setLong(R.string.p_backups_android_backup_last, now()) - } + addHelper(BACKUP_KEY, TasksFileBackupHelper(this)) } override fun onQuotaExceeded(backupDataBytes: Long, quotaBytes: Long) { - Timber.e("onQuotaExceeded(%s, %s)", backupDataBytes, quotaBytes) + Timber.e("onQuotaExceeded(backupDataBytes = $backupDataBytes, quotaBytes = $quotaBytes)") } companion object { diff --git a/app/src/main/java/org/tasks/backup/TasksFileBackupHelper.kt b/app/src/main/java/org/tasks/backup/TasksFileBackupHelper.kt new file mode 100644 index 000000000..086d8b16a --- /dev/null +++ b/app/src/main/java/org/tasks/backup/TasksFileBackupHelper.kt @@ -0,0 +1,72 @@ +package org.tasks.backup + +import android.app.backup.BackupDataInputStream +import android.app.backup.BackupDataOutput +import android.app.backup.FileBackupHelper +import android.content.Context +import android.net.Uri +import android.os.ParcelFileDescriptor +import com.todoroo.astrid.backup.BackupConstants +import dagger.hilt.EntryPoint +import dagger.hilt.InstallIn +import dagger.hilt.android.EntryPointAccessors +import dagger.hilt.android.components.ApplicationComponent +import kotlinx.coroutines.runBlocking +import org.tasks.R +import org.tasks.preferences.Preferences +import timber.log.Timber +import java.io.File + +class TasksFileBackupHelper( + private val context: Context +) : FileBackupHelper(context, BackupConstants.INTERNAL_BACKUP) { + + @EntryPoint + @InstallIn(ApplicationComponent::class) + internal interface TasksFileBackupHelperEntryPoint { + val tasksJsonImporter: TasksJsonImporter + val preferences: Preferences + } + + override fun performBackup( + oldState: ParcelFileDescriptor?, + data: BackupDataOutput?, + newState: ParcelFileDescriptor? + ) { + val preferences = hilt.preferences + if (!preferences.androidBackupServiceEnabled()) { + Timber.d("Android backup service disabled") + return + } + file + ?.let { + Timber.d("Backing up ${it.absolutePath}") + super.performBackup(oldState, data, newState) + preferences.setLong(R.string.p_backups_android_backup_last, it.lastModified()) + } + ?: Timber.e("$path not found") + } + + private val path: String + get() = "${context.filesDir.absolutePath}/${BackupConstants.INTERNAL_BACKUP}" + + private val file: File? + get() = File(path).takeIf { it.exists() } + + override fun restoreEntity(data: BackupDataInputStream?) { + super.restoreEntity(data) + + file + ?.let { + runBlocking { + Timber.d("Restoring ${it.absolutePath}") + hilt.tasksJsonImporter.importTasks(context, Uri.fromFile(it), null) + } + } + ?: Timber.e("$path not found") + } + + private val hilt: TasksFileBackupHelperEntryPoint + get() = EntryPointAccessors + .fromApplication(context, TasksFileBackupHelperEntryPoint::class.java) +} \ No newline at end of file diff --git a/app/src/main/java/org/tasks/preferences/Preferences.kt b/app/src/main/java/org/tasks/preferences/Preferences.kt index 9e0dead21..16ad52999 100644 --- a/app/src/main/java/org/tasks/preferences/Preferences.kt +++ b/app/src/main/java/org/tasks/preferences/Preferences.kt @@ -34,6 +34,8 @@ class Preferences @JvmOverloads constructor(private val context: Context, name: private val prefs: SharedPreferences = context.getSharedPreferences(name, Context.MODE_PRIVATE) private val publicPrefs: SharedPreferences = context.getSharedPreferences(AstridApiConstants.PUBLIC_PREFS, Context.MODE_PRIVATE) + fun androidBackupServiceEnabled() = getBoolean(R.string.p_backups_android_backup_enabled, true) + fun addTasksToTop(): Boolean { return getBoolean(R.string.p_add_to_top, true) }