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); } @@ -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 f757eb6dd..a5cc4602d 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; @@ -87,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); @@ -100,7 +95,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. - */ - -package org.sufficientlysecure.keychain.service; - - -import android.app.Service; -import android.content.Intent; -import android.os.Bundle; -import android.os.IBinder; -import android.os.Message; -import android.os.Messenger; -import android.os.Parcelable; -import android.os.RemoteException; -import android.support.v4.os.CancellationSignal; - -import org.sufficientlysecure.keychain.operations.KeySyncOperation; -import org.sufficientlysecure.keychain.operations.KeySyncParcel; -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.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.daos.KeyWritableRepository; -import org.sufficientlysecure.keychain.service.ServiceProgressHandler.MessageStatus; -import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; -import timber.log.Timber; - - -/** - * This Service contains all important long lasting operations for OpenKeychain. It receives Intents with - * data from the activities or other apps, executes them, and stops itself after doing them. - */ -public class KeychainService extends Service implements Progressable { - - // messenger for communication (hack) - public static final String EXTRA_MESSENGER = "messenger"; - - // extras for operation - public static final String EXTRA_OPERATION_INPUT = "op_input"; - public static final String EXTRA_CRYPTO_INPUT = "crypto_input"; - - public static final String ACTION_CANCEL = "action_cancel"; - - // this attribute can possibly merged with the one above? not sure... - private CancellationSignal mActionCanceled; - - ThreadLocal mMessenger = new ThreadLocal<>(); - - @Override - public IBinder onBind(Intent intent) { - return null; - } - - /** - * 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(); - } - 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); - - } - }; - - Thread actionThread = new Thread(actionRunnable); - actionThread.start(); - - return START_NOT_STICKY; - } - - 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!"); - } - } - - private void sendMessageToHandler(MessageStatus status, OperationResult data) { - Bundle bundle = new Bundle(); - bundle.putParcelable(OperationResult.EXTRA_RESULT, data); - sendMessageToHandler(status, null, bundle); - } - - 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/service/KeychainServiceTask.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainServiceTask.java new file mode 100644 index 000000000..305a566a1 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainServiceTask.java @@ -0,0 +1,183 @@ +/* + * 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 android.support.v4.os.CancellationSignal; + +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 CancellationSignal startOperationInBackground( + Parcelable inputParcel, CryptoInputParcel cryptoInput, OperationCallback operationCallback) { + AtomicBoolean operationCancelledBoolean = new AtomicBoolean(false); + + 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 (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 onPostExecute(OperationResult result) { + operationCallback.operationFinished(result); + } + }; + asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + + CancellationSignal cancellationSignal = new CancellationSignal(); + cancellationSignal.setOnCancelListener(() -> { + operationCancelledBoolean.set(true); + }); + return cancellationSignal; + } + + 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..d5086a4ba --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ProgressDialogManager.java @@ -0,0 +1,98 @@ +/* + * 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 android.support.v4.os.CancellationSignal; + +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, null); + } + + public void showProgressDialog( + String progressDialogMessage, int progressDialogStyle, CancellationSignal cancellationSignal) { + + final ProgressDialogFragment frag = ProgressDialogFragment.newInstance( + progressDialogMessage, progressDialogStyle, cancellationSignal != null); + + frag.setCancellationSignal(cancellationSignal); + + // 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/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..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 @@ -17,32 +17,31 @@ package org.sufficientlysecure.keychain.ui.base; + 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.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; -import org.sufficientlysecure.keychain.service.KeychainService; -import org.sufficientlysecure.keychain.service.ServiceProgressHandler; +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.SecurityTokenOperationActivity; import org.sufficientlysecure.keychain.ui.OrbotRequiredDialogActivity; import org.sufficientlysecure.keychain.ui.PassphraseDialogActivity; import org.sufficientlysecure.keychain.ui.RetryUploadDialogActivity; -import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment; +import org.sufficientlysecure.keychain.ui.SecurityTokenOperationActivity; import timber.log.Timber; @@ -91,12 +90,12 @@ 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) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java index 5d48b7b09..3132dce00 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java @@ -17,16 +17,17 @@ package org.sufficientlysecure.keychain.ui.dialog; + import android.app.Activity; import android.app.Dialog; import android.app.ProgressDialog; import android.content.DialogInterface; import android.content.DialogInterface.OnKeyListener; -import android.content.Intent; import android.graphics.Color; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v4.app.DialogFragment; +import android.support.v4.os.CancellationSignal; import android.view.ContextThemeWrapper; import android.view.KeyEvent; import android.view.View; @@ -34,7 +35,6 @@ import android.view.View.OnClickListener; import android.widget.Button; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.service.KeychainService; import org.sufficientlysecure.keychain.ui.util.ThemeChanger; /** @@ -44,15 +44,18 @@ public class ProgressDialogFragment extends DialogFragment { private static final String ARG_MESSAGE = "message"; private static final String ARG_STYLE = "style"; private static final String ARG_CANCELABLE = "cancelable"; - private static final String ARG_SERVICE_TYPE = "service_class"; boolean mCanCancel = false, mPreventCancel = false, mIsCancelled = false; + private CancellationSignal cancellationSignal; /** * creates a new instance of this fragment - * @param message the message to be displayed initially above the progress bar - * @param style the progress bar style, as defined in ProgressDialog (horizontal or spinner) - * @param cancelable should we let the user cancel this operation + * + * @param message + * the message to be displayed initially above the progress bar + * @param style + * the progress bar style, as defined in ProgressDialog (horizontal or spinner) + * * @return */ public static ProgressDialogFragment newInstance(String message, int style, boolean cancelable) { @@ -141,20 +144,24 @@ public class ProgressDialogFragment extends DialogFragment { return dialog; } - public void setPreventCancel(boolean preventCancel) { + public void setPreventCancel() { // Don't care if we can't cancel anymore either way! if (mIsCancelled || ! mCanCancel) { return; } - mPreventCancel = preventCancel; + mPreventCancel = true; ProgressDialog dialog = (ProgressDialog) getDialog(); if (dialog == null) { return; } final Button negative = dialog.getButton(DialogInterface.BUTTON_NEGATIVE); - negative.setEnabled(mIsCancelled && !preventCancel); + negative.setEnabled(false); + } + + public void setCancellationSignal(CancellationSignal cancellationSignal) { + this.cancellationSignal = cancellationSignal; } @Override @@ -167,7 +174,7 @@ public class ProgressDialogFragment extends DialogFragment { @Override public void onClick(View v) { // nvm if we are already cancelled, or weren't able to begin with - if (mIsCancelled || ! mCanCancel) { + if (mIsCancelled || !mCanCancel || cancellationSignal == null) { return; } @@ -176,13 +183,7 @@ public class ProgressDialogFragment extends DialogFragment { negative.setClickable(false); negative.setTextColor(Color.GRAY); - // send a cancel message. note that this message will be handled by - // KeychainService.onStartCommand, which runs in this thread, - // not the service one, and will not queue up a command. - Intent serviceIntent = new Intent(getActivity(), KeychainService.class); - - serviceIntent.setAction(KeychainService.ACTION_CANCEL); - getActivity().startService(serviceIntent); + cancellationSignal.cancel(); // Set the progress bar accordingly ProgressDialog dialog = (ProgressDialog) getDialog(); @@ -192,11 +193,8 @@ public class ProgressDialogFragment extends DialogFragment { dialog.setIndeterminate(true); dialog.setMessage(getString(R.string.progress_cancelling)); - - } }); } - } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ProgressScaler.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ProgressScaler.java index cc20cc0de..48908b1dc 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ProgressScaler.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ProgressScaler.java @@ -39,27 +39,12 @@ public class ProgressScaler implements Progressable { this.mMax = max; } - /** - * Set progress of ProgressDialog by sending message to handler on UI thread - */ - public void setProgress(String message, int progress, int max) { - if (mWrapped != null) { - mWrapped.setProgress(message, mFrom + progress * (mTo - mFrom) / max, mMax); - } - } - - public void setProgress(int resourceId, int progress, int max) { + public void setProgress(Integer resourceId, int progress, int max) { if (mWrapped != null) { mWrapped.setProgress(resourceId, mFrom + progress * (mTo - mFrom) / max, mMax); } } - public void setProgress(int progress, int max) { - if (mWrapped != null) { - mWrapped.setProgress(mFrom + progress * (mTo - mFrom) / max, mMax); - } - } - @Override public void setPreventCancel() { if (mWrapped != null) { diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 6ff54cc39..5a7d2ac92 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -477,10 +477,8 @@ "changing PIN…" "changing Admin PIN…" - - "exporting key…" - "exporting keys…" - + "exporting key…" + "exporting keys…" "preparing operation…" "extracting signature key…"