From 1d3f7af099f55a41a8fcd6039c1c6d986c274473 Mon Sep 17 00:00:00 2001 From: Jakob Nixdorf Date: Sat, 6 Feb 2021 16:18:16 +0100 Subject: [PATCH] Refactor backup tasks Base the backup tasks on UiBasedBackgroundTask --- .../andotp/Activities/BackupActivity.java | 79 ++++------- .../flocke/andotp/Tasks/BackupTask.java | 124 ------------------ .../andotp/Tasks/EncryptedBackupTask.java | 37 ++++++ .../andotp/Tasks/GenericBackupTask.java | 70 ++++++++++ .../flocke/andotp/Tasks/PGPBackupTask.java | 30 +++++ .../andotp/Tasks/PlainTextBackupTask.java | 35 +++++ .../flocke/andotp/Utilities/BackupHelper.java | 19 --- 7 files changed, 201 insertions(+), 193 deletions(-) delete mode 100644 app/src/main/java/org/shadowice/flocke/andotp/Tasks/BackupTask.java create mode 100644 app/src/main/java/org/shadowice/flocke/andotp/Tasks/EncryptedBackupTask.java create mode 100644 app/src/main/java/org/shadowice/flocke/andotp/Tasks/GenericBackupTask.java create mode 100644 app/src/main/java/org/shadowice/flocke/andotp/Tasks/PGPBackupTask.java create mode 100644 app/src/main/java/org/shadowice/flocke/andotp/Tasks/PlainTextBackupTask.java diff --git a/app/src/main/java/org/shadowice/flocke/andotp/Activities/BackupActivity.java b/app/src/main/java/org/shadowice/flocke/andotp/Activities/BackupActivity.java index ec154f3b..fdf39215 100644 --- a/app/src/main/java/org/shadowice/flocke/andotp/Activities/BackupActivity.java +++ b/app/src/main/java/org/shadowice/flocke/andotp/Activities/BackupActivity.java @@ -53,7 +53,10 @@ import org.openintents.openpgp.util.OpenPgpServiceConnection; import org.shadowice.flocke.andotp.Database.Entry; import org.shadowice.flocke.andotp.Dialogs.PasswordEntryDialog; import org.shadowice.flocke.andotp.R; -import org.shadowice.flocke.andotp.Tasks.BackupTask; +import org.shadowice.flocke.andotp.Tasks.EncryptedBackupTask; +import org.shadowice.flocke.andotp.Tasks.GenericBackupTask; +import org.shadowice.flocke.andotp.Tasks.PGPBackupTask; +import org.shadowice.flocke.andotp.Tasks.PlainTextBackupTask; import org.shadowice.flocke.andotp.Utilities.BackupHelper; import org.shadowice.flocke.andotp.Utilities.Constants; import org.shadowice.flocke.andotp.Utilities.DatabaseHelper; @@ -68,13 +71,10 @@ import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import javax.crypto.SecretKey; -public class BackupActivity extends BaseActivity - implements BackupTask.BackupCallback { +public class BackupActivity extends BaseActivity { private final static String TAG = BackupActivity.class.getSimpleName(); private Constants.BackupType backupType = Constants.BackupType.ENCRYPTED; @@ -259,36 +259,18 @@ public class BackupActivity extends BaseActivity pgpServiceConnection.unbindFromService(); } - @Override - public void onBackupFinished() { - hideProgress(); + private void handleBackupTaskResult(GenericBackupTask.BackupTaskResult result) { + Toast.makeText(this, result.messageId, Toast.LENGTH_LONG).show(); + showBackupProgress(false); } - @Override - public void onBackupFailed() { - hideProgress(); - } + private void showBackupProgress(boolean running) { + btnBackup.setEnabled(!running); + btnRestore.setEnabled(!running); + chkOldFormat.setEnabled(!running); + swReplace.setEnabled(!running); - private void showProgress(boolean restore) { - btnBackup.setEnabled(false); - btnRestore.setEnabled(false); - chkOldFormat.setEnabled(false); - swReplace.setEnabled(false); - - if (restore) - progressRestore.setVisibility(View.VISIBLE); - else - progressBackup.setVisibility(View.VISIBLE); - } - - private void hideProgress() { - btnBackup.setEnabled(true); - btnRestore.setEnabled(true); - chkOldFormat.setEnabled(true); - swReplace.setEnabled(true); - - progressRestore.setVisibility(View.GONE); - progressBackup.setVisibility(View.GONE); + progressBackup.setVisibility(running ? View.VISIBLE : View.GONE); } // Get the result from external activities @@ -414,15 +396,11 @@ public class BackupActivity extends BaseActivity if (Tools.isExternalStorageWritable()) { ArrayList entries = DatabaseHelper.loadDatabase(this, encryptionKey); - ExecutorService executor = Executors.newSingleThreadExecutor(); + PlainTextBackupTask task = new PlainTextBackupTask(this, entries, uri); + task.setCallback(this::handleBackupTaskResult); - BackupTask backupTask = new BackupTask(this, Constants.BackupType.PLAIN_TEXT, DatabaseHelper.entriesToString(entries), this); - - if (uri != null) - backupTask.setUri(uri); - - showProgress(false); - executor.execute(backupTask); + task.execute(); + showBackupProgress(true); } else { Toast.makeText(this, R.string.backup_toast_storage_not_accessible, Toast.LENGTH_LONG).show(); } @@ -524,8 +502,13 @@ public class BackupActivity extends BaseActivity private void doBackupCryptWithPassword(Uri uri, String password) { if (Tools.isExternalStorageWritable()) { - showProgress(false); - BackupHelper.backupToFileAsync(this, uri, password, encryptionKey, this, false); + ArrayList entries = DatabaseHelper.loadDatabase(this, encryptionKey); + + EncryptedBackupTask task = new EncryptedBackupTask(this, entries, password, uri); + task.setCallback(this::handleBackupTaskResult); + + task.execute(); + showBackupProgress(true); } else { Toast.makeText(this, R.string.backup_toast_storage_not_accessible, Toast.LENGTH_LONG).show(); } @@ -548,15 +531,11 @@ public class BackupActivity extends BaseActivity private void doBackupEncrypted(Uri uri, String data) { if (Tools.isExternalStorageWritable()) { - ExecutorService executor = Executors.newSingleThreadExecutor(); + PGPBackupTask task = new PGPBackupTask(this, data, uri); + task.setCallback(this::handleBackupTaskResult); - BackupTask backupTask = new BackupTask(this, Constants.BackupType.OPEN_PGP, data, this); - - if (uri != null) - backupTask.setUri(uri); - - showProgress(false); - executor.execute(backupTask); + task.execute(); + showBackupProgress(true); } else { Toast.makeText(this, R.string.backup_toast_storage_not_accessible, Toast.LENGTH_LONG).show(); } diff --git a/app/src/main/java/org/shadowice/flocke/andotp/Tasks/BackupTask.java b/app/src/main/java/org/shadowice/flocke/andotp/Tasks/BackupTask.java deleted file mode 100644 index 9a5c7705..00000000 --- a/app/src/main/java/org/shadowice/flocke/andotp/Tasks/BackupTask.java +++ /dev/null @@ -1,124 +0,0 @@ -package org.shadowice.flocke.andotp.Tasks; - -import android.content.Context; -import android.net.Uri; -import android.os.Handler; -import android.os.Looper; -import android.widget.Toast; - -import org.shadowice.flocke.andotp.R; -import org.shadowice.flocke.andotp.Utilities.BackupHelper; -import org.shadowice.flocke.andotp.Utilities.Constants; -import org.shadowice.flocke.andotp.Utilities.Settings; -import org.shadowice.flocke.andotp.Utilities.StorageAccessHelper; - -public class BackupTask implements Runnable { - final private Context context; - final private String payload; - final private Constants.BackupType type; - final private BackupCallback callback; - - final private Handler handler; - - private boolean silent = false; - private Uri uri = null; - private String password = null; - - public BackupTask(Context context, Constants.BackupType type, String payload, BackupCallback callback) { - this.context = context; - this.payload = payload; - this.type = type; - this.callback = callback; - - this.handler = new Handler(Looper.getMainLooper()); - } - - public void setUri(Uri uri) { - this.uri = uri; - } - - public void setPassword(String password) { - this.password = password; - } - - public void setSilent(boolean silent) { - this.silent = silent; - } - - @Override - public void run() { - boolean success; - - if (uri == null) - uri = getTargetUri(); - - if (uri == null) - return; - - if (type == Constants.BackupType.PLAIN_TEXT) { - success = StorageAccessHelper.saveFile(context, uri, payload); - } else if (type == Constants.BackupType.ENCRYPTED) { - success = BackupHelper.backupToFile(context, uri, password, payload); - } else if (type == Constants.BackupType.OPEN_PGP) { - success = StorageAccessHelper.saveFile(context, uri, payload); - } else { - success = false; - } - - if (success) - onFinished(); - else - onFailed(); - } - - private Uri getTargetUri() { - Settings settings = new Settings(context); - - BackupHelper.BackupFile backupFile = BackupHelper.backupFile(context, settings.getBackupLocation(), type); - - if (backupFile.file != null) { - return backupFile.file.getUri(); - } else { - showToast(context, backupFile.errorMessage); - return null; - } - } - - private void showToast(Context context, int msgId) { - if (!this.silent) { - this.handler.post(new Runnable() { - @Override - public void run() { - Toast.makeText(context, msgId, Toast.LENGTH_LONG).show(); - } - }); - } - } - - private void onFinished() { - this.handler.post(new Runnable() { - @Override - public void run() { - Toast.makeText(context, R.string.backup_toast_export_success, Toast.LENGTH_LONG).show(); - if (callback != null) - callback.onBackupFinished(); - } - }); - } - - private void onFailed() { - this.handler.post(new Runnable() { - @Override - public void run() { - Toast.makeText(context, R.string.backup_toast_export_failed, Toast.LENGTH_LONG).show(); - if (callback != null) - callback.onBackupFailed(); - } - }); - } - - public interface BackupCallback { - void onBackupFinished(); - void onBackupFailed(); - } -} diff --git a/app/src/main/java/org/shadowice/flocke/andotp/Tasks/EncryptedBackupTask.java b/app/src/main/java/org/shadowice/flocke/andotp/Tasks/EncryptedBackupTask.java new file mode 100644 index 00000000..f810a34d --- /dev/null +++ b/app/src/main/java/org/shadowice/flocke/andotp/Tasks/EncryptedBackupTask.java @@ -0,0 +1,37 @@ +package org.shadowice.flocke.andotp.Tasks; + +import android.content.Context; +import android.net.Uri; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import org.shadowice.flocke.andotp.Database.Entry; +import org.shadowice.flocke.andotp.Utilities.BackupHelper; +import org.shadowice.flocke.andotp.Utilities.Constants; +import org.shadowice.flocke.andotp.Utilities.DatabaseHelper; + +import java.util.ArrayList; + +public class EncryptedBackupTask extends GenericBackupTask { + private final String password; + private final ArrayList entries; + + public EncryptedBackupTask(Context context, ArrayList entries, String password, @Nullable Uri uri) { + super(context, uri); + this.entries = entries; + this.password = password; + } + + @Override + @NonNull + protected Constants.BackupType getBackupType() { + return Constants.BackupType.ENCRYPTED; + } + + @Override + protected boolean doBackup() { + String payload = DatabaseHelper.entriesToString(entries); + return BackupHelper.backupToFile(applicationContext, uri, password, payload); + } +} diff --git a/app/src/main/java/org/shadowice/flocke/andotp/Tasks/GenericBackupTask.java b/app/src/main/java/org/shadowice/flocke/andotp/Tasks/GenericBackupTask.java new file mode 100644 index 00000000..5c18afb2 --- /dev/null +++ b/app/src/main/java/org/shadowice/flocke/andotp/Tasks/GenericBackupTask.java @@ -0,0 +1,70 @@ +package org.shadowice.flocke.andotp.Tasks; + +import android.content.Context; +import android.net.Uri; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import org.shadowice.flocke.andotp.R; +import org.shadowice.flocke.andotp.Utilities.BackupHelper; +import org.shadowice.flocke.andotp.Utilities.Constants; +import org.shadowice.flocke.andotp.Utilities.Settings; + +public abstract class GenericBackupTask extends UiBasedBackgroundTask { + protected final Context applicationContext; + protected final Settings settings; + protected final Constants.BackupType type; + protected Uri uri; + + public GenericBackupTask(Context context, @Nullable Uri uri) { + super(BackupTaskResult.failure()); + + this.applicationContext = context.getApplicationContext(); + this.settings = new Settings(applicationContext); + + this.type = getBackupType(); + this.uri = uri; + } + + @Override + @NonNull + protected BackupTaskResult doInBackground() { + if (uri == null) { + BackupHelper.BackupFile backupFile = BackupHelper.backupFile(applicationContext, settings.getBackupLocation(), type); + + if (backupFile.file == null) + return new BackupTaskResult(backupFile.errorMessage); + + uri = backupFile.file.getUri(); + } + + boolean success = doBackup(); + + if (success) + return BackupTaskResult.success(); + else + return BackupTaskResult.failure(); + } + + @NonNull + protected abstract Constants.BackupType getBackupType(); + protected abstract boolean doBackup(); + + + public static class BackupTaskResult { + public final int messageId; + + public BackupTaskResult(int messageId) { + this.messageId = messageId; + } + + public static BackupTaskResult success() { + return new BackupTaskResult(R.string.backup_toast_export_success); + } + + public static BackupTaskResult failure() { + return new BackupTaskResult(R.string.backup_toast_export_failed); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/shadowice/flocke/andotp/Tasks/PGPBackupTask.java b/app/src/main/java/org/shadowice/flocke/andotp/Tasks/PGPBackupTask.java new file mode 100644 index 00000000..1d900614 --- /dev/null +++ b/app/src/main/java/org/shadowice/flocke/andotp/Tasks/PGPBackupTask.java @@ -0,0 +1,30 @@ +package org.shadowice.flocke.andotp.Tasks; + +import android.content.Context; +import android.net.Uri; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import org.shadowice.flocke.andotp.Utilities.Constants; +import org.shadowice.flocke.andotp.Utilities.StorageAccessHelper; + +public class PGPBackupTask extends GenericBackupTask { + private final String payload; + + public PGPBackupTask(Context context, String payload, @Nullable Uri uri) { + super(context, uri); + this.payload = payload; + } + + @Override + @NonNull + protected Constants.BackupType getBackupType() { + return Constants.BackupType.OPEN_PGP; + } + + @Override + protected boolean doBackup() { + return StorageAccessHelper.saveFile(applicationContext, uri, payload); + } +} \ No newline at end of file diff --git a/app/src/main/java/org/shadowice/flocke/andotp/Tasks/PlainTextBackupTask.java b/app/src/main/java/org/shadowice/flocke/andotp/Tasks/PlainTextBackupTask.java new file mode 100644 index 00000000..c4cab579 --- /dev/null +++ b/app/src/main/java/org/shadowice/flocke/andotp/Tasks/PlainTextBackupTask.java @@ -0,0 +1,35 @@ +package org.shadowice.flocke.andotp.Tasks; + +import android.content.Context; +import android.net.Uri; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import org.shadowice.flocke.andotp.Database.Entry; +import org.shadowice.flocke.andotp.Utilities.Constants; +import org.shadowice.flocke.andotp.Utilities.DatabaseHelper; +import org.shadowice.flocke.andotp.Utilities.StorageAccessHelper; + +import java.util.ArrayList; + +public class PlainTextBackupTask extends GenericBackupTask { + private final ArrayList entries; + + public PlainTextBackupTask(Context context, ArrayList entries, @Nullable Uri uri) { + super(context, uri); + this.entries = entries; + } + + @Override + @NonNull + protected Constants.BackupType getBackupType() { + return Constants.BackupType.PLAIN_TEXT; + } + + @Override + protected boolean doBackup() { + String payload = DatabaseHelper.entriesToString(entries); + return StorageAccessHelper.saveFile(applicationContext, uri, payload); + } +} \ No newline at end of file diff --git a/app/src/main/java/org/shadowice/flocke/andotp/Utilities/BackupHelper.java b/app/src/main/java/org/shadowice/flocke/andotp/Utilities/BackupHelper.java index f1839ee9..f6377303 100644 --- a/app/src/main/java/org/shadowice/flocke/andotp/Utilities/BackupHelper.java +++ b/app/src/main/java/org/shadowice/flocke/andotp/Utilities/BackupHelper.java @@ -7,13 +7,10 @@ import androidx.documentfile.provider.DocumentFile; import org.shadowice.flocke.andotp.Database.Entry; import org.shadowice.flocke.andotp.R; -import org.shadowice.flocke.andotp.Tasks.BackupTask; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.ArrayList; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import javax.crypto.SecretKey; @@ -104,22 +101,6 @@ public class BackupHelper { return Constants.BackupType.UNAVAILABLE; } - public static void backupToFileAsync(Context context, Uri uri, String password, SecretKey encryptionKey, BackupTask.BackupCallback callback, boolean silent) { - ArrayList entries = DatabaseHelper.loadDatabase(context, encryptionKey); - - ExecutorService executor = Executors.newSingleThreadExecutor(); - - BackupTask backupTask = new BackupTask(context, Constants.BackupType.ENCRYPTED, DatabaseHelper.entriesToString(entries), callback); - - if (uri != null) - backupTask.setUri(uri); - - backupTask.setPassword(password); - backupTask.setSilent(silent); - - executor.execute(backupTask); - } - public static boolean backupToFile(Context context, Uri uri, String password, SecretKey encryptionKey) { ArrayList entries = DatabaseHelper.loadDatabase(context, encryptionKey); String plain = DatabaseHelper.entriesToString(entries);