From 1fcc1889ecfe46a945e4b4bff04b46078376114f Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 17 Jul 2018 14:13:03 +0200 Subject: [PATCH] Use CancellationSignal for cancellation in UI code --- .../keychain/service/KeychainServiceTask.java | 160 ++++++++++-------- .../service/ProgressDialogManager.java | 15 +- .../ui/base/CryptoOperationHelper.java | 39 ++--- .../ui/dialog/ProgressDialogFragment.java | 26 +-- 4 files changed, 118 insertions(+), 122 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainServiceTask.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainServiceTask.java index 29e294ba7..305a566a1 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainServiceTask.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainServiceTask.java @@ -24,6 +24,7 @@ import android.annotation.SuppressLint; import android.content.Context; import android.os.AsyncTask; import android.os.Parcelable; +import android.support.v4.os.CancellationSignal; import org.sufficientlysecure.keychain.daos.KeyWritableRepository; import org.sufficientlysecure.keychain.operations.BackupOperation; @@ -64,90 +65,101 @@ public class KeychainServiceTask { private final KeyWritableRepository keyRepository; @SuppressLint("StaticFieldLeak") - public void startOperationInBackground( + public CancellationSignal startOperationInBackground( Parcelable inputParcel, CryptoInputParcel cryptoInput, OperationCallback operationCallback) { - new AsyncTask() { - private AtomicBoolean operationCancelledBoolean = new AtomicBoolean(false); + AtomicBoolean operationCancelledBoolean = new AtomicBoolean(false); - @Override - protected OperationResult doInBackground(Void... voids) { - BaseOperation op; + AsyncTask asyncTask = + new AsyncTask() { + @Override + protected OperationResult doInBackground(Void... voids) { + BaseOperation op; - if (inputParcel instanceof SignEncryptParcel) { - op = new SignEncryptOperation(context, keyRepository, asyncProgressable, operationCancelledBoolean); - } else if (inputParcel instanceof PgpDecryptVerifyInputParcel) { - op = new PgpDecryptVerifyOperation(context, keyRepository, asyncProgressable); - } else if (inputParcel instanceof SaveKeyringParcel) { - op = new EditKeyOperation(context, keyRepository, asyncProgressable, operationCancelledBoolean); - } else if (inputParcel instanceof ChangeUnlockParcel) { - op = new ChangeUnlockOperation(context, keyRepository, asyncProgressable); - } else if (inputParcel instanceof RevokeKeyringParcel) { - op = new RevokeOperation(context, keyRepository, asyncProgressable); - } else if (inputParcel instanceof CertifyActionsParcel) { - op = new CertifyOperation(context, keyRepository, asyncProgressable, operationCancelledBoolean); - } else if (inputParcel instanceof DeleteKeyringParcel) { - op = new DeleteOperation(context, keyRepository, asyncProgressable); - } else if (inputParcel instanceof PromoteKeyringParcel) { - op = new PromoteKeyOperation(context, keyRepository, asyncProgressable, operationCancelledBoolean); - } else if (inputParcel instanceof ImportKeyringParcel) { - op = new ImportOperation(context, keyRepository, asyncProgressable, operationCancelledBoolean); - } else if (inputParcel instanceof BackupKeyringParcel) { - op = new BackupOperation(context, keyRepository, asyncProgressable, operationCancelledBoolean); - } else if (inputParcel instanceof UploadKeyringParcel) { - op = new UploadOperation(context, keyRepository, asyncProgressable, operationCancelledBoolean); - } else if (inputParcel instanceof KeybaseVerificationParcel) { - op = new KeybaseVerificationOperation(context, keyRepository, asyncProgressable); - } else if (inputParcel instanceof InputDataParcel) { - op = new InputDataOperation(context, keyRepository, asyncProgressable); - } else if (inputParcel instanceof BenchmarkInputParcel) { - op = new BenchmarkOperation(context, keyRepository, asyncProgressable); - } else if (inputParcel instanceof KeySyncParcel) { - op = new KeySyncOperation(context, keyRepository, asyncProgressable, operationCancelledBoolean); - } else { - throw new AssertionError("Unrecognized input parcel in KeychainService!"); - } + if (inputParcel instanceof SignEncryptParcel) { + op = new SignEncryptOperation(context, keyRepository, asyncProgressable, + operationCancelledBoolean); + } else if (inputParcel instanceof PgpDecryptVerifyInputParcel) { + op = new PgpDecryptVerifyOperation(context, keyRepository, asyncProgressable); + } else if (inputParcel instanceof SaveKeyringParcel) { + op = new EditKeyOperation(context, keyRepository, asyncProgressable, + operationCancelledBoolean); + } else if (inputParcel instanceof ChangeUnlockParcel) { + op = new ChangeUnlockOperation(context, keyRepository, asyncProgressable); + } else if (inputParcel instanceof RevokeKeyringParcel) { + op = new RevokeOperation(context, keyRepository, asyncProgressable); + } else if (inputParcel instanceof CertifyActionsParcel) { + op = new CertifyOperation(context, keyRepository, asyncProgressable, + operationCancelledBoolean); + } else if (inputParcel instanceof DeleteKeyringParcel) { + op = new DeleteOperation(context, keyRepository, asyncProgressable); + } else if (inputParcel instanceof PromoteKeyringParcel) { + op = new PromoteKeyOperation(context, keyRepository, asyncProgressable, + operationCancelledBoolean); + } else if (inputParcel instanceof ImportKeyringParcel) { + op = new ImportOperation(context, keyRepository, asyncProgressable, + operationCancelledBoolean); + } else if (inputParcel instanceof BackupKeyringParcel) { + op = new BackupOperation(context, keyRepository, asyncProgressable, + operationCancelledBoolean); + } else if (inputParcel instanceof UploadKeyringParcel) { + op = new UploadOperation(context, keyRepository, asyncProgressable, + operationCancelledBoolean); + } else if (inputParcel instanceof KeybaseVerificationParcel) { + op = new KeybaseVerificationOperation(context, keyRepository, asyncProgressable); + } else if (inputParcel instanceof InputDataParcel) { + op = new InputDataOperation(context, keyRepository, asyncProgressable); + } else if (inputParcel instanceof BenchmarkInputParcel) { + op = new BenchmarkOperation(context, keyRepository, asyncProgressable); + } else if (inputParcel instanceof KeySyncParcel) { + op = new KeySyncOperation(context, keyRepository, asyncProgressable, + operationCancelledBoolean); + } else { + throw new AssertionError("Unrecognized input parcel in KeychainService!"); + } - if (isCancelled()) { - return null; - } + if (isCancelled()) { + return null; + } - // noinspection unchecked, we make sure it's the correct op above - return op.execute(inputParcel, cryptoInput); - } + // noinspection unchecked, we make sure it's the correct op above + return op.execute(inputParcel, cryptoInput); + } - Progressable asyncProgressable = new Progressable() { - @Override - public void setPreventCancel() { - publishProgress((ProgressUpdate) null); - } + Progressable asyncProgressable = new Progressable() { + @Override + public void setPreventCancel() { + publishProgress((ProgressUpdate) null); + } - @Override - public void setProgress(Integer resourceId, int current, int total) { - publishProgress(new ProgressUpdate(resourceId, current, total)); - } - }; + @Override + public void setProgress(Integer resourceId, int current, int total) { + publishProgress(new ProgressUpdate(resourceId, current, total)); + } + }; - @Override - protected void onProgressUpdate(ProgressUpdate... values) { - ProgressUpdate progressUpdate = values[0]; - if (progressUpdate == null) { - operationCallback.setPreventCancel(); - } else { - operationCallback.setProgress(progressUpdate.resourceId, progressUpdate.current, progressUpdate.total); - } - } + @Override + protected void onProgressUpdate(ProgressUpdate... values) { + ProgressUpdate progressUpdate = values[0]; + if (progressUpdate == null) { + operationCallback.setPreventCancel(); + } else { + operationCallback.setProgress(progressUpdate.resourceId, progressUpdate.current, + progressUpdate.total); + } + } - @Override - protected void onCancelled() { - super.onCancelled(); - operationCancelledBoolean.set(true); - } + @Override + protected void onPostExecute(OperationResult result) { + operationCallback.operationFinished(result); + } + }; + asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - @Override - protected void onPostExecute(OperationResult result) { - operationCallback.operationFinished(result); - } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + CancellationSignal cancellationSignal = new CancellationSignal(); + cancellationSignal.setOnCancelListener(() -> { + operationCancelledBoolean.set(true); + }); + return cancellationSignal; } public interface OperationCallback { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ProgressDialogManager.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ProgressDialogManager.java index 960a60552..d5086a4ba 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ProgressDialogManager.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ProgressDialogManager.java @@ -22,6 +22,7 @@ import android.app.ProgressDialog; import android.os.Handler; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; +import android.support.v4.os.CancellationSignal; import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment; @@ -36,16 +37,16 @@ public class ProgressDialogManager { } public void showProgressDialog() { - showProgressDialog("", ProgressDialog.STYLE_SPINNER, false); + showProgressDialog("", ProgressDialog.STYLE_SPINNER, null); } public void showProgressDialog( - String progressDialogMessage, int progressDialogStyle, boolean cancelable) { + String progressDialogMessage, int progressDialogStyle, CancellationSignal cancellationSignal) { final ProgressDialogFragment frag = ProgressDialogFragment.newInstance( - progressDialogMessage, - progressDialogStyle, - cancelable); + progressDialogMessage, progressDialogStyle, cancellationSignal != null); + + frag.setCancellationSignal(cancellationSignal); // TODO: This is a hack!, see // http://stackoverflow.com/questions/10114324/show-dialogfragment-from-onactivityresult @@ -79,9 +80,7 @@ public class ProgressDialogManager { progressDialogFragment.dismissAllowingStateLoss(); } - public void onSetProgress(Integer resourceInt, int progress, int max) { - ProgressDialogFragment progressDialogFragment = (ProgressDialogFragment) activity.getSupportFragmentManager() .findFragmentByTag(TAG_PROGRESS_DIALOG); @@ -95,7 +94,5 @@ public class ProgressDialogManager { } else { progressDialogFragment.setProgress(progress, max); } - } - } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java index 088862422..d5dc19234 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java @@ -29,7 +29,7 @@ import android.os.SystemClock; import android.support.annotation.UiThread; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; -import android.support.v4.app.FragmentManager; +import android.support.v4.os.CancellationSignal; import org.sufficientlysecure.keychain.operations.results.InputPendingResult; import org.sufficientlysecure.keychain.operations.results.OperationResult; @@ -42,7 +42,6 @@ import org.sufficientlysecure.keychain.ui.OrbotRequiredDialogActivity; import org.sufficientlysecure.keychain.ui.PassphraseDialogActivity; import org.sufficientlysecure.keychain.ui.RetryUploadDialogActivity; import org.sufficientlysecure.keychain.ui.SecurityTokenOperationActivity; -import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment; import timber.log.Timber; @@ -264,28 +263,6 @@ public class CryptoOperationHelper