From 2c8e219aa87e43fd8e1b0fde2e890043ea83f2d7 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 3 Jul 2018 22:59:30 +0200 Subject: [PATCH 1/4] use ThreadPool for background task execution --- OpenKeychain/src/main/AndroidManifest.xml | 3 - .../keychain/keysync/KeyserverSyncWorker.java | 7 +- .../keychain/operations/BackupOperation.java | 8 +- .../keychain/operations/BaseOperation.java | 11 +- .../operations/BaseReadWriteOperation.java | 7 +- .../keychain/operations/CertifyOperation.java | 12 +- .../keychain/operations/EditKeyOperation.java | 10 +- .../keychain/operations/ImportOperation.java | 8 +- .../keychain/operations/KeySyncOperation.java | 8 +- .../operations/PromoteKeyOperation.java | 8 +- .../operations/SignEncryptOperation.java | 6 +- .../keychain/operations/UploadOperation.java | 4 +- .../keychain/pgp/PgpKeyOperation.java | 9 +- .../keychain/pgp/PgpSignEncryptOperation.java | 10 +- .../keychain/service/KeychainService.java | 239 ++++++------------ .../ui/base/CryptoOperationFragment.java | 3 - .../ui/base/CryptoOperationHelper.java | 83 +++++- .../ui/dialog/ProgressDialogFragment.java | 9 +- 18 files changed, 203 insertions(+), 242 deletions(-) diff --git a/OpenKeychain/src/main/AndroidManifest.xml b/OpenKeychain/src/main/AndroidManifest.xml index 3be9e0aef..7c604611b 100644 --- a/OpenKeychain/src/main/AndroidManifest.xml +++ b/OpenKeychain/src/main/AndroidManifest.xml @@ -877,9 +877,6 @@ android:name=".remote.CryptoInputParcelCacheService" android:exported="false" android:process=":remote_api" /> - { } public BackupOperation(Context context, KeyRepository keyRepository, - Progressable progressable, CancellationSignal cancelled) { + Progressable progressable, AtomicBoolean cancelled) { super(context, keyRepository, progressable, cancelled); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BaseOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BaseOperation.java index f757eb6dd..693d6dd11 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BaseOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BaseOperation.java @@ -18,17 +18,18 @@ package org.sufficientlysecure.keychain.operations; +import java.util.concurrent.atomic.AtomicBoolean; + import android.content.Context; import android.os.Parcelable; import android.support.annotation.NonNull; import android.support.annotation.StringRes; -import android.support.v4.os.CancellationSignal; import org.sufficientlysecure.keychain.Constants.key; +import org.sufficientlysecure.keychain.daos.KeyRepository; import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.pgp.PassphraseCacheInterface; import org.sufficientlysecure.keychain.pgp.Progressable; -import org.sufficientlysecure.keychain.daos.KeyRepository; import org.sufficientlysecure.keychain.service.PassphraseCacheService; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.util.Passphrase; @@ -37,7 +38,7 @@ public abstract class BaseOperation implements PassphraseC final public Context mContext; final public Progressable mProgressable; - final public CancellationSignal mCancelled; + final public AtomicBoolean mCancelled; final public KeyRepository mKeyRepository; @@ -71,7 +72,7 @@ public abstract class BaseOperation implements PassphraseC } public BaseOperation(Context context, KeyRepository keyRepository, - Progressable progressable, CancellationSignal cancelled) { + Progressable progressable, AtomicBoolean cancelled) { mContext = context; mProgressable = progressable; mKeyRepository = keyRepository; @@ -100,7 +101,7 @@ public abstract class BaseOperation implements PassphraseC } protected boolean checkCancelled() { - return mCancelled != null && mCancelled.isCanceled(); + return mCancelled != null && mCancelled.get(); } protected void setPreventCancel () { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BaseReadWriteOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BaseReadWriteOperation.java index 43df20fb1..ec90c9158 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BaseReadWriteOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BaseReadWriteOperation.java @@ -18,12 +18,13 @@ package org.sufficientlysecure.keychain.operations; +import java.util.concurrent.atomic.AtomicBoolean; + import android.content.Context; import android.os.Parcelable; -import android.support.v4.os.CancellationSignal; -import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.daos.KeyWritableRepository; +import org.sufficientlysecure.keychain.pgp.Progressable; public abstract class BaseReadWriteOperation extends BaseOperation { protected final KeyWritableRepository mKeyWritableRepository; @@ -37,7 +38,7 @@ public abstract class BaseReadWriteOperation extends BaseO } protected BaseReadWriteOperation(Context context, KeyWritableRepository databaseInteractor, - Progressable progressable, CancellationSignal cancelled) { + Progressable progressable, AtomicBoolean cancelled) { super(context, databaseInteractor, progressable, cancelled); mKeyWritableRepository = databaseInteractor; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java index b9a657cd8..87eaccd8f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java @@ -19,11 +19,14 @@ package org.sufficientlysecure.keychain.operations; import java.util.ArrayList; +import java.util.concurrent.atomic.AtomicBoolean; import android.content.Context; import android.support.annotation.NonNull; -import android.support.v4.os.CancellationSignal; +import org.sufficientlysecure.keychain.daos.KeyMetadataDao; +import org.sufficientlysecure.keychain.daos.KeyRepository.NotFoundException; +import org.sufficientlysecure.keychain.daos.KeyWritableRepository; import org.sufficientlysecure.keychain.operations.results.CertifyResult; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; @@ -38,9 +41,6 @@ import org.sufficientlysecure.keychain.pgp.PgpCertifyOperation.PgpCertifyResult; import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; -import org.sufficientlysecure.keychain.daos.KeyMetadataDao; -import org.sufficientlysecure.keychain.daos.KeyRepository.NotFoundException; -import org.sufficientlysecure.keychain.daos.KeyWritableRepository; import org.sufficientlysecure.keychain.service.CertifyActionsParcel; import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyAction; import org.sufficientlysecure.keychain.service.ContactSyncAdapterService; @@ -63,8 +63,8 @@ import org.sufficientlysecure.keychain.util.Passphrase; public class CertifyOperation extends BaseReadWriteOperation { private final KeyMetadataDao keyMetadataDao; - public CertifyOperation(Context context, KeyWritableRepository keyWritableRepository, Progressable progressable, CancellationSignal - cancelled) { + public CertifyOperation(Context context, KeyWritableRepository keyWritableRepository, Progressable progressable, + AtomicBoolean cancelled) { super(context, keyWritableRepository, progressable, cancelled); this.keyMetadataDao = KeyMetadataDao.create(context); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java index f0d10c7b5..053ca87b0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java @@ -19,12 +19,15 @@ package org.sufficientlysecure.keychain.operations; import java.io.IOException; +import java.util.concurrent.atomic.AtomicBoolean; import android.content.Context; import android.support.annotation.NonNull; -import android.support.v4.os.CancellationSignal; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.daos.KeyMetadataDao; +import org.sufficientlysecure.keychain.daos.KeyRepository.NotFoundException; +import org.sufficientlysecure.keychain.daos.KeyWritableRepository; import org.sufficientlysecure.keychain.operations.results.EditKeyResult; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; @@ -35,9 +38,6 @@ import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing; import org.sufficientlysecure.keychain.pgp.PgpKeyOperation; import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; -import org.sufficientlysecure.keychain.daos.KeyMetadataDao; -import org.sufficientlysecure.keychain.daos.KeyRepository.NotFoundException; -import org.sufficientlysecure.keychain.daos.KeyWritableRepository; import org.sufficientlysecure.keychain.service.ContactSyncAdapterService; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.UploadKeyringParcel; @@ -61,7 +61,7 @@ public class EditKeyOperation extends BaseReadWriteOperation public EditKeyOperation(Context context, KeyWritableRepository databaseInteractor, - Progressable progressable, CancellationSignal cancelled) { + Progressable progressable, AtomicBoolean cancelled) { super(context, databaseInteractor, progressable, cancelled); this.keyMetadataDao = KeyMetadataDao.create(context); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportOperation.java index 189d596fd..452990673 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportOperation.java @@ -29,13 +29,15 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import android.content.Context; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.support.v4.os.CancellationSignal; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.daos.KeyMetadataDao; +import org.sufficientlysecure.keychain.daos.KeyWritableRepository; import org.sufficientlysecure.keychain.keyimport.FacebookKeyserverClient; import org.sufficientlysecure.keychain.keyimport.HkpKeyserverAddress; import org.sufficientlysecure.keychain.keyimport.HkpKeyserverClient; @@ -54,8 +56,6 @@ import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing; import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; -import org.sufficientlysecure.keychain.daos.KeyMetadataDao; -import org.sufficientlysecure.keychain.daos.KeyWritableRepository; import org.sufficientlysecure.keychain.service.ContactSyncAdapterService; import org.sufficientlysecure.keychain.service.ImportKeyringParcel; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; @@ -102,7 +102,7 @@ public class ImportOperation extends BaseReadWriteOperation } public ImportOperation(Context context, KeyWritableRepository databaseInteractor, - Progressable progressable, CancellationSignal cancelled) { + Progressable progressable, AtomicBoolean cancelled) { super(context, databaseInteractor, progressable, cancelled); this.keyMetadataDao = KeyMetadataDao.create(context); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeySyncOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeySyncOperation.java index ba4f5d79e..e97a31bf4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeySyncOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeySyncOperation.java @@ -5,18 +5,18 @@ import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import android.content.Context; import android.support.annotation.NonNull; -import android.support.v4.os.CancellationSignal; import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.daos.KeyMetadataDao; +import org.sufficientlysecure.keychain.daos.KeyWritableRepository; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.pgp.Progressable; -import org.sufficientlysecure.keychain.daos.KeyMetadataDao; -import org.sufficientlysecure.keychain.daos.KeyWritableRepository; import org.sufficientlysecure.keychain.service.ImportKeyringParcel; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; @@ -36,7 +36,7 @@ public class KeySyncOperation extends BaseReadWriteOperation { private final Preferences preferences; public KeySyncOperation(Context context, KeyWritableRepository databaseInteractor, - Progressable progressable, CancellationSignal cancellationSignal) { + Progressable progressable, AtomicBoolean cancellationSignal) { super(context, databaseInteractor, progressable, cancellationSignal); keyMetadataDao = KeyMetadataDao.create(context); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperation.java index fb4f350b2..b1126cf2f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperation.java @@ -20,12 +20,14 @@ package org.sufficientlysecure.keychain.operations; import java.util.Arrays; import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; import android.content.Context; import android.support.annotation.NonNull; -import android.support.v4.os.CancellationSignal; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.daos.KeyRepository.NotFoundException; +import org.sufficientlysecure.keychain.daos.KeyWritableRepository; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult; @@ -35,8 +37,6 @@ import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKey; import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing; import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; -import org.sufficientlysecure.keychain.daos.KeyRepository.NotFoundException; -import org.sufficientlysecure.keychain.daos.KeyWritableRepository; import org.sufficientlysecure.keychain.service.PromoteKeyringParcel; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; @@ -50,7 +50,7 @@ import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; */ public class PromoteKeyOperation extends BaseReadWriteOperation { public PromoteKeyOperation(Context context, KeyWritableRepository databaseInteractor, - Progressable progressable, CancellationSignal cancelled) { + Progressable progressable, AtomicBoolean cancelled) { super(context, databaseInteractor, progressable, cancelled); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java index 306003b6e..20bcd19e8 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java @@ -20,12 +20,13 @@ package org.sufficientlysecure.keychain.operations; import java.util.ArrayDeque; import java.util.ArrayList; +import java.util.concurrent.atomic.AtomicBoolean; import android.content.Context; import android.net.Uri; import android.support.annotation.NonNull; -import android.support.v4.os.CancellationSignal; +import org.sufficientlysecure.keychain.daos.KeyRepository; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult; @@ -34,7 +35,6 @@ import org.sufficientlysecure.keychain.pgp.PgpSignEncryptInputParcel; import org.sufficientlysecure.keychain.pgp.PgpSignEncryptOperation; import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.pgp.SignEncryptParcel; -import org.sufficientlysecure.keychain.daos.KeyRepository; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel.RequiredInputType; @@ -52,7 +52,7 @@ import org.sufficientlysecure.keychain.util.ProgressScaler; public class SignEncryptOperation extends BaseOperation { public SignEncryptOperation(Context context, KeyRepository keyRepository, - Progressable progressable, CancellationSignal cancelled) { + Progressable progressable, AtomicBoolean cancelled) { super(context, keyRepository, progressable, cancelled); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/UploadOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/UploadOperation.java index 221d7af64..f7c70e671 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/UploadOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/UploadOperation.java @@ -21,11 +21,11 @@ package org.sufficientlysecure.keychain.operations; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.Proxy; +import java.util.concurrent.atomic.AtomicBoolean; import android.content.Context; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.support.v4.os.CancellationSignal; import org.bouncycastle.bcpg.ArmoredOutputStream; import org.sufficientlysecure.keychain.R; @@ -60,7 +60,7 @@ public class UploadOperation extends BaseOperation { private KeyMetadataDao keyMetadataDao; public UploadOperation(Context context, KeyRepository keyRepository, - Progressable progressable, CancellationSignal cancelled) { + Progressable progressable, AtomicBoolean cancelled) { super(context, keyRepository, progressable, cancelled); keyMetadataDao = KeyMetadataDao.create(mContext); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index 8fd9867cf..47fdd57fa 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -33,8 +33,7 @@ import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Stack; - -import android.support.v4.os.CancellationSignal; +import java.util.concurrent.atomic.AtomicBoolean; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.nist.NISTNamedCurves; @@ -109,7 +108,7 @@ import timber.log.Timber; public class PgpKeyOperation { private Stack mProgress; - private CancellationSignal mCancelled; + private AtomicBoolean mCancelled; public PgpKeyOperation(Progressable progress) { super(); @@ -119,13 +118,13 @@ public class PgpKeyOperation { } } - public PgpKeyOperation(Progressable progress, CancellationSignal cancelled) { + public PgpKeyOperation(Progressable progress, AtomicBoolean cancelled) { this(progress); mCancelled = cancelled; } private boolean checkCancelled() { - return mCancelled != null && mCancelled.isCanceled(); + return mCancelled != null && mCancelled.get(); } private void subProgressPush(int from, int to) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java index 9d071fc4b..038cbf01a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java @@ -33,11 +33,11 @@ import java.security.SignatureException; import java.util.Collection; import java.util.Date; import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; import android.content.Context; import android.net.Uri; import android.support.annotation.NonNull; -import android.support.v4.os.CancellationSignal; import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.BCPGOutputStream; @@ -54,6 +54,9 @@ import org.bouncycastle.openpgp.operator.jcajce.NfcSyncPGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.jcajce.PGPUtil; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.daos.KeyRepository; +import org.sufficientlysecure.keychain.daos.KeyRepository.NotFoundException; +import org.sufficientlysecure.keychain.daos.KeyWritableRepository; import org.sufficientlysecure.keychain.operations.BaseOperation; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; @@ -63,9 +66,6 @@ import org.sufficientlysecure.keychain.pgp.PgpSecurityConstants.OpenKeychainComp import org.sufficientlysecure.keychain.pgp.PgpSecurityConstants.OpenKeychainHashAlgorithmTags; import org.sufficientlysecure.keychain.pgp.PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; -import org.sufficientlysecure.keychain.daos.KeyRepository; -import org.sufficientlysecure.keychain.daos.KeyRepository.NotFoundException; -import org.sufficientlysecure.keychain.daos.KeyWritableRepository; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; @@ -104,7 +104,7 @@ public class PgpSignEncryptOperation extends BaseOperation()); + this.keyRepository = KeyWritableRepository.create(context); + } - public static final String ACTION_CANCEL = "action_cancel"; + private final Context context; + private final ThreadPoolExecutor threadPoolExecutor; + private final KeyWritableRepository keyRepository; // this attribute can possibly merged with the one above? not sure... - private CancellationSignal mActionCanceled; + private AtomicBoolean operationCancelledBoolean = new AtomicBoolean(false); - ThreadLocal mMessenger = new ThreadLocal<>(); + public void startOperationInBackground(Parcelable inputParcel, CryptoInputParcel cryptoInput, + Progressable progressable, OperationCallback operationCallback) { + operationCancelledBoolean.set(false); - @Override - public IBinder onBind(Intent intent) { - return null; - } + Runnable actionRunnable = () -> { + BaseOperation op; - /** - * This is run on the main thread, we need to spawn a runnable which runs on another thread for the actual operation - */ - @Override - public int onStartCommand(final Intent intent, int flags, int startId) { - - if (intent.getAction() != null && intent.getAction().equals(ACTION_CANCEL)) { - if (mActionCanceled != null) { - mActionCanceled.cancel(); + if (inputParcel instanceof SignEncryptParcel) { + op = new SignEncryptOperation(context, keyRepository, progressable, operationCancelledBoolean); + } else if (inputParcel instanceof PgpDecryptVerifyInputParcel) { + op = new PgpDecryptVerifyOperation(context, keyRepository, progressable); + } else if (inputParcel instanceof SaveKeyringParcel) { + op = new EditKeyOperation(context, keyRepository, progressable, operationCancelledBoolean); + } else if (inputParcel instanceof ChangeUnlockParcel) { + op = new ChangeUnlockOperation(context, keyRepository, progressable); + } else if (inputParcel instanceof RevokeKeyringParcel) { + op = new RevokeOperation(context, keyRepository, progressable); + } else if (inputParcel instanceof CertifyActionsParcel) { + op = new CertifyOperation(context, keyRepository, progressable, operationCancelledBoolean); + } else if (inputParcel instanceof DeleteKeyringParcel) { + op = new DeleteOperation(context, keyRepository, progressable); + } else if (inputParcel instanceof PromoteKeyringParcel) { + op = new PromoteKeyOperation(context, keyRepository, progressable, operationCancelledBoolean); + } else if (inputParcel instanceof ImportKeyringParcel) { + op = new ImportOperation(context, keyRepository, progressable, operationCancelledBoolean); + } else if (inputParcel instanceof BackupKeyringParcel) { + op = new BackupOperation(context, keyRepository, progressable, operationCancelledBoolean); + } else if (inputParcel instanceof UploadKeyringParcel) { + op = new UploadOperation(context, keyRepository, progressable, operationCancelledBoolean); + } else if (inputParcel instanceof KeybaseVerificationParcel) { + op = new KeybaseVerificationOperation(context, keyRepository, progressable); + } else if (inputParcel instanceof InputDataParcel) { + op = new InputDataOperation(context, keyRepository, progressable); + } else if (inputParcel instanceof BenchmarkInputParcel) { + op = new BenchmarkOperation(context, keyRepository, progressable); + } else if (inputParcel instanceof KeySyncParcel) { + op = new KeySyncOperation(context, keyRepository, progressable, operationCancelledBoolean); + } else { + throw new AssertionError("Unrecognized input parcel in KeychainService!"); } - return START_NOT_STICKY; - } - mActionCanceled = new CancellationSignal(); - - Runnable actionRunnable = new Runnable() { - @Override - public void run() { - Bundle extras = intent.getExtras(); - - // Set messenger for communication (for this particular thread) - mMessenger.set(extras.getParcelable(EXTRA_MESSENGER)); - - // Input - Parcelable inputParcel = extras.getParcelable(EXTRA_OPERATION_INPUT); - CryptoInputParcel cryptoInput = extras.getParcelable(EXTRA_CRYPTO_INPUT); - - // Operation - BaseOperation op; - - // just for brevity - KeychainService outerThis = KeychainService.this; - KeyWritableRepository databaseInteractor = - KeyWritableRepository.create(outerThis); - if (inputParcel instanceof SignEncryptParcel) { - op = new SignEncryptOperation(outerThis, databaseInteractor, outerThis, mActionCanceled); - } else if (inputParcel instanceof PgpDecryptVerifyInputParcel) { - op = new PgpDecryptVerifyOperation(outerThis, databaseInteractor, outerThis); - } else if (inputParcel instanceof SaveKeyringParcel) { - op = new EditKeyOperation(outerThis, databaseInteractor, outerThis, mActionCanceled); - } else if (inputParcel instanceof ChangeUnlockParcel) { - op = new ChangeUnlockOperation(outerThis, databaseInteractor, outerThis); - } else if (inputParcel instanceof RevokeKeyringParcel) { - op = new RevokeOperation(outerThis, databaseInteractor, outerThis); - } else if (inputParcel instanceof CertifyActionsParcel) { - op = new CertifyOperation(outerThis, databaseInteractor, outerThis, mActionCanceled); - } else if (inputParcel instanceof DeleteKeyringParcel) { - op = new DeleteOperation(outerThis, databaseInteractor, outerThis); - } else if (inputParcel instanceof PromoteKeyringParcel) { - op = new PromoteKeyOperation(outerThis, databaseInteractor, outerThis, mActionCanceled); - } else if (inputParcel instanceof ImportKeyringParcel) { - op = new ImportOperation(outerThis, databaseInteractor, outerThis, mActionCanceled); - } else if (inputParcel instanceof BackupKeyringParcel) { - op = new BackupOperation(outerThis, databaseInteractor, outerThis, mActionCanceled); - } else if (inputParcel instanceof UploadKeyringParcel) { - op = new UploadOperation(outerThis, databaseInteractor, outerThis, mActionCanceled); - } else if (inputParcel instanceof KeybaseVerificationParcel) { - op = new KeybaseVerificationOperation(outerThis, databaseInteractor, outerThis); - } else if (inputParcel instanceof InputDataParcel) { - op = new InputDataOperation(outerThis, databaseInteractor, outerThis); - } else if (inputParcel instanceof BenchmarkInputParcel) { - op = new BenchmarkOperation(outerThis, databaseInteractor, outerThis); - } else if (inputParcel instanceof KeySyncParcel) { - op = new KeySyncOperation(outerThis, databaseInteractor, outerThis, mActionCanceled); - } else { - throw new AssertionError("Unrecognized input parcel in KeychainService!"); - } - - @SuppressWarnings("unchecked") // this is unchecked, we make sure it's the correct op above! - OperationResult result = op.execute(inputParcel, cryptoInput); - sendMessageToHandler(MessageStatus.OKAY, result); - - } + @SuppressWarnings("unchecked") // this is unchecked, we make sure it's the correct op above! + OperationResult result = op.execute(inputParcel, cryptoInput); + operationCallback.operationFinished(result); }; - Thread actionThread = new Thread(actionRunnable); - actionThread.start(); - - return START_NOT_STICKY; + threadPoolExecutor.execute(actionRunnable); } - private void sendMessageToHandler(MessageStatus status, Integer arg2, Bundle data) { - - Message msg = Message.obtain(); - assert msg != null; - msg.arg1 = status.ordinal(); - if (arg2 != null) { - msg.arg2 = arg2; - } - if (data != null) { - msg.setData(data); - } - - try { - mMessenger.get().send(msg); - } catch (RemoteException e) { - Timber.w(e, "Exception sending message, Is handler present?"); - } catch (NullPointerException e) { - Timber.w(e, "Messenger is null!"); + public void cancelRunningTask() { + if (operationCancelledBoolean != null) { + operationCancelledBoolean.set(true); } } - private void sendMessageToHandler(MessageStatus status, OperationResult data) { - Bundle bundle = new Bundle(); - bundle.putParcelable(OperationResult.EXTRA_RESULT, data); - sendMessageToHandler(status, null, bundle); + public interface OperationCallback { + void operationFinished(OperationResult data); } - - private void sendMessageToHandler(MessageStatus status) { - sendMessageToHandler(status, null, null); - } - - /** - * Set progress of ProgressDialog by sending message to handler on UI thread - */ - @Override - public void setProgress(String message, int progress, int max) { - Timber.d("Send message by setProgress with progress=" + progress + ", max=" - + max); - - Bundle data = new Bundle(); - if (message != null) { - data.putString(ServiceProgressHandler.DATA_MESSAGE, message); - } - data.putInt(ServiceProgressHandler.DATA_PROGRESS, progress); - data.putInt(ServiceProgressHandler.DATA_PROGRESS_MAX, max); - - sendMessageToHandler(MessageStatus.UPDATE_PROGRESS, null, data); - } - - @Override - public void setProgress(int resourceId, int progress, int max) { - setProgress(getString(resourceId), progress, max); - } - - @Override - public void setProgress(int progress, int max) { - setProgress(null, progress, max); - } - - @Override - public void setPreventCancel() { - sendMessageToHandler(MessageStatus.PREVENT_CANCEL); - } - } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java index 13b62752e..92aaeda39 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java @@ -29,7 +29,6 @@ import android.view.inputmethod.InputMethodManager; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.operations.results.OperationResult; -import org.sufficientlysecure.keychain.service.KeychainService; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; /** This is a base class for fragments which implement a cryptoOperation. @@ -47,8 +46,6 @@ import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; * must override at least onCryptoOperationSuccess to proceed after a * successful operation. * - * @see KeychainService - * */ public abstract class CryptoOperationFragment extends Fragment implements CryptoOperationHelper.Callback { 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 06dc54345..374dda3aa 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 @@ -17,6 +17,7 @@ package org.sufficientlysecure.keychain.ui.base; + import java.util.Date; import android.app.Activity; @@ -27,6 +28,7 @@ import android.os.Handler; import android.os.Message; import android.os.Messenger; import android.os.Parcelable; +import android.os.RemoteException; import android.os.SystemClock; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; @@ -34,14 +36,17 @@ import android.support.v4.app.FragmentManager; import org.sufficientlysecure.keychain.operations.results.InputPendingResult; import org.sufficientlysecure.keychain.operations.results.OperationResult; +import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.service.KeychainService; +import org.sufficientlysecure.keychain.service.KeychainService.OperationCallback; import org.sufficientlysecure.keychain.service.ServiceProgressHandler; +import org.sufficientlysecure.keychain.service.ServiceProgressHandler.MessageStatus; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; -import org.sufficientlysecure.keychain.ui.SecurityTokenOperationActivity; 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; @@ -295,12 +300,6 @@ public class CryptoOperationHelper Date: Tue, 17 Jul 2018 14:01:17 +0200 Subject: [PATCH 2/4] ditch ThreadPoolExecutor for AsyncTask --- .../keychain/keysync/KeyserverSyncWorker.java | 12 +- .../keychain/operations/BackupOperation.java | 3 +- .../keychain/operations/BaseOperation.java | 6 - .../keychain/pgp/Progressable.java | 10 +- .../keychain/remote/OpenPgpService.java | 12 +- .../keychain/service/KeychainService.java | 135 ------------ .../keychain/service/KeychainServiceTask.java | 171 +++++++++++++++ .../service/ProgressDialogManager.java | 101 +++++++++ .../service/ServiceProgressHandler.java | 195 ------------------ .../ui/base/CryptoOperationHelper.java | 144 +++---------- .../ui/dialog/ProgressDialogFragment.java | 13 +- .../keychain/util/ProgressScaler.java | 17 +- OpenKeychain/src/main/res/values/strings.xml | 6 +- 13 files changed, 321 insertions(+), 504 deletions(-) delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainServiceTask.java create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ProgressDialogManager.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ServiceProgressHandler.java diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keysync/KeyserverSyncWorker.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keysync/KeyserverSyncWorker.java index c4cbaed5d..2d9b2fdb8 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keysync/KeyserverSyncWorker.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keysync/KeyserverSyncWorker.java @@ -94,17 +94,7 @@ public class KeyserverSyncWorker extends Worker { return new Progressable() { @Override - public void setProgress(String message, int current, int total) { - setProgress(current, total); - } - - @Override - public void setProgress(int resourceId, int current, int total) { - setProgress(current, total); - } - - @Override - public void setProgress(int current, int total) { + public void setProgress(Integer ignored, int current, int total) { if (total == 0) { notificationManager.cancel(NotificationIds.KEYSERVER_SYNC); return; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BackupOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BackupOperation.java index c3d9f917d..f3c85fc0a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BackupOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BackupOperation.java @@ -222,8 +222,7 @@ public class BackupOperation extends BaseOperation { } int numKeys = unifiedKeyInfos.size(); - updateProgress(mContext.getResources().getQuantityString(R.plurals.progress_exporting_key, numKeys), - 0, numKeys); + updateProgress(numKeys == 1 ? R.string.progress_exporting_key : R.string.progress_exporting_key, 0, numKeys); // For each public masterKey id for (UnifiedKeyInfo keyInfo : unifiedKeyInfos) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BaseOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BaseOperation.java index 693d6dd11..a5cc4602d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BaseOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BaseOperation.java @@ -88,12 +88,6 @@ public abstract class BaseOperation implements PassphraseC } } - public void updateProgress(String message, int current, int total) { - if (mProgressable != null) { - mProgressable.setProgress(message, current, total); - } - } - public void updateProgress(int current, int total) { if (mProgressable != null) { mProgressable.setProgress(current, total); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/Progressable.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/Progressable.java index 4a5381bca..cdce4875c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/Progressable.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/Progressable.java @@ -18,11 +18,9 @@ package org.sufficientlysecure.keychain.pgp; public interface Progressable { - void setProgress(String message, int current, int total); - - void setProgress(int resourceId, int current, int total); - - void setProgress(int current, int total); - + void setProgress(Integer resourceId, int current, int total); + default void setProgress(int current, int total) { + setProgress(null, current, total); + } void setPreventCancel(); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index b173e65bc..39e405a7b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -1095,17 +1095,7 @@ public class OpenPgpService extends Service { return new Progressable() { boolean errorState = false; @Override - public void setProgress(String message, int current, int total) { - setProgress(current, total); - } - - @Override - public void setProgress(int resourceId, int current, int total) { - setProgress(current, total); - } - - @Override - public void setProgress(int current, int total) { + public void setProgress(Integer ignored, int current, int total) { if (errorState) { return; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java deleted file mode 100644 index 08416abb9..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (C) 2017 Schürmann & Breitmoser GbR - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.sufficientlysecure.keychain.service; - - -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; - -import android.content.Context; -import android.os.Parcelable; - -import org.sufficientlysecure.keychain.daos.KeyWritableRepository; -import org.sufficientlysecure.keychain.operations.BackupOperation; -import org.sufficientlysecure.keychain.operations.BaseOperation; -import org.sufficientlysecure.keychain.operations.BenchmarkOperation; -import org.sufficientlysecure.keychain.operations.CertifyOperation; -import org.sufficientlysecure.keychain.operations.ChangeUnlockOperation; -import org.sufficientlysecure.keychain.operations.DeleteOperation; -import org.sufficientlysecure.keychain.operations.EditKeyOperation; -import org.sufficientlysecure.keychain.operations.ImportOperation; -import org.sufficientlysecure.keychain.operations.InputDataOperation; -import org.sufficientlysecure.keychain.operations.KeySyncOperation; -import org.sufficientlysecure.keychain.operations.KeySyncParcel; -import org.sufficientlysecure.keychain.operations.KeybaseVerificationOperation; -import org.sufficientlysecure.keychain.operations.PromoteKeyOperation; -import org.sufficientlysecure.keychain.operations.RevokeOperation; -import org.sufficientlysecure.keychain.operations.SignEncryptOperation; -import org.sufficientlysecure.keychain.operations.UploadOperation; -import org.sufficientlysecure.keychain.operations.results.OperationResult; -import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel; -import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyOperation; -import org.sufficientlysecure.keychain.pgp.Progressable; -import org.sufficientlysecure.keychain.pgp.SignEncryptParcel; -import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; - - -public class KeychainService { - private static KeychainService keychainService; - - public static KeychainService getInstance(Context context) { - if (keychainService == null) { - keychainService = new KeychainService(context.getApplicationContext()); - } - return keychainService; - } - - private KeychainService(Context context) { - this.context = context; - this.threadPoolExecutor = new ThreadPoolExecutor(0, 4, 1000, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>()); - this.keyRepository = KeyWritableRepository.create(context); - } - - private final Context context; - private final ThreadPoolExecutor threadPoolExecutor; - private final KeyWritableRepository keyRepository; - - // this attribute can possibly merged with the one above? not sure... - private AtomicBoolean operationCancelledBoolean = new AtomicBoolean(false); - - public void startOperationInBackground(Parcelable inputParcel, CryptoInputParcel cryptoInput, - Progressable progressable, OperationCallback operationCallback) { - operationCancelledBoolean.set(false); - - Runnable actionRunnable = () -> { - BaseOperation op; - - if (inputParcel instanceof SignEncryptParcel) { - op = new SignEncryptOperation(context, keyRepository, progressable, operationCancelledBoolean); - } else if (inputParcel instanceof PgpDecryptVerifyInputParcel) { - op = new PgpDecryptVerifyOperation(context, keyRepository, progressable); - } else if (inputParcel instanceof SaveKeyringParcel) { - op = new EditKeyOperation(context, keyRepository, progressable, operationCancelledBoolean); - } else if (inputParcel instanceof ChangeUnlockParcel) { - op = new ChangeUnlockOperation(context, keyRepository, progressable); - } else if (inputParcel instanceof RevokeKeyringParcel) { - op = new RevokeOperation(context, keyRepository, progressable); - } else if (inputParcel instanceof CertifyActionsParcel) { - op = new CertifyOperation(context, keyRepository, progressable, operationCancelledBoolean); - } else if (inputParcel instanceof DeleteKeyringParcel) { - op = new DeleteOperation(context, keyRepository, progressable); - } else if (inputParcel instanceof PromoteKeyringParcel) { - op = new PromoteKeyOperation(context, keyRepository, progressable, operationCancelledBoolean); - } else if (inputParcel instanceof ImportKeyringParcel) { - op = new ImportOperation(context, keyRepository, progressable, operationCancelledBoolean); - } else if (inputParcel instanceof BackupKeyringParcel) { - op = new BackupOperation(context, keyRepository, progressable, operationCancelledBoolean); - } else if (inputParcel instanceof UploadKeyringParcel) { - op = new UploadOperation(context, keyRepository, progressable, operationCancelledBoolean); - } else if (inputParcel instanceof KeybaseVerificationParcel) { - op = new KeybaseVerificationOperation(context, keyRepository, progressable); - } else if (inputParcel instanceof InputDataParcel) { - op = new InputDataOperation(context, keyRepository, progressable); - } else if (inputParcel instanceof BenchmarkInputParcel) { - op = new BenchmarkOperation(context, keyRepository, progressable); - } else if (inputParcel instanceof KeySyncParcel) { - op = new KeySyncOperation(context, keyRepository, progressable, operationCancelledBoolean); - } else { - throw new AssertionError("Unrecognized input parcel in KeychainService!"); - } - - @SuppressWarnings("unchecked") // this is unchecked, we make sure it's the correct op above! - OperationResult result = op.execute(inputParcel, cryptoInput); - operationCallback.operationFinished(result); - }; - - threadPoolExecutor.execute(actionRunnable); - } - - public void cancelRunningTask() { - if (operationCancelledBoolean != null) { - operationCancelledBoolean.set(true); - } - } - - public interface OperationCallback { - void operationFinished(OperationResult data); - } -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainServiceTask.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainServiceTask.java new file mode 100644 index 000000000..29e294ba7 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainServiceTask.java @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2017 Schürmann & Breitmoser GbR + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.sufficientlysecure.keychain.service; + + +import java.util.concurrent.atomic.AtomicBoolean; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.os.AsyncTask; +import android.os.Parcelable; + +import org.sufficientlysecure.keychain.daos.KeyWritableRepository; +import org.sufficientlysecure.keychain.operations.BackupOperation; +import org.sufficientlysecure.keychain.operations.BaseOperation; +import org.sufficientlysecure.keychain.operations.BenchmarkOperation; +import org.sufficientlysecure.keychain.operations.CertifyOperation; +import org.sufficientlysecure.keychain.operations.ChangeUnlockOperation; +import org.sufficientlysecure.keychain.operations.DeleteOperation; +import org.sufficientlysecure.keychain.operations.EditKeyOperation; +import org.sufficientlysecure.keychain.operations.ImportOperation; +import org.sufficientlysecure.keychain.operations.InputDataOperation; +import org.sufficientlysecure.keychain.operations.KeySyncOperation; +import org.sufficientlysecure.keychain.operations.KeySyncParcel; +import org.sufficientlysecure.keychain.operations.KeybaseVerificationOperation; +import org.sufficientlysecure.keychain.operations.PromoteKeyOperation; +import org.sufficientlysecure.keychain.operations.RevokeOperation; +import org.sufficientlysecure.keychain.operations.SignEncryptOperation; +import org.sufficientlysecure.keychain.operations.UploadOperation; +import org.sufficientlysecure.keychain.operations.results.OperationResult; +import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel; +import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyOperation; +import org.sufficientlysecure.keychain.pgp.Progressable; +import org.sufficientlysecure.keychain.pgp.SignEncryptParcel; +import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; + + +public class KeychainServiceTask { + public static KeychainServiceTask create(Context context) { + return new KeychainServiceTask(context.getApplicationContext()); + } + + private KeychainServiceTask(Context context) { + this.context = context; + this.keyRepository = KeyWritableRepository.create(context); + } + + private final Context context; + private final KeyWritableRepository keyRepository; + + @SuppressLint("StaticFieldLeak") + public void startOperationInBackground( + Parcelable inputParcel, CryptoInputParcel cryptoInput, OperationCallback operationCallback) { + new AsyncTask() { + private AtomicBoolean operationCancelledBoolean = new AtomicBoolean(false); + + @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 (isCancelled()) { + return null; + } + + // 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); + } + + @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 onCancelled() { + super.onCancelled(); + operationCancelledBoolean.set(true); + } + + @Override + protected void onPostExecute(OperationResult result) { + operationCallback.operationFinished(result); + } + }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + + public interface OperationCallback { + void setProgress(Integer message, int current, int total); + void setPreventCancel(); + void operationFinished(OperationResult data); + } + + private static class ProgressUpdate { + public final Integer resourceId; + public final int current; + public final int total; + + ProgressUpdate(Integer resourceId, int current, int total) { + this.resourceId = resourceId; + this.current = current; + this.total = total; + } + } + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ProgressDialogManager.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ProgressDialogManager.java new file mode 100644 index 000000000..960a60552 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ProgressDialogManager.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2017 Schürmann & Breitmoser GbR + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.sufficientlysecure.keychain.service; + + +import android.app.ProgressDialog; +import android.os.Handler; +import android.support.v4.app.FragmentActivity; +import android.support.v4.app.FragmentManager; + +import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment; + + +public class ProgressDialogManager { + public static final String TAG_PROGRESS_DIALOG = "progressDialog"; + + private FragmentActivity activity; + + public ProgressDialogManager(FragmentActivity activity) { + this.activity = activity; + } + + public void showProgressDialog() { + showProgressDialog("", ProgressDialog.STYLE_SPINNER, false); + } + + public void showProgressDialog( + String progressDialogMessage, int progressDialogStyle, boolean cancelable) { + + final ProgressDialogFragment frag = ProgressDialogFragment.newInstance( + progressDialogMessage, + progressDialogStyle, + cancelable); + + // TODO: This is a hack!, see + // http://stackoverflow.com/questions/10114324/show-dialogfragment-from-onactivityresult + final FragmentManager manager = activity.getSupportFragmentManager(); + Handler handler = new Handler(); + handler.post(() -> frag.show(manager, TAG_PROGRESS_DIALOG)); + + } + + public void setPreventCancel() { + ProgressDialogFragment progressDialogFragment = + (ProgressDialogFragment) activity.getSupportFragmentManager() + .findFragmentByTag(TAG_PROGRESS_DIALOG); + + if (progressDialogFragment == null) { + return; + } + + progressDialogFragment.setPreventCancel(); + } + + public void dismissAllowingStateLoss() { + ProgressDialogFragment progressDialogFragment = + (ProgressDialogFragment) activity.getSupportFragmentManager() + .findFragmentByTag(TAG_PROGRESS_DIALOG); + + if (progressDialogFragment == null) { + return; + } + + progressDialogFragment.dismissAllowingStateLoss(); + } + + + public void onSetProgress(Integer resourceInt, int progress, int max) { + + ProgressDialogFragment progressDialogFragment = + (ProgressDialogFragment) activity.getSupportFragmentManager() + .findFragmentByTag(TAG_PROGRESS_DIALOG); + + if (progressDialogFragment == null) { + return; + } + + if (resourceInt != null) { + progressDialogFragment.setProgress(resourceInt, progress, max); + } else { + progressDialogFragment.setProgress(progress, max); + } + + } + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ServiceProgressHandler.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ServiceProgressHandler.java deleted file mode 100644 index 544d2e77c..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ServiceProgressHandler.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (C) 2017 Schürmann & Breitmoser GbR - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.sufficientlysecure.keychain.service; - - -import android.app.ProgressDialog; -import android.os.Bundle; -import android.os.Handler; -import android.os.Message; -import android.support.v4.app.FragmentActivity; -import android.support.v4.app.FragmentManager; - -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment; -import org.sufficientlysecure.keychain.ui.util.Notify; -import timber.log.Timber; - - -public class ServiceProgressHandler extends Handler { - - // possible messages sent from this service to handler on ui - public enum MessageStatus { - UNKNOWN, - OKAY, - EXCEPTION, - UPDATE_PROGRESS, - PREVENT_CANCEL; - - private static final MessageStatus[] values = values(); - - public static MessageStatus fromInt(int n) { - if (n < 0 || n >= values.length) { - return UNKNOWN; - } else { - return values[n]; - } - } - } - - // possible data keys for messages - public static final String DATA_ERROR = "error"; - public static final String DATA_PROGRESS = "progress"; - public static final String DATA_PROGRESS_MAX = "max"; - public static final String DATA_MESSAGE = "message"; - public static final String DATA_MESSAGE_ID = "message_id"; - - // keybase proof specific - public static final String KEYBASE_PROOF_URL = "keybase_proof_url"; - public static final String KEYBASE_PRESENCE_URL = "keybase_presence_url"; - public static final String KEYBASE_PRESENCE_LABEL = "keybase_presence_label"; - - public static final String TAG_PROGRESS_DIALOG = "progressDialog"; - - FragmentActivity mActivity; - - public ServiceProgressHandler(FragmentActivity activity) { - mActivity = activity; - } - - public void showProgressDialog() { - showProgressDialog("", ProgressDialog.STYLE_SPINNER, false); - } - - public void showProgressDialog( - String progressDialogMessage, int progressDialogStyle, boolean cancelable) { - - final ProgressDialogFragment frag = ProgressDialogFragment.newInstance( - progressDialogMessage, - progressDialogStyle, - cancelable); - - // TODO: This is a hack!, see - // http://stackoverflow.com/questions/10114324/show-dialogfragment-from-onactivityresult - final FragmentManager manager = mActivity.getSupportFragmentManager(); - Handler handler = new Handler(); - handler.post(new Runnable() { - public void run() { - frag.show(manager, TAG_PROGRESS_DIALOG); - } - }); - - } - - @Override - public void handleMessage(Message message) { - Bundle data = message.getData(); - - MessageStatus status = MessageStatus.fromInt(message.arg1); - switch (status) { - case OKAY: - dismissAllowingStateLoss(); - - break; - - case EXCEPTION: - dismissAllowingStateLoss(); - - // show error from service - if (data.containsKey(DATA_ERROR)) { - Notify.create(mActivity, - mActivity.getString(R.string.error_message, data.getString(DATA_ERROR)), - Notify.Style.ERROR).show(); - } - - break; - - case UPDATE_PROGRESS: - if (data.containsKey(DATA_PROGRESS) && data.containsKey(DATA_PROGRESS_MAX)) { - - String msg = null; - int progress = data.getInt(DATA_PROGRESS); - int max = data.getInt(DATA_PROGRESS_MAX); - - // update progress from service - if (data.containsKey(DATA_MESSAGE)) { - msg = data.getString(DATA_MESSAGE); - } else if (data.containsKey(DATA_MESSAGE_ID)) { - msg = mActivity.getString(data.getInt(DATA_MESSAGE_ID)); - } - - onSetProgress(msg, progress, max); - - } - - break; - - case PREVENT_CANCEL: - setPreventCancel(true); - break; - - default: - Timber.e("unknown handler message!"); - break; - } - } - - private void setPreventCancel(boolean preventCancel) { - ProgressDialogFragment progressDialogFragment = - (ProgressDialogFragment) mActivity.getSupportFragmentManager() - .findFragmentByTag("progressDialog"); - - if (progressDialogFragment == null) { - return; - } - - progressDialogFragment.setPreventCancel(preventCancel); - } - - protected void dismissAllowingStateLoss() { - ProgressDialogFragment progressDialogFragment = - (ProgressDialogFragment) mActivity.getSupportFragmentManager() - .findFragmentByTag("progressDialog"); - - if (progressDialogFragment == null) { - return; - } - - progressDialogFragment.dismissAllowingStateLoss(); - } - - - protected void onSetProgress(String msg, int progress, int max) { - - ProgressDialogFragment progressDialogFragment = - (ProgressDialogFragment) mActivity.getSupportFragmentManager() - .findFragmentByTag("progressDialog"); - - if (progressDialogFragment == null) { - return; - } - - if (msg != null) { - progressDialogFragment.setProgress(msg, progress, max); - } 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 374dda3aa..088862422 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 @@ -23,24 +23,19 @@ import java.util.Date; import android.app.Activity; import android.app.ProgressDialog; import android.content.Intent; -import android.os.Bundle; import android.os.Handler; -import android.os.Message; -import android.os.Messenger; import android.os.Parcelable; -import android.os.RemoteException; 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 org.sufficientlysecure.keychain.operations.results.InputPendingResult; import org.sufficientlysecure.keychain.operations.results.OperationResult; -import org.sufficientlysecure.keychain.pgp.Progressable; -import org.sufficientlysecure.keychain.service.KeychainService; -import org.sufficientlysecure.keychain.service.KeychainService.OperationCallback; -import org.sufficientlysecure.keychain.service.ServiceProgressHandler; -import org.sufficientlysecure.keychain.service.ServiceProgressHandler.MessageStatus; +import org.sufficientlysecure.keychain.service.KeychainServiceTask; +import org.sufficientlysecure.keychain.service.KeychainServiceTask.OperationCallback; +import org.sufficientlysecure.keychain.service.ProgressDialogManager; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.ui.OrbotRequiredDialogActivity; @@ -281,7 +276,7 @@ public class CryptoOperationHelper minimumOperationDelay) { returnResultToCallback(result); return; } - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - returnResultToCallback(result); - } - }, minimumOperationDelay - elapsedTime); + long artificialDelay = minimumOperationDelay - elapsedTime; + new Handler().postDelayed(() -> returnResultToCallback(result), artificialDelay); } private void returnResultToCallback(OperationResult result) { @@ -421,37 +376,4 @@ public class CryptoOperationHelper"changing PIN…" "changing Admin PIN…" - - "exporting key…" - "exporting keys…" - + "exporting key…" + "exporting keys…" "preparing operation…" "extracting signature key…" From 1fcc1889ecfe46a945e4b4bff04b46078376114f Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 17 Jul 2018 14:13:03 +0200 Subject: [PATCH 3/4] 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 Date: Tue, 17 Jul 2018 14:24:51 +0200 Subject: [PATCH 4/4] clean up warnings in CryptoOperationHelper --- .../ui/base/CryptoOperationHelper.java | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) 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 d5dc19234..16737121a 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 @@ -90,12 +90,12 @@ public class CryptoOperationHelper