use ThreadPool for background task execution

This commit is contained in:
Vincent Breitmoser
2018-07-03 22:59:30 +02:00
parent 6ed110f1ee
commit 2c8e219aa8
18 changed files with 203 additions and 242 deletions

View File

@@ -877,9 +877,6 @@
android:name=".remote.CryptoInputParcelCacheService" android:name=".remote.CryptoInputParcelCacheService"
android:exported="false" android:exported="false"
android:process=":remote_api" /> android:process=":remote_api" />
<service
android:name=".service.KeychainService"
android:exported="false" />
<provider <provider
android:name=".provider.KeychainProvider" android:name=".provider.KeychainProvider"

View File

@@ -1,12 +1,13 @@
package org.sufficientlysecure.keychain.keysync; package org.sufficientlysecure.keychain.keysync;
import java.util.concurrent.atomic.AtomicBoolean;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.content.Context; import android.content.Context;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.v4.app.NotificationCompat; import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationCompat.Builder; import android.support.v4.app.NotificationCompat.Builder;
import android.support.v4.os.CancellationSignal;
import androidx.work.Worker; import androidx.work.Worker;
import org.sufficientlysecure.keychain.Constants.NotificationIds; import org.sufficientlysecure.keychain.Constants.NotificationIds;
@@ -25,7 +26,7 @@ import timber.log.Timber;
public class KeyserverSyncWorker extends Worker { public class KeyserverSyncWorker extends Worker {
private CancellationSignal cancellationSignal = new CancellationSignal(); private AtomicBoolean cancellationSignal = new AtomicBoolean(false);
@NonNull @NonNull
@Override @Override
@@ -128,6 +129,6 @@ public class KeyserverSyncWorker extends Worker {
@Override @Override
public void onStopped() { public void onStopped() {
super.onStopped(); super.onStopped();
cancellationSignal.cancel(); cancellationSignal.set(true);
} }
} }

View File

@@ -27,17 +27,19 @@ import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import android.content.Context; import android.content.Context;
import android.net.Uri; import android.net.Uri;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v4.os.CancellationSignal;
import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.daos.KeyRepository;
import org.sufficientlysecure.keychain.daos.KeyRepository.NotFoundException;
import org.sufficientlysecure.keychain.model.SubKey.UnifiedKeyInfo; import org.sufficientlysecure.keychain.model.SubKey.UnifiedKeyInfo;
import org.sufficientlysecure.keychain.operations.results.ExportResult; import org.sufficientlysecure.keychain.operations.results.ExportResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
@@ -50,8 +52,6 @@ import org.sufficientlysecure.keychain.pgp.PgpSignEncryptOperation;
import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.pgp.Progressable;
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.daos.KeyRepository;
import org.sufficientlysecure.keychain.daos.KeyRepository.NotFoundException;
import org.sufficientlysecure.keychain.provider.TemporaryFileProvider; import org.sufficientlysecure.keychain.provider.TemporaryFileProvider;
import org.sufficientlysecure.keychain.service.BackupKeyringParcel; import org.sufficientlysecure.keychain.service.BackupKeyringParcel;
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
@@ -83,7 +83,7 @@ public class BackupOperation extends BaseOperation<BackupKeyringParcel> {
} }
public BackupOperation(Context context, KeyRepository keyRepository, public BackupOperation(Context context, KeyRepository keyRepository,
Progressable progressable, CancellationSignal cancelled) { Progressable progressable, AtomicBoolean cancelled) {
super(context, keyRepository, progressable, cancelled); super(context, keyRepository, progressable, cancelled);
} }

View File

@@ -18,17 +18,18 @@
package org.sufficientlysecure.keychain.operations; package org.sufficientlysecure.keychain.operations;
import java.util.concurrent.atomic.AtomicBoolean;
import android.content.Context; import android.content.Context;
import android.os.Parcelable; import android.os.Parcelable;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.StringRes; import android.support.annotation.StringRes;
import android.support.v4.os.CancellationSignal;
import org.sufficientlysecure.keychain.Constants.key; import org.sufficientlysecure.keychain.Constants.key;
import org.sufficientlysecure.keychain.daos.KeyRepository;
import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.pgp.PassphraseCacheInterface; import org.sufficientlysecure.keychain.pgp.PassphraseCacheInterface;
import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.pgp.Progressable;
import org.sufficientlysecure.keychain.daos.KeyRepository;
import org.sufficientlysecure.keychain.service.PassphraseCacheService; import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
import org.sufficientlysecure.keychain.util.Passphrase; import org.sufficientlysecure.keychain.util.Passphrase;
@@ -37,7 +38,7 @@ public abstract class BaseOperation<T extends Parcelable> implements PassphraseC
final public Context mContext; final public Context mContext;
final public Progressable mProgressable; final public Progressable mProgressable;
final public CancellationSignal mCancelled; final public AtomicBoolean mCancelled;
final public KeyRepository mKeyRepository; final public KeyRepository mKeyRepository;
@@ -71,7 +72,7 @@ public abstract class BaseOperation<T extends Parcelable> implements PassphraseC
} }
public BaseOperation(Context context, KeyRepository keyRepository, public BaseOperation(Context context, KeyRepository keyRepository,
Progressable progressable, CancellationSignal cancelled) { Progressable progressable, AtomicBoolean cancelled) {
mContext = context; mContext = context;
mProgressable = progressable; mProgressable = progressable;
mKeyRepository = keyRepository; mKeyRepository = keyRepository;
@@ -100,7 +101,7 @@ public abstract class BaseOperation<T extends Parcelable> implements PassphraseC
} }
protected boolean checkCancelled() { protected boolean checkCancelled() {
return mCancelled != null && mCancelled.isCanceled(); return mCancelled != null && mCancelled.get();
} }
protected void setPreventCancel () { protected void setPreventCancel () {

View File

@@ -18,12 +18,13 @@
package org.sufficientlysecure.keychain.operations; package org.sufficientlysecure.keychain.operations;
import java.util.concurrent.atomic.AtomicBoolean;
import android.content.Context; import android.content.Context;
import android.os.Parcelable; 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.daos.KeyWritableRepository;
import org.sufficientlysecure.keychain.pgp.Progressable;
public abstract class BaseReadWriteOperation<T extends Parcelable> extends BaseOperation<T> { public abstract class BaseReadWriteOperation<T extends Parcelable> extends BaseOperation<T> {
protected final KeyWritableRepository mKeyWritableRepository; protected final KeyWritableRepository mKeyWritableRepository;
@@ -37,7 +38,7 @@ public abstract class BaseReadWriteOperation<T extends Parcelable> extends BaseO
} }
protected BaseReadWriteOperation(Context context, KeyWritableRepository databaseInteractor, protected BaseReadWriteOperation(Context context, KeyWritableRepository databaseInteractor,
Progressable progressable, CancellationSignal cancelled) { Progressable progressable, AtomicBoolean cancelled) {
super(context, databaseInteractor, progressable, cancelled); super(context, databaseInteractor, progressable, cancelled);
mKeyWritableRepository = databaseInteractor; mKeyWritableRepository = databaseInteractor;

View File

@@ -19,11 +19,14 @@ package org.sufficientlysecure.keychain.operations;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import android.content.Context; import android.content.Context;
import android.support.annotation.NonNull; 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.CertifyResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; 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.Progressable;
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; 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;
import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyAction; import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyAction;
import org.sufficientlysecure.keychain.service.ContactSyncAdapterService; import org.sufficientlysecure.keychain.service.ContactSyncAdapterService;
@@ -63,8 +63,8 @@ import org.sufficientlysecure.keychain.util.Passphrase;
public class CertifyOperation extends BaseReadWriteOperation<CertifyActionsParcel> { public class CertifyOperation extends BaseReadWriteOperation<CertifyActionsParcel> {
private final KeyMetadataDao keyMetadataDao; private final KeyMetadataDao keyMetadataDao;
public CertifyOperation(Context context, KeyWritableRepository keyWritableRepository, Progressable progressable, CancellationSignal public CertifyOperation(Context context, KeyWritableRepository keyWritableRepository, Progressable progressable,
cancelled) { AtomicBoolean cancelled) {
super(context, keyWritableRepository, progressable, cancelled); super(context, keyWritableRepository, progressable, cancelled);
this.keyMetadataDao = KeyMetadataDao.create(context); this.keyMetadataDao = KeyMetadataDao.create(context);

View File

@@ -19,12 +19,15 @@ package org.sufficientlysecure.keychain.operations;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.atomic.AtomicBoolean;
import android.content.Context; import android.content.Context;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.v4.os.CancellationSignal;
import org.sufficientlysecure.keychain.R; 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.EditKeyResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; 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.PgpKeyOperation;
import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.pgp.Progressable;
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; 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.ContactSyncAdapterService;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.service.UploadKeyringParcel; import org.sufficientlysecure.keychain.service.UploadKeyringParcel;
@@ -61,7 +61,7 @@ public class EditKeyOperation extends BaseReadWriteOperation<SaveKeyringParcel>
public EditKeyOperation(Context context, KeyWritableRepository databaseInteractor, public EditKeyOperation(Context context, KeyWritableRepository databaseInteractor,
Progressable progressable, CancellationSignal cancelled) { Progressable progressable, AtomicBoolean cancelled) {
super(context, databaseInteractor, progressable, cancelled); super(context, databaseInteractor, progressable, cancelled);
this.keyMetadataDao = KeyMetadataDao.create(context); this.keyMetadataDao = KeyMetadataDao.create(context);

View File

@@ -29,13 +29,15 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import android.content.Context; import android.content.Context;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v4.os.CancellationSignal;
import org.sufficientlysecure.keychain.R; 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.FacebookKeyserverClient;
import org.sufficientlysecure.keychain.keyimport.HkpKeyserverAddress; import org.sufficientlysecure.keychain.keyimport.HkpKeyserverAddress;
import org.sufficientlysecure.keychain.keyimport.HkpKeyserverClient; 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.Progressable;
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; 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.ContactSyncAdapterService;
import org.sufficientlysecure.keychain.service.ImportKeyringParcel; import org.sufficientlysecure.keychain.service.ImportKeyringParcel;
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
@@ -102,7 +102,7 @@ public class ImportOperation extends BaseReadWriteOperation<ImportKeyringParcel>
} }
public ImportOperation(Context context, KeyWritableRepository databaseInteractor, public ImportOperation(Context context, KeyWritableRepository databaseInteractor,
Progressable progressable, CancellationSignal cancelled) { Progressable progressable, AtomicBoolean cancelled) {
super(context, databaseInteractor, progressable, cancelled); super(context, databaseInteractor, progressable, cancelled);
this.keyMetadataDao = KeyMetadataDao.create(context); this.keyMetadataDao = KeyMetadataDao.create(context);

View File

@@ -5,18 +5,18 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import android.content.Context; import android.content.Context;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.v4.os.CancellationSignal;
import org.sufficientlysecure.keychain.Constants; 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.keyimport.ParcelableKeyRing;
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.pgp.Progressable; 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.ImportKeyringParcel;
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
@@ -36,7 +36,7 @@ public class KeySyncOperation extends BaseReadWriteOperation<KeySyncParcel> {
private final Preferences preferences; private final Preferences preferences;
public KeySyncOperation(Context context, KeyWritableRepository databaseInteractor, public KeySyncOperation(Context context, KeyWritableRepository databaseInteractor,
Progressable progressable, CancellationSignal cancellationSignal) { Progressable progressable, AtomicBoolean cancellationSignal) {
super(context, databaseInteractor, progressable, cancellationSignal); super(context, databaseInteractor, progressable, cancellationSignal);
keyMetadataDao = KeyMetadataDao.create(context); keyMetadataDao = KeyMetadataDao.create(context);

View File

@@ -20,12 +20,14 @@ package org.sufficientlysecure.keychain.operations;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import android.content.Context; import android.content.Context;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.v4.os.CancellationSignal;
import org.sufficientlysecure.keychain.R; 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.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult; 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.CanonicalizedPublicKeyRing;
import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.pgp.Progressable;
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; 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.PromoteKeyringParcel;
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
@@ -50,7 +50,7 @@ import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
*/ */
public class PromoteKeyOperation extends BaseReadWriteOperation<PromoteKeyringParcel> { public class PromoteKeyOperation extends BaseReadWriteOperation<PromoteKeyringParcel> {
public PromoteKeyOperation(Context context, KeyWritableRepository databaseInteractor, public PromoteKeyOperation(Context context, KeyWritableRepository databaseInteractor,
Progressable progressable, CancellationSignal cancelled) { Progressable progressable, AtomicBoolean cancelled) {
super(context, databaseInteractor, progressable, cancelled); super(context, databaseInteractor, progressable, cancelled);
} }

View File

@@ -20,12 +20,13 @@ package org.sufficientlysecure.keychain.operations;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import android.content.Context; import android.content.Context;
import android.net.Uri; import android.net.Uri;
import android.support.annotation.NonNull; 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.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
import org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult; 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.PgpSignEncryptOperation;
import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.pgp.Progressable;
import org.sufficientlysecure.keychain.pgp.SignEncryptParcel; 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.CryptoInputParcel;
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel.RequiredInputType; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel.RequiredInputType;
@@ -52,7 +52,7 @@ import org.sufficientlysecure.keychain.util.ProgressScaler;
public class SignEncryptOperation extends BaseOperation<SignEncryptParcel> { public class SignEncryptOperation extends BaseOperation<SignEncryptParcel> {
public SignEncryptOperation(Context context, KeyRepository keyRepository, public SignEncryptOperation(Context context, KeyRepository keyRepository,
Progressable progressable, CancellationSignal cancelled) { Progressable progressable, AtomicBoolean cancelled) {
super(context, keyRepository, progressable, cancelled); super(context, keyRepository, progressable, cancelled);
} }

View File

@@ -21,11 +21,11 @@ package org.sufficientlysecure.keychain.operations;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.net.Proxy; import java.net.Proxy;
import java.util.concurrent.atomic.AtomicBoolean;
import android.content.Context; import android.content.Context;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v4.os.CancellationSignal;
import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
@@ -60,7 +60,7 @@ public class UploadOperation extends BaseOperation<UploadKeyringParcel> {
private KeyMetadataDao keyMetadataDao; private KeyMetadataDao keyMetadataDao;
public UploadOperation(Context context, KeyRepository keyRepository, public UploadOperation(Context context, KeyRepository keyRepository,
Progressable progressable, CancellationSignal cancelled) { Progressable progressable, AtomicBoolean cancelled) {
super(context, keyRepository, progressable, cancelled); super(context, keyRepository, progressable, cancelled);
keyMetadataDao = KeyMetadataDao.create(mContext); keyMetadataDao = KeyMetadataDao.create(mContext);

View File

@@ -33,8 +33,7 @@ import java.util.Date;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Stack; import java.util.Stack;
import java.util.concurrent.atomic.AtomicBoolean;
import android.support.v4.os.CancellationSignal;
import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.nist.NISTNamedCurves; import org.bouncycastle.asn1.nist.NISTNamedCurves;
@@ -109,7 +108,7 @@ import timber.log.Timber;
public class PgpKeyOperation { public class PgpKeyOperation {
private Stack<Progressable> mProgress; private Stack<Progressable> mProgress;
private CancellationSignal mCancelled; private AtomicBoolean mCancelled;
public PgpKeyOperation(Progressable progress) { public PgpKeyOperation(Progressable progress) {
super(); super();
@@ -119,13 +118,13 @@ public class PgpKeyOperation {
} }
} }
public PgpKeyOperation(Progressable progress, CancellationSignal cancelled) { public PgpKeyOperation(Progressable progress, AtomicBoolean cancelled) {
this(progress); this(progress);
mCancelled = cancelled; mCancelled = cancelled;
} }
private boolean checkCancelled() { private boolean checkCancelled() {
return mCancelled != null && mCancelled.isCanceled(); return mCancelled != null && mCancelled.get();
} }
private void subProgressPush(int from, int to) { private void subProgressPush(int from, int to) {

View File

@@ -33,11 +33,11 @@ import java.security.SignatureException;
import java.util.Collection; import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import android.content.Context; import android.content.Context;
import android.net.Uri; import android.net.Uri;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.v4.os.CancellationSignal;
import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.bcpg.BCPGOutputStream; 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.bouncycastle.openpgp.operator.jcajce.PGPUtil;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R; 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.BaseOperation;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; 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.OpenKeychainHashAlgorithmTags;
import org.sufficientlysecure.keychain.pgp.PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags; import org.sufficientlysecure.keychain.pgp.PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; 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.CryptoInputParcel;
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
@@ -104,7 +104,7 @@ public class PgpSignEncryptOperation extends BaseOperation<PgpSignEncryptInputPa
} }
} }
public PgpSignEncryptOperation(Context context, KeyRepository keyRepository, Progressable progressable, CancellationSignal cancelled) { public PgpSignEncryptOperation(Context context, KeyRepository keyRepository, Progressable progressable, AtomicBoolean cancelled) {
super(context, keyRepository, progressable, cancelled); super(context, keyRepository, progressable, cancelled);
} }

View File

@@ -18,18 +18,15 @@
package org.sufficientlysecure.keychain.service; package org.sufficientlysecure.keychain.service;
import android.app.Service; import java.util.concurrent.LinkedBlockingQueue;
import android.content.Intent; import java.util.concurrent.ThreadPoolExecutor;
import android.os.Bundle; import java.util.concurrent.TimeUnit;
import android.os.IBinder; import java.util.concurrent.atomic.AtomicBoolean;
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 android.content.Context;
import org.sufficientlysecure.keychain.operations.KeySyncParcel; import android.os.Parcelable;
import org.sufficientlysecure.keychain.daos.KeyWritableRepository;
import org.sufficientlysecure.keychain.operations.BackupOperation; import org.sufficientlysecure.keychain.operations.BackupOperation;
import org.sufficientlysecure.keychain.operations.BaseOperation; import org.sufficientlysecure.keychain.operations.BaseOperation;
import org.sufficientlysecure.keychain.operations.BenchmarkOperation; import org.sufficientlysecure.keychain.operations.BenchmarkOperation;
@@ -39,6 +36,8 @@ import org.sufficientlysecure.keychain.operations.DeleteOperation;
import org.sufficientlysecure.keychain.operations.EditKeyOperation; import org.sufficientlysecure.keychain.operations.EditKeyOperation;
import org.sufficientlysecure.keychain.operations.ImportOperation; import org.sufficientlysecure.keychain.operations.ImportOperation;
import org.sufficientlysecure.keychain.operations.InputDataOperation; 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.KeybaseVerificationOperation;
import org.sufficientlysecure.keychain.operations.PromoteKeyOperation; import org.sufficientlysecure.keychain.operations.PromoteKeyOperation;
import org.sufficientlysecure.keychain.operations.RevokeOperation; import org.sufficientlysecure.keychain.operations.RevokeOperation;
@@ -49,180 +48,88 @@ import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel;
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyOperation; import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyOperation;
import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.pgp.Progressable;
import org.sufficientlysecure.keychain.pgp.SignEncryptParcel; 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 org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
import timber.log.Timber;
/** public class KeychainService {
* This Service contains all important long lasting operations for OpenKeychain. It receives Intents with private static KeychainService keychainService;
* 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 KeychainService getInstance(Context context) {
public static final String EXTRA_MESSENGER = "messenger"; if (keychainService == null) {
keychainService = new KeychainService(context.getApplicationContext());
}
return keychainService;
}
// extras for operation private KeychainService(Context context) {
public static final String EXTRA_OPERATION_INPUT = "op_input"; this.context = context;
public static final String EXTRA_CRYPTO_INPUT = "crypto_input"; this.threadPoolExecutor = new ThreadPoolExecutor(0, 4, 1000, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
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... // this attribute can possibly merged with the one above? not sure...
private CancellationSignal mActionCanceled; private AtomicBoolean operationCancelledBoolean = new AtomicBoolean(false);
ThreadLocal<Messenger> mMessenger = new ThreadLocal<>(); public void startOperationInBackground(Parcelable inputParcel, CryptoInputParcel cryptoInput,
Progressable progressable, OperationCallback operationCallback) {
operationCancelledBoolean.set(false);
@Override Runnable actionRunnable = () -> {
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; BaseOperation op;
// just for brevity
KeychainService outerThis = KeychainService.this;
KeyWritableRepository databaseInteractor =
KeyWritableRepository.create(outerThis);
if (inputParcel instanceof SignEncryptParcel) { if (inputParcel instanceof SignEncryptParcel) {
op = new SignEncryptOperation(outerThis, databaseInteractor, outerThis, mActionCanceled); op = new SignEncryptOperation(context, keyRepository, progressable, operationCancelledBoolean);
} else if (inputParcel instanceof PgpDecryptVerifyInputParcel) { } else if (inputParcel instanceof PgpDecryptVerifyInputParcel) {
op = new PgpDecryptVerifyOperation(outerThis, databaseInteractor, outerThis); op = new PgpDecryptVerifyOperation(context, keyRepository, progressable);
} else if (inputParcel instanceof SaveKeyringParcel) { } else if (inputParcel instanceof SaveKeyringParcel) {
op = new EditKeyOperation(outerThis, databaseInteractor, outerThis, mActionCanceled); op = new EditKeyOperation(context, keyRepository, progressable, operationCancelledBoolean);
} else if (inputParcel instanceof ChangeUnlockParcel) { } else if (inputParcel instanceof ChangeUnlockParcel) {
op = new ChangeUnlockOperation(outerThis, databaseInteractor, outerThis); op = new ChangeUnlockOperation(context, keyRepository, progressable);
} else if (inputParcel instanceof RevokeKeyringParcel) { } else if (inputParcel instanceof RevokeKeyringParcel) {
op = new RevokeOperation(outerThis, databaseInteractor, outerThis); op = new RevokeOperation(context, keyRepository, progressable);
} else if (inputParcel instanceof CertifyActionsParcel) { } else if (inputParcel instanceof CertifyActionsParcel) {
op = new CertifyOperation(outerThis, databaseInteractor, outerThis, mActionCanceled); op = new CertifyOperation(context, keyRepository, progressable, operationCancelledBoolean);
} else if (inputParcel instanceof DeleteKeyringParcel) { } else if (inputParcel instanceof DeleteKeyringParcel) {
op = new DeleteOperation(outerThis, databaseInteractor, outerThis); op = new DeleteOperation(context, keyRepository, progressable);
} else if (inputParcel instanceof PromoteKeyringParcel) { } else if (inputParcel instanceof PromoteKeyringParcel) {
op = new PromoteKeyOperation(outerThis, databaseInteractor, outerThis, mActionCanceled); op = new PromoteKeyOperation(context, keyRepository, progressable, operationCancelledBoolean);
} else if (inputParcel instanceof ImportKeyringParcel) { } else if (inputParcel instanceof ImportKeyringParcel) {
op = new ImportOperation(outerThis, databaseInteractor, outerThis, mActionCanceled); op = new ImportOperation(context, keyRepository, progressable, operationCancelledBoolean);
} else if (inputParcel instanceof BackupKeyringParcel) { } else if (inputParcel instanceof BackupKeyringParcel) {
op = new BackupOperation(outerThis, databaseInteractor, outerThis, mActionCanceled); op = new BackupOperation(context, keyRepository, progressable, operationCancelledBoolean);
} else if (inputParcel instanceof UploadKeyringParcel) { } else if (inputParcel instanceof UploadKeyringParcel) {
op = new UploadOperation(outerThis, databaseInteractor, outerThis, mActionCanceled); op = new UploadOperation(context, keyRepository, progressable, operationCancelledBoolean);
} else if (inputParcel instanceof KeybaseVerificationParcel) { } else if (inputParcel instanceof KeybaseVerificationParcel) {
op = new KeybaseVerificationOperation(outerThis, databaseInteractor, outerThis); op = new KeybaseVerificationOperation(context, keyRepository, progressable);
} else if (inputParcel instanceof InputDataParcel) { } else if (inputParcel instanceof InputDataParcel) {
op = new InputDataOperation(outerThis, databaseInteractor, outerThis); op = new InputDataOperation(context, keyRepository, progressable);
} else if (inputParcel instanceof BenchmarkInputParcel) { } else if (inputParcel instanceof BenchmarkInputParcel) {
op = new BenchmarkOperation(outerThis, databaseInteractor, outerThis); op = new BenchmarkOperation(context, keyRepository, progressable);
} else if (inputParcel instanceof KeySyncParcel) { } else if (inputParcel instanceof KeySyncParcel) {
op = new KeySyncOperation(outerThis, databaseInteractor, outerThis, mActionCanceled); op = new KeySyncOperation(context, keyRepository, progressable, operationCancelledBoolean);
} else { } else {
throw new AssertionError("Unrecognized input parcel in KeychainService!"); throw new AssertionError("Unrecognized input parcel in KeychainService!");
} }
@SuppressWarnings("unchecked") // this is unchecked, we make sure it's the correct op above! @SuppressWarnings("unchecked") // this is unchecked, we make sure it's the correct op above!
OperationResult result = op.execute(inputParcel, cryptoInput); OperationResult result = op.execute(inputParcel, cryptoInput);
sendMessageToHandler(MessageStatus.OKAY, result); operationCallback.operationFinished(result);
}
}; };
Thread actionThread = new Thread(actionRunnable); threadPoolExecutor.execute(actionRunnable);
actionThread.start();
return START_NOT_STICKY;
} }
private void sendMessageToHandler(MessageStatus status, Integer arg2, Bundle data) { public void cancelRunningTask() {
if (operationCancelledBoolean != null) {
Message msg = Message.obtain(); operationCancelledBoolean.set(true);
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) { public interface OperationCallback {
Bundle bundle = new Bundle(); void operationFinished(OperationResult data);
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);
}
} }

View File

@@ -29,7 +29,6 @@ import android.view.inputmethod.InputMethodManager;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.service.KeychainService;
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
/** This is a base class for fragments which implement a cryptoOperation. /** 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 * must override at least onCryptoOperationSuccess to proceed after a
* successful operation. * successful operation.
* *
* @see KeychainService
*
*/ */
public abstract class CryptoOperationFragment<T extends Parcelable, S extends OperationResult> public abstract class CryptoOperationFragment<T extends Parcelable, S extends OperationResult>
extends Fragment implements CryptoOperationHelper.Callback<T, S> { extends Fragment implements CryptoOperationHelper.Callback<T, S> {

View File

@@ -17,6 +17,7 @@
package org.sufficientlysecure.keychain.ui.base; package org.sufficientlysecure.keychain.ui.base;
import java.util.Date; import java.util.Date;
import android.app.Activity; import android.app.Activity;
@@ -27,6 +28,7 @@ import android.os.Handler;
import android.os.Message; import android.os.Message;
import android.os.Messenger; import android.os.Messenger;
import android.os.Parcelable; import android.os.Parcelable;
import android.os.RemoteException;
import android.os.SystemClock; import android.os.SystemClock;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity; 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.InputPendingResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult; 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;
import org.sufficientlysecure.keychain.service.KeychainService.OperationCallback;
import org.sufficientlysecure.keychain.service.ServiceProgressHandler; 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.CryptoInputParcel;
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
import org.sufficientlysecure.keychain.ui.SecurityTokenOperationActivity;
import org.sufficientlysecure.keychain.ui.OrbotRequiredDialogActivity; import org.sufficientlysecure.keychain.ui.OrbotRequiredDialogActivity;
import org.sufficientlysecure.keychain.ui.PassphraseDialogActivity; import org.sufficientlysecure.keychain.ui.PassphraseDialogActivity;
import org.sufficientlysecure.keychain.ui.RetryUploadDialogActivity; import org.sufficientlysecure.keychain.ui.RetryUploadDialogActivity;
import org.sufficientlysecure.keychain.ui.SecurityTokenOperationActivity;
import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
import timber.log.Timber; import timber.log.Timber;
@@ -295,12 +300,6 @@ public class CryptoOperationHelper<T extends Parcelable, S extends OperationResu
return; return;
} }
// Send all information needed to service to edit key in other thread
Intent intent = new Intent(activity, KeychainService.class);
intent.putExtra(KeychainService.EXTRA_OPERATION_INPUT, operationInput);
intent.putExtra(KeychainService.EXTRA_CRYPTO_INPUT, cryptoInput);
ServiceProgressHandler saveHandler = new ServiceProgressHandler(activity) { ServiceProgressHandler saveHandler = new ServiceProgressHandler(activity) {
@Override @Override
public void handleMessage(Message message) { public void handleMessage(Message message) {
@@ -331,9 +330,39 @@ public class CryptoOperationHelper<T extends Parcelable, S extends OperationResu
} }
}; };
// Create a new Messenger for the communication back
Messenger messenger = new Messenger(saveHandler); Messenger messenger = new Messenger(saveHandler);
intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger); Communicator communicator = new Communicator(messenger);
Progressable progressable = new Progressable() {
@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);
communicator.sendMessageToHandler(MessageStatus.UPDATE_PROGRESS, data);
}
@Override
public void setProgress(int resourceId, int progress, int max) {
setProgress(activity.getString(resourceId), progress, max);
}
@Override
public void setProgress(int progress, int max) {
setProgress(null, progress, max);
}
@Override
public void setPreventCancel() {
communicator.sendMessageToHandler(MessageStatus.PREVENT_CANCEL, (Bundle) null);
}
};
if (mProgressMessageResource != null) { if (mProgressMessageResource != null) {
saveHandler.showProgressDialog( saveHandler.showProgressDialog(
@@ -341,7 +370,8 @@ public class CryptoOperationHelper<T extends Parcelable, S extends OperationResu
ProgressDialog.STYLE_HORIZONTAL, mCancellable); ProgressDialog.STYLE_HORIZONTAL, mCancellable);
} }
activity.startService(intent); KeychainService keychainService = KeychainService.getInstance(activity);
keychainService.startOperationInBackground(operationInput, cryptoInput, progressable, communicator);
} }
public void cryptoOperation() { public void cryptoOperation() {
@@ -391,4 +421,37 @@ public class CryptoOperationHelper<T extends Parcelable, S extends OperationResu
+ result.getClass().getSimpleName() + "), this is a programming error!"); + result.getClass().getSimpleName() + "), this is a programming error!");
} }
} }
public static class Communicator implements OperationCallback {
final Messenger messenger;
Communicator(Messenger messenger) {
this.messenger = messenger;
}
public void sendMessageToHandler(MessageStatus status, Bundle data) {
Message msg = Message.obtain();
assert msg != null;
msg.arg1 = status.ordinal();
if (data != null) {
msg.setData(data);
}
try {
messenger.send(msg);
} catch (RemoteException e) {
Timber.w(e, "Exception sending message, Is handler present?");
} catch (NullPointerException e) {
Timber.w(e, "Messenger is null!");
}
}
@Override
public void operationFinished(OperationResult data) {
Bundle bundle = new Bundle();
bundle.putParcelable(OperationResult.EXTRA_RESULT, data);
sendMessageToHandler(MessageStatus.OKAY, bundle);
}
}
} }

View File

@@ -176,13 +176,8 @@ public class ProgressDialogFragment extends DialogFragment {
negative.setClickable(false); negative.setClickable(false);
negative.setTextColor(Color.GRAY); negative.setTextColor(Color.GRAY);
// send a cancel message. note that this message will be handled by KeychainService keychainService = KeychainService.getInstance(requireContext());
// KeychainService.onStartCommand, which runs in this thread, keychainService.cancelRunningTask();
// 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);
// Set the progress bar accordingly // Set the progress bar accordingly
ProgressDialog dialog = (ProgressDialog) getDialog(); ProgressDialog dialog = (ProgressDialog) getDialog();