Update Android Backup Service implementation

pull/1122/head
Alex Baker 4 years ago
parent cfe23c4f74
commit ee46c74994

@ -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"

@ -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 {

@ -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)
}

@ -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)
}

Loading…
Cancel
Save