From 074b6633b015aba84f8f60a05878a93d4b8ec9b2 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sat, 6 Jun 2015 23:17:42 +0200 Subject: [PATCH] eventbus: initial attempt, replace messenger hack with eventbus communication --- .../operations/CertifyOperationTest.java | 20 +-- OpenKeychain/build.gradle | 1 + OpenKeychain/src/main/AndroidManifest.xml | 3 + .../keychain/operations/BaseOperation.java | 9 +- .../keychain/operations/CertifyOperation.java | 6 +- .../keychain/operations/EditKeyOperation.java | 3 +- .../operations/SignEncryptOperation.java | 2 +- .../keychain/pgp/PgpDecryptVerify.java | 5 +- .../pgp/PgpSignEncryptInputParcel.java | 5 - .../service/CertifyActionsParcel.java | 2 + .../keychain/service/KeychainNewService.java | 150 ++++++++++++++++++ .../keychain/service/KeychainService.java | 89 +---------- .../keychain/service/ProgressEvent.java | 16 ++ .../keychain/ui/CertifyKeyFragment.java | 110 +++---------- .../keychain/ui/DecryptFilesFragment.java | 128 +++------------ .../keychain/ui/DecryptFragment.java | 7 +- .../keychain/ui/DecryptTextFragment.java | 104 +++--------- .../keychain/ui/EditKeyFragment.java | 97 +++-------- .../keychain/ui/EncryptFilesFragment.java | 145 +++++++---------- .../keychain/ui/EncryptTextFragment.java | 105 +++--------- .../base/CachingCryptoOperationFragment.java | 62 +++++--- .../ui/base/CryptoOperationFragment.java | 147 ++++++++++++++--- OpenKeychain/src/main/res/values/strings.xml | 1 + 23 files changed, 529 insertions(+), 688 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ProgressEvent.java diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/CertifyOperationTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/CertifyOperationTest.java index 130b86908..65bb85712 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/CertifyOperationTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/CertifyOperationTest.java @@ -30,14 +30,9 @@ import org.spongycastle.jce.provider.BouncyCastleProvider; import org.sufficientlysecure.keychain.operations.results.CertifyResult; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult; -import org.sufficientlysecure.keychain.operations.results.ExportResult; -import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing; -import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify; import org.sufficientlysecure.keychain.pgp.PgpKeyOperation; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; -import org.sufficientlysecure.keychain.pgp.UncachedKeyRing.IteratorWithIOThrow; -import org.sufficientlysecure.keychain.pgp.WrappedSignature; import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute; import org.sufficientlysecure.keychain.provider.KeychainContract.Certs; import org.sufficientlysecure.keychain.provider.ProviderHelper; @@ -47,18 +42,13 @@ import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; -import org.sufficientlysecure.keychain.util.InputData; import org.sufficientlysecure.keychain.util.Passphrase; import org.sufficientlysecure.keychain.util.ProgressScaler; import org.sufficientlysecure.keychain.util.TestingUtils; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.OutputStream; import java.io.PrintStream; import java.security.Security; import java.util.ArrayList; -import java.util.Iterator; import java.util.Random; @@ -166,7 +156,7 @@ public class CertifyOperationTest { CertifyActionsParcel actions = new CertifyActionsParcel(mStaticRing1.getMasterKeyId()); actions.add(new CertifyAction(mStaticRing2.getMasterKeyId(), mStaticRing2.getPublicKey().getUnorderedUserIds())); - CertifyResult result = op.certify(actions, new CryptoInputParcel(mKeyPhrase1), null); + CertifyResult result = op.execute(actions, new CryptoInputParcel(mKeyPhrase1), null); Assert.assertTrue("certification must succeed", result.success()); @@ -194,7 +184,7 @@ public class CertifyOperationTest { CertifyActionsParcel actions = new CertifyActionsParcel(mStaticRing1.getMasterKeyId()); actions.add(new CertifyAction(mStaticRing2.getMasterKeyId(), null, mStaticRing2.getPublicKey().getUnorderedUserAttributes())); - CertifyResult result = op.certify(actions, new CryptoInputParcel(mKeyPhrase1), null); + CertifyResult result = op.execute(actions, new CryptoInputParcel(mKeyPhrase1), null); Assert.assertTrue("certification must succeed", result.success()); @@ -217,7 +207,7 @@ public class CertifyOperationTest { actions.add(new CertifyAction(mStaticRing1.getMasterKeyId(), mStaticRing2.getPublicKey().getUnorderedUserIds())); - CertifyResult result = op.certify(actions, new CryptoInputParcel(mKeyPhrase1), null); + CertifyResult result = op.execute(actions, new CryptoInputParcel(mKeyPhrase1), null); Assert.assertFalse("certification with itself must fail!", result.success()); Assert.assertTrue("error msg must be about self certification", @@ -236,7 +226,7 @@ public class CertifyOperationTest { uids.add("nonexistent"); actions.add(new CertifyAction(1234L, uids)); - CertifyResult result = op.certify(actions, new CryptoInputParcel(mKeyPhrase1), null); + CertifyResult result = op.execute(actions, new CryptoInputParcel(mKeyPhrase1), null); Assert.assertFalse("certification of nonexistent key must fail", result.success()); Assert.assertTrue("must contain error msg about not found", @@ -248,7 +238,7 @@ public class CertifyOperationTest { actions.add(new CertifyAction(mStaticRing1.getMasterKeyId(), mStaticRing2.getPublicKey().getUnorderedUserIds())); - CertifyResult result = op.certify(actions, new CryptoInputParcel(mKeyPhrase1), null); + CertifyResult result = op.execute(actions, new CryptoInputParcel(mKeyPhrase1), null); Assert.assertFalse("certification of nonexistent key must fail", result.success()); Assert.assertTrue("must contain error msg about not found", diff --git a/OpenKeychain/build.gradle b/OpenKeychain/build.gradle index a4caa1fe7..d658572e0 100644 --- a/OpenKeychain/build.gradle +++ b/OpenKeychain/build.gradle @@ -24,6 +24,7 @@ dependencies { } // JCenter etc. + compile 'de.greenrobot:eventbus:2.4.0' compile 'com.eftimoff:android-patternview:1.0.1@aar' compile 'com.journeyapps:zxing-android-embedded:2.3.0@aar' compile 'com.journeyapps:zxing-android-integration:2.3.0@aar' diff --git a/OpenKeychain/src/main/AndroidManifest.xml b/OpenKeychain/src/main/AndroidManifest.xml index 7b74a5b20..f10547a0b 100644 --- a/OpenKeychain/src/main/AndroidManifest.xml +++ b/OpenKeychain/src/main/AndroidManifest.xml @@ -718,6 +718,9 @@ android:name=".remote.CryptoInputParcelCacheService" android:exported="false" android:process=":remote_api" /> + 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 5a3321ac8..fae59b7a4 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,20 @@ package org.sufficientlysecure.keychain.operations; import android.content.Context; +import android.os.Parcelable; +import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.pgp.PassphraseCacheInterface; import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.provider.ProviderHelper.NotFoundException; import org.sufficientlysecure.keychain.service.PassphraseCacheService; +import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.util.Passphrase; import java.util.concurrent.atomic.AtomicBoolean; -public abstract class BaseOperation implements PassphraseCacheInterface { +public abstract class BaseOperation implements PassphraseCacheInterface { final public Context mContext; final public Progressable mProgressable; @@ -73,6 +76,10 @@ public abstract class BaseOperation implements PassphraseCacheInterface { mCancelled = cancelled; } + public OperationResult execute(T input, CryptoInputParcel cryptoInput) { + return null; + } + public void updateProgress(int message, int current, int total) { if (mProgressable != null) { mProgressable.setProgress(message, current, total); 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 186d0531d..439260b74 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java @@ -64,7 +64,7 @@ public class CertifyOperation extends BaseOperation { super(context, providerHelper, progressable, cancelled); } - public CertifyResult certify(CertifyActionsParcel parcel, CryptoInputParcel cryptoInput, String keyServerUri) { + public CertifyResult execute(CertifyActionsParcel parcel, CryptoInputParcel cryptoInput) { OperationLog log = new OperationLog(); log.add(LogType.MSG_CRT, 0); @@ -186,8 +186,8 @@ public class CertifyOperation extends BaseOperation { HkpKeyserver keyServer = null; ImportExportOperation importExportOperation = null; - if (keyServerUri != null) { - keyServer = new HkpKeyserver(keyServerUri); + if (parcel.keyServerUri != null) { + keyServer = new HkpKeyserver(parcel.keyServerUri); importExportOperation = new ImportExportOperation(mContext, mProviderHelper, mProgressable); } 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 e8e888c7a..469e386cb 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java @@ -37,7 +37,6 @@ import org.sufficientlysecure.keychain.service.PassphraseCacheService; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; -import org.sufficientlysecure.keychain.util.Passphrase; import org.sufficientlysecure.keychain.util.ProgressScaler; import java.util.concurrent.atomic.AtomicBoolean; @@ -51,7 +50,7 @@ import java.util.concurrent.atomic.AtomicBoolean; * @see SaveKeyringParcel * */ -public class EditKeyOperation extends BaseOperation { +public class EditKeyOperation extends BaseOperation { public EditKeyOperation(Context context, ProviderHelper providerHelper, Progressable progressable, AtomicBoolean 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 651d15e8f..7c58d62f8 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java @@ -55,7 +55,7 @@ import java.util.concurrent.atomic.AtomicBoolean; * a pending result, it will terminate. * */ -public class SignEncryptOperation extends BaseOperation { +public class SignEncryptOperation extends BaseOperation { public SignEncryptOperation(Context context, ProviderHelper providerHelper, Progressable progressable, AtomicBoolean cancelled) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java index 4382c9fae..fd3d41f93 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java @@ -76,10 +76,7 @@ import java.security.SignatureException; import java.util.Date; import java.util.Iterator; -/** - * This class uses a Builder pattern! - */ -public class PgpDecryptVerify extends BaseOperation { +public class PgpDecryptVerify extends BaseOperation { public PgpDecryptVerify(Context context, ProviderHelper providerHelper, Progressable progressable) { super(context, providerHelper, progressable); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptInputParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptInputParcel.java index fd3c4910c..fa6268758 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptInputParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptInputParcel.java @@ -20,13 +20,8 @@ package org.sufficientlysecure.keychain.pgp; import org.spongycastle.bcpg.CompressionAlgorithmTags; import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.util.Passphrase; -import java.nio.ByteBuffer; -import java.util.Date; -import java.util.Map; - import android.os.Parcel; import android.os.Parcelable; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CertifyActionsParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CertifyActionsParcel.java index 8721f4c0c..a11f81658 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CertifyActionsParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CertifyActionsParcel.java @@ -43,6 +43,8 @@ public class CertifyActionsParcel implements Parcelable { public ArrayList mCertifyActions = new ArrayList<>(); + public String keyServerUri; + public CertifyActionsParcel(long masterKeyId) { mMasterKeyId = masterKeyId; mLevel = CertifyLevel.DEFAULT; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java new file mode 100644 index 000000000..5ef475029 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2012-2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser + * + * 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.app.Service; +import android.content.Intent; +import android.os.Bundle; +import android.os.IBinder; +import android.os.Parcelable; + +import de.greenrobot.event.EventBus; +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.operations.BaseOperation; +import org.sufficientlysecure.keychain.operations.CertifyOperation; +import org.sufficientlysecure.keychain.operations.EditKeyOperation; +import org.sufficientlysecure.keychain.operations.SignEncryptOperation; +import org.sufficientlysecure.keychain.operations.results.OperationResult; +import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify; +import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel; +import org.sufficientlysecure.keychain.pgp.Progressable; +import org.sufficientlysecure.keychain.pgp.SignEncryptParcel; +import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyAction; +import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; +import org.sufficientlysecure.keychain.util.Log; + +/** + * 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 KeychainNewService extends Service implements Progressable { + + /* extras that can be given by intent */ + public static final String EXTRA_OPERATION_INPUT = "op_input"; + public static final String EXTRA_CRYPTO_INPUT = "crypto_input"; + + // this attribute can possibly merged with the one above? not sure... + private AtomicBoolean mActionCanceled = new AtomicBoolean(false); + + @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) { + EventBus bus = EventBus.getDefault(); + if (!bus.isRegistered(this)) { + bus.register(this); + } + + Bundle extras = intent.getExtras(); + if (extras != null) { + bus.post(extras); + } else { + Log.e(Constants.TAG, "Extras bundle is null!"); + } + + return START_NOT_STICKY; + } + + @Override + public void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + } + + public void onEventAsync(Bundle bundle) { + + // Input + Parcelable inputParcel = bundle.getParcelable(EXTRA_OPERATION_INPUT); + CryptoInputParcel cryptoInput = bundle.getParcelable(EXTRA_CRYPTO_INPUT); + + // Operation + BaseOperation op; + + if (inputParcel instanceof SignEncryptParcel) { + op = new SignEncryptOperation(this, new ProviderHelper(this), this, mActionCanceled); + } else if (inputParcel instanceof PgpDecryptVerifyInputParcel) { + op = new PgpDecryptVerify(this, new ProviderHelper(this), this); + } else if (inputParcel instanceof SaveKeyringParcel) { + op = new EditKeyOperation(this, new ProviderHelper(this), this, mActionCanceled); + } else if (inputParcel instanceof CertifyAction) { + op = new CertifyOperation(this, new ProviderHelper(this), this, mActionCanceled); + } else { + return; + } + + @SuppressWarnings("unchecked") // this is unchecked, we make sure it's the correct op above! + OperationResult result = op.execute(inputParcel, cryptoInput); + + // Result + EventBus.getDefault().post(result); + + stopSelf(); + + } + + /** + * Set progress of ProgressDialog by sending message to handler on UI thread + */ + @Override + public void setProgress(String message, int progress, int max) { + Log.d(Constants.TAG, "Send message by setProgress with progress=" + progress + ", max=" + + max); + + ProgressEvent event = new ProgressEvent(message, progress, max); + EventBus.getDefault().post(event); + + } + + @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/KeychainService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java index b8cb9de27..e4bfd7dee 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java @@ -30,6 +30,7 @@ import android.os.RemoteException; import com.textuality.keybase.lib.Proof; import com.textuality.keybase.lib.prover.Prover; +import de.greenrobot.event.EventBus; import org.json.JSONObject; import org.spongycastle.openpgp.PGPUtil; import org.sufficientlysecure.keychain.Constants; @@ -96,14 +97,9 @@ public class KeychainService extends Service implements Progressable { public static final String EXTRA_DATA = "data"; /* possible actions */ - public static final String ACTION_SIGN_ENCRYPT = Constants.INTENT_PREFIX + "SIGN_ENCRYPT"; - - public static final String ACTION_DECRYPT_VERIFY = Constants.INTENT_PREFIX + "DECRYPT_VERIFY"; public static final String ACTION_VERIFY_KEYBASE_PROOF = Constants.INTENT_PREFIX + "VERIFY_KEYBASE_PROOF"; - public static final String ACTION_DECRYPT_METADATA = Constants.INTENT_PREFIX + "DECRYPT_METADATA"; - public static final String ACTION_EDIT_KEYRING = Constants.INTENT_PREFIX + "EDIT_KEYRING"; public static final String ACTION_PROMOTE_KEYRING = Constants.INTENT_PREFIX + "PROMOTE_KEYRING"; @@ -113,8 +109,6 @@ public class KeychainService extends Service implements Progressable { public static final String ACTION_UPLOAD_KEYRING = Constants.INTENT_PREFIX + "UPLOAD_KEYRING"; - public static final String ACTION_CERTIFY_KEYRING = Constants.INTENT_PREFIX + "SIGN_KEYRING"; - public static final String ACTION_DELETE = Constants.INTENT_PREFIX + "DELETE"; public static final String ACTION_CONSOLIDATE = Constants.INTENT_PREFIX + "CONSOLIDATE"; @@ -123,14 +117,6 @@ public class KeychainService extends Service implements Progressable { /* keys for data bundle */ - // encrypt - public static final String ENCRYPT_DECRYPT_INPUT_URI = "input_uri"; - public static final String ENCRYPT_DECRYPT_OUTPUT_URI = "output_uri"; - public static final String SIGN_ENCRYPT_PARCEL = "sign_encrypt_parcel"; - - // decrypt/verify - public static final String DECRYPT_VERIFY_PARCEL = "decrypt_verify_parcel"; - // keybase proof public static final String KEYBASE_REQUIRED_FINGERPRINT = "keybase_required_fingerprint"; public static final String KEYBASE_PROOF = "keybase_proof"; @@ -158,9 +144,6 @@ public class KeychainService extends Service implements Progressable { // upload key public static final String UPLOAD_KEY_SERVER = "upload_key_server"; - // certify key - public static final String CERTIFY_PARCEL = "certify_parcel"; - // promote key public static final String PROMOTE_MASTER_KEY_ID = "promote_master_key_id"; public static final String PROMOTE_CARD_AID = "promote_card_aid"; @@ -232,23 +215,6 @@ public class KeychainService extends Service implements Progressable { // executeServiceMethod action from extra bundle switch (action) { - case ACTION_CERTIFY_KEYRING: { - - // Input - CertifyActionsParcel parcel = data.getParcelable(CERTIFY_PARCEL); - CryptoInputParcel cryptoInput = data.getParcelable(EXTRA_CRYPTO_INPUT); - String keyServerUri = data.getString(UPLOAD_KEY_SERVER); - - // Operation - CertifyOperation op = new CertifyOperation(mKeychainService, providerHelper, mKeychainService, - mActionCanceled); - CertifyResult result = op.certify(parcel, cryptoInput, keyServerUri); - - // Result - sendMessageToHandler(MessageStatus.OKAY, result); - - break; - } case ACTION_CONSOLIDATE: { // Operation @@ -264,24 +230,6 @@ public class KeychainService extends Service implements Progressable { break; } - case ACTION_DECRYPT_METADATA: { - - // Input - CryptoInputParcel cryptoInput = data.getParcelable(EXTRA_CRYPTO_INPUT); - PgpDecryptVerifyInputParcel input = data.getParcelable(DECRYPT_VERIFY_PARCEL); - - // this action is here for compatibility only - input.setDecryptMetadataOnly(true); - - // Operation - PgpDecryptVerify op = new PgpDecryptVerify(mKeychainService, providerHelper, mKeychainService); - DecryptVerifyResult decryptVerifyResult = op.execute(input, cryptoInput); - - // Result - sendMessageToHandler(MessageStatus.OKAY, decryptVerifyResult); - - break; - } case ACTION_VERIFY_KEYBASE_PROOF: { try { @@ -376,25 +324,6 @@ public class KeychainService extends Service implements Progressable { break; } - case ACTION_DECRYPT_VERIFY: { - - // Input - CryptoInputParcel cryptoInput = data.getParcelable(EXTRA_CRYPTO_INPUT); - PgpDecryptVerifyInputParcel input = data.getParcelable(DECRYPT_VERIFY_PARCEL); - - // for compatibility - // TODO merge with ACTION_DECRYPT_METADATA - input.setDecryptMetadataOnly(false); - - // Operation - PgpDecryptVerify op = new PgpDecryptVerify(mKeychainService, providerHelper, mKeychainService); - DecryptVerifyResult decryptVerifyResult = op.execute(input, cryptoInput); - - // Output - sendMessageToHandler(MessageStatus.OKAY, decryptVerifyResult); - - break; - } case ACTION_DELETE: { // Input @@ -495,22 +424,6 @@ public class KeychainService extends Service implements Progressable { break; } - case ACTION_SIGN_ENCRYPT: { - - // Input - SignEncryptParcel inputParcel = data.getParcelable(SIGN_ENCRYPT_PARCEL); - CryptoInputParcel cryptoInput = data.getParcelable(EXTRA_CRYPTO_INPUT); - - // Operation - SignEncryptOperation op = new SignEncryptOperation( - mKeychainService, providerHelper, mKeychainService, mActionCanceled); - SignEncryptResult result = op.execute(inputParcel, cryptoInput); - - // Result - sendMessageToHandler(MessageStatus.OKAY, result); - - break; - } case ACTION_UPLOAD_KEYRING: { try { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ProgressEvent.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ProgressEvent.java new file mode 100644 index 000000000..d441eccd0 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ProgressEvent.java @@ -0,0 +1,16 @@ +package org.sufficientlysecure.keychain.service; + + +public class ProgressEvent { + + public final String mMessage; + public final int mProgress; + public final int mMax; + + public ProgressEvent(String message, int progress, int max) { + mMessage = message; + mProgress = progress; + mMax = max; + } + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java index 6afe2256b..e39a3a0bf 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java @@ -64,7 +64,8 @@ import org.sufficientlysecure.keychain.util.Preferences; import java.util.ArrayList; -public class CertifyKeyFragment extends CachingCryptoOperationFragment +public class CertifyKeyFragment + extends CachingCryptoOperationFragment implements LoaderManager.LoaderCallbacks { public static final String ARG_CHECK_STATES = "check_states"; @@ -89,7 +90,6 @@ public class CertifyKeyFragment extends CachingCryptoOperationFragment checkedStates; if (savedInstanceState != null) { checkedStates = (ArrayList) savedInstanceState.getSerializable(ARG_CHECK_STATES); @@ -306,97 +302,39 @@ public class CertifyKeyFragment extends CachingCryptoOperationFragment certifyActions = mUserIdsAdapter.getSelectedCertifyActions(); - if (certifyActions.isEmpty()) { - Notify.create(getActivity(), "No identities selected!", - Notify.Style.ERROR).show(); - return; - } - - long selectedKeyId = mCertifyKeySpinner.getSelectedKeyId(); - - // fill values for this action - actionsParcel = new CertifyActionsParcel(selectedKeyId); - actionsParcel.mCertifyActions.addAll(certifyActions); - - // cached for next cryptoOperation loop - cacheActionsParcel(actionsParcel); - } - - data.putParcelable(KeychainService.EXTRA_CRYPTO_INPUT, cryptoInput); - data.putParcelable(KeychainService.CERTIFY_PARCEL, actionsParcel); - - if (mUploadKeyCheckbox.isChecked()) { - String keyserver = Preferences.getPreferences(getActivity()).getPreferredKeyserver(); - data.putString(KeychainService.UPLOAD_KEY_SERVER, keyserver); - } + // Bail out if there is not at least one user id selected + ArrayList certifyActions = mUserIdsAdapter.getSelectedCertifyActions(); + if (certifyActions.isEmpty()) { + Notify.create(getActivity(), "No identities selected!", + Notify.Style.ERROR).show(); + return null; } - // Send all information needed to service to sign key in other thread - Intent intent = new Intent(getActivity(), KeychainService.class); - intent.setAction(KeychainService.ACTION_CERTIFY_KEYRING); - intent.putExtra(KeychainService.EXTRA_DATA, data); + long selectedKeyId = mCertifyKeySpinner.getSelectedKeyId(); - if (mPassthroughMessenger != null) { - intent.putExtra(KeychainService.EXTRA_MESSENGER, mPassthroughMessenger); - } else { + // fill values for this action + CertifyActionsParcel actionsParcel = new CertifyActionsParcel(selectedKeyId); + actionsParcel.mCertifyActions.addAll(certifyActions); - // Message is received after signing is done in KeychainService - ServiceProgressHandler saveHandler = new ServiceProgressHandler( - getActivity(), - getString(R.string.progress_certifying), - ProgressDialog.STYLE_SPINNER, - true - ) { - @Override - public void handleMessage(Message message) { - // handle messages by KeychainIntentCryptoServiceHandler first - super.handleMessage(message); + // cached for next cryptoOperation loop + cacheActionsParcel(actionsParcel); - // handle pending messages - if (handlePendingMessage(message)) { - return; - } - - if (message.arg1 == MessageStatus.OKAY.ordinal()) { - Bundle data = message.getData(); - - CertifyResult result = data.getParcelable(CertifyResult.EXTRA_RESULT); - - Intent intent = new Intent(); - intent.putExtra(CertifyResult.EXTRA_RESULT, result); - getActivity().setResult(Activity.RESULT_OK, intent); - getActivity().finish(); - } - } - }; - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(saveHandler); - intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger); - - // show progress dialog - saveHandler.showProgressDialog(getActivity()); - } - - // start service with intent - getActivity().startService(intent); - - if (mPassthroughMessenger != null) { - getActivity().setResult(Activity.RESULT_OK); - getActivity().finish(); - } + return actionsParcel; + } + @Override + protected void onCryptoOperationSuccess(CertifyResult result) { + Intent intent = new Intent(); + intent.putExtra(CertifyResult.EXTRA_RESULT, result); + getActivity().setResult(Activity.RESULT_OK, intent); + getActivity().finish(); } @Override protected void onCryptoOperationCancelled() { super.onCryptoOperationCancelled(); } + } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java index b2d9596fd..bc7705233 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java @@ -63,8 +63,6 @@ public class DecryptFilesFragment extends DecryptFragment { private Uri mInputUri = null; private Uri mOutputUri = null; - private String mCurrentCryptoOperation; - /** * Creates new instance of this fragment */ @@ -151,7 +149,7 @@ public class DecryptFilesFragment extends DecryptFragment { return; } - startDecryptFilenames(); + cryptoOperation(); } private String removeEncryptedAppend(String name) { @@ -179,112 +177,6 @@ public class DecryptFilesFragment extends DecryptFragment { } } - private void startDecrypt() { - mCurrentCryptoOperation = KeychainService.ACTION_DECRYPT_VERIFY; - cryptoOperation(new CryptoInputParcel()); - } - - private void startDecryptFilenames() { - mCurrentCryptoOperation = KeychainService.ACTION_DECRYPT_METADATA; - cryptoOperation(new CryptoInputParcel()); - } - - @Override - @SuppressLint("HandlerLeak") - protected void cryptoOperation(CryptoInputParcel cryptoInput) { - // Send all information needed to service to decrypt in other thread - Intent intent = new Intent(getActivity(), KeychainService.class); - - // fill values for this action - Bundle data = new Bundle(); - // use current operation, either decrypt metadata or decrypt payload - intent.setAction(mCurrentCryptoOperation); - - // data - - Log.d(Constants.TAG, "mInputUri=" + mInputUri + ", mOutputUri=" + mOutputUri); - - PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(mInputUri, mOutputUri) - .setAllowSymmetricDecryption(true); - - data.putParcelable(KeychainService.DECRYPT_VERIFY_PARCEL, input); - data.putParcelable(KeychainService.EXTRA_CRYPTO_INPUT, cryptoInput); - - intent.putExtra(KeychainService.EXTRA_DATA, data); - - // Message is received after decrypting is done in KeychainService - ServiceProgressHandler saveHandler = new ServiceProgressHandler( - getActivity(), - getString(R.string.progress_decrypting), - ProgressDialog.STYLE_HORIZONTAL - ) { - @Override - public void handleMessage(Message message) { - // handle messages by standard KeychainIntentServiceHandler first - super.handleMessage(message); - - // handle pending messages - if (handlePendingMessage(message)) { - return; - } - - if (message.arg1 == MessageStatus.OKAY.ordinal()) { - // get returned data bundle - Bundle returnData = message.getData(); - - DecryptVerifyResult pgpResult = - returnData.getParcelable(DecryptVerifyResult.EXTRA_RESULT); - - if (pgpResult.success()) { - switch (mCurrentCryptoOperation) { - case KeychainService.ACTION_DECRYPT_METADATA: { - askForOutputFilename(pgpResult.getDecryptMetadata().getFilename()); - break; - } - case KeychainService.ACTION_DECRYPT_VERIFY: { - // display signature result in activity - loadVerifyResult(pgpResult); - - if (mDeleteAfter.isChecked()) { - // Create and show dialog to delete original file - DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment.newInstance(mInputUri); - deleteFileDialog.show(getActivity().getSupportFragmentManager(), "deleteDialog"); - setInputUri(null); - } - - /* - // A future open after decryption feature - if () { - Intent viewFile = new Intent(Intent.ACTION_VIEW); - viewFile.setInputData(mOutputUri); - startActivity(viewFile); - } - */ - break; - } - default: { - Log.e(Constants.TAG, "Bug: not supported operation!"); - break; - } - } - } - pgpResult.createNotify(getActivity()).show(DecryptFilesFragment.this); - } - - } - }; - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(saveHandler); - intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger); - - // show progress dialog - saveHandler.showProgressDialog(getActivity()); - - // start service with intent - getActivity().startService(intent); - } - @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { @@ -299,7 +191,7 @@ public class DecryptFilesFragment extends DecryptFragment { // This happens after output file was selected, so start our operation if (resultCode == Activity.RESULT_OK && data != null) { mOutputUri = data.getData(); - startDecrypt(); + cryptoOperation(); } return; } @@ -314,4 +206,20 @@ public class DecryptFilesFragment extends DecryptFragment { protected void onVerifyLoaded(boolean hideErrorOverlay) { } + + @Override + protected PgpDecryptVerifyInputParcel createOperationInput() { + return new PgpDecryptVerifyInputParcel(mInputUri, mOutputUri).setAllowSymmetricDecryption(true); + } + + @Override + protected void onCryptoOperationSuccess(DecryptVerifyResult result) { + + // display signature result in activity + loadVerifyResult(result); + + // TODO delete after decrypt not implemented! + + } + } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java index 3d87ce894..0626326fc 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java @@ -43,12 +43,14 @@ import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult; import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.pgp.KeyRing; +import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel; import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.KeychainService; import org.sufficientlysecure.keychain.service.ServiceProgressHandler; +import org.sufficientlysecure.keychain.ui.base.CachingCryptoOperationFragment; import org.sufficientlysecure.keychain.ui.base.CryptoOperationFragment; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State; @@ -56,8 +58,9 @@ import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.ui.util.Notify.Style; import org.sufficientlysecure.keychain.util.Preferences; -public abstract class DecryptFragment extends CryptoOperationFragment implements - LoaderManager.LoaderCallbacks { +public abstract class DecryptFragment + extends CachingCryptoOperationFragment + implements LoaderManager.LoaderCallbacks { public static final int LOADER_ID_UNIFIED = 0; public static final String ARG_DECRYPT_VERIFY_RESULT = "decrypt_verify_result"; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java index b7ea90a36..1dcda5b8d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java @@ -17,11 +17,8 @@ package org.sufficientlysecure.keychain.ui; -import android.app.ProgressDialog; import android.content.Intent; import android.os.Bundle; -import android.os.Message; -import android.os.Messenger; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -35,9 +32,6 @@ import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.ClipboardReflection; import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult; import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel; -import org.sufficientlysecure.keychain.service.KeychainService; -import org.sufficientlysecure.keychain.service.ServiceProgressHandler; -import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.util.ShareHelper; @@ -115,7 +109,7 @@ public class DecryptTextFragment extends DecryptFragment { mShowMenuOptions = args.getBoolean(ARG_SHOW_MENU, false); if (savedInstanceState == null) { - cryptoOperation(new CryptoInputParcel()); + cryptoOperation(); } } @@ -158,77 +152,8 @@ public class DecryptTextFragment extends DecryptFragment { } @Override - protected void cryptoOperation(CryptoInputParcel cryptoInput) { - // Send all information needed to service to decrypt in other thread - Intent intent = new Intent(getActivity(), KeychainService.class); - - // fill values for this action - Bundle data = new Bundle(); - - intent.setAction(KeychainService.ACTION_DECRYPT_VERIFY); - - PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(mCiphertext.getBytes()); - data.putParcelable(KeychainService.DECRYPT_VERIFY_PARCEL, input); - data.putParcelable(KeychainService.EXTRA_CRYPTO_INPUT, cryptoInput); - - intent.putExtra(KeychainService.EXTRA_DATA, data); - - // Message is received after encrypting is done in KeychainService - ServiceProgressHandler saveHandler = new ServiceProgressHandler( - getActivity(), - getString(R.string.progress_decrypting), - ProgressDialog.STYLE_HORIZONTAL - ) { - public void handleMessage(Message message) { - // handle messages by standard KeychainIntentServiceHandler first - super.handleMessage(message); - - // handle pending messages - if (handlePendingMessage(message)) { - return; - } - - if (message.arg1 == MessageStatus.OKAY.ordinal()) { - // get returned data bundle - Bundle returnData = message.getData(); - - DecryptVerifyResult pgpResult = - returnData.getParcelable(DecryptVerifyResult.EXTRA_RESULT); - - if (pgpResult.success()) { - byte[] decryptedMessage = pgpResult.getOutputBytes(); - String displayMessage; - if (pgpResult.getCharset() != null) { - try { - displayMessage = new String(decryptedMessage, pgpResult.getCharset()); - } catch (UnsupportedEncodingException e) { - // if we can't decode properly, just fall back to utf-8 - displayMessage = new String(decryptedMessage); - } - } else { - displayMessage = new String(decryptedMessage); - } - mText.setText(displayMessage); - - // display signature result in activity - loadVerifyResult(pgpResult); - } else { - // TODO: show also invalid layout with different text? - } - pgpResult.createNotify(getActivity()).show(DecryptTextFragment.this); - } - } - }; - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(saveHandler); - intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger); - - // show progress dialog - saveHandler.showProgressDialog(getActivity()); - - // start service with intent - getActivity().startService(intent); + protected PgpDecryptVerifyInputParcel createOperationInput() { + return new PgpDecryptVerifyInputParcel(mCiphertext.getBytes()); } @Override @@ -236,4 +161,27 @@ public class DecryptTextFragment extends DecryptFragment { mShowMenuOptions = hideErrorOverlay; getActivity().supportInvalidateOptionsMenu(); } + + @Override + protected void onCryptoOperationSuccess(DecryptVerifyResult result) { + + byte[] decryptedMessage = result.getOutputBytes(); + String displayMessage; + if (result.getCharset() != null) { + try { + displayMessage = new String(decryptedMessage, result.getCharset()); + } catch (UnsupportedEncodingException e) { + // if we can't decode properly, just fall back to utf-8 + displayMessage = new String(decryptedMessage); + } + } else { + displayMessage = new String(decryptedMessage); + } + mText.setText(displayMessage); + + // display signature result in activity + loadVerifyResult(result); + + } + } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java index 63fb8413b..48aa3016d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java @@ -26,6 +26,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.Messenger; +import android.os.Parcelable; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; @@ -39,6 +40,9 @@ import android.widget.ListView; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround; +import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult; +import org.sufficientlysecure.keychain.operations.results.EditKeyResult; +import org.sufficientlysecure.keychain.operations.results.InputPendingResult; import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.SingletonResult; @@ -66,9 +70,8 @@ import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Passphrase; - -public class EditKeyFragment extends CryptoOperationFragment implements - LoaderManager.LoaderCallbacks { +public class EditKeyFragment extends CryptoOperationFragment + implements LoaderManager.LoaderCallbacks { public static final String ARG_DATA_URI = "uri"; public static final String ARG_SAVE_KEYRING_PARCEL = "save_keyring_parcel"; @@ -572,7 +575,7 @@ public class EditKeyFragment extends CryptoOperationFragment implements addSubkeyDialogFragment.show(getActivity().getSupportFragmentManager(), "addSubkeyDialog"); } - private void returnKeyringParcel() { + protected void returnKeyringParcel() { if (mSaveKeyringParcel.mAddUserIds.size() == 0) { Notify.create(getActivity(), R.string.edit_key_error_add_identity, Notify.Style.ERROR).show(); return; @@ -591,76 +594,6 @@ public class EditKeyFragment extends CryptoOperationFragment implements getActivity().finish(); } - @Override - protected void cryptoOperation(CryptoInputParcel cryptoInput) { - - Log.d(Constants.TAG, "cryptoInput:\n" + cryptoInput); - Log.d(Constants.TAG, "mSaveKeyringParcel:\n" + mSaveKeyringParcel); - - ServiceProgressHandler saveHandler = new ServiceProgressHandler( - getActivity(), - getString(R.string.progress_saving), - ProgressDialog.STYLE_HORIZONTAL, - true - ) { - public void handleMessage(Message message) { - // handle messages by standard KeychainIntentServiceHandler first - super.handleMessage(message); - - if (handlePendingMessage(message)) { - return; - } - - if (message.arg1 == MessageStatus.OKAY.ordinal()) { - - // get returned data bundle - Bundle returnData = message.getData(); - if (returnData == null) { - return; - } - final OperationResult result = - returnData.getParcelable(OperationResult.EXTRA_RESULT); - if (result == null) { - return; - } - - // if bad -> display here! - if (!result.success()) { - result.createNotify(getActivity()).show(); - return; - } - - // if good -> finish, return result to showkey and display there! - Intent intent = new Intent(); - intent.putExtra(OperationResult.EXTRA_RESULT, result); - getActivity().setResult(EditKeyActivity.RESULT_OK, intent); - getActivity().finish(); - - } - } - }; - - // Send all information needed to service to import key in other thread - Intent intent = new Intent(getActivity(), KeychainService.class); - intent.setAction(KeychainService.ACTION_EDIT_KEYRING); - - // fill values for this action - Bundle data = new Bundle(); - data.putParcelable(KeychainService.EXTRA_CRYPTO_INPUT, cryptoInput); - data.putParcelable(KeychainService.EDIT_KEYRING_PARCEL, mSaveKeyringParcel); - intent.putExtra(KeychainService.EXTRA_DATA, data); - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(saveHandler); - intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger); - - // show progress dialog - saveHandler.showProgressDialog(getActivity()); - - // start service with intent - getActivity().startService(intent); - } - /** * Closes this activity, returning a result parcel with a single error log entry. */ @@ -675,4 +608,20 @@ public class EditKeyFragment extends CryptoOperationFragment implements getActivity().finish(); } + @Override + protected SaveKeyringParcel createOperationInput() { + return mSaveKeyringParcel; + } + + @Override + protected void onCryptoOperationSuccess(OperationResult result) { + + // if good -> finish, return result to showkey and display there! + Intent intent = new Intent(); + intent.putExtra(OperationResult.EXTRA_RESULT, result); + getActivity().setResult(EditKeyActivity.RESULT_OK, intent); + getActivity().finish(); + + } + } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java index ddfdecca3..ba626cf11 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java @@ -49,6 +49,7 @@ import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.pgp.PgpConstants; import org.sufficientlysecure.keychain.pgp.SignEncryptParcel; import org.sufficientlysecure.keychain.provider.TemporaryStorageProvider; +import org.sufficientlysecure.keychain.service.KeychainNewService; import org.sufficientlysecure.keychain.service.KeychainService; import org.sufficientlysecure.keychain.service.ServiceProgressHandler; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; @@ -72,7 +73,8 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -public class EncryptFilesFragment extends CachingCryptoOperationFragment { +public class EncryptFilesFragment + extends CachingCryptoOperationFragment { public static final String ARG_DELETE_AFTER_ENCRYPT = "delete_after_encrypt"; public static final String ARG_ENCRYPT_FILENAMES = "encrypt_filenames"; @@ -272,11 +274,13 @@ public class EncryptFilesFragment extends CachingCryptoOperationFragment(1); mOutputUris.add(data.getData()); - cryptoOperation(false); + mShareAfterEncrypt = false; + cryptoOperation(); } return; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java index e206169bb..a58ac8e87 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java @@ -18,11 +18,8 @@ package org.sufficientlysecure.keychain.ui; import android.app.Activity; -import android.app.ProgressDialog; import android.content.Intent; import android.os.Bundle; -import android.os.Message; -import android.os.Messenger; import android.text.Editable; import android.text.TextWatcher; import android.view.LayoutInflater; @@ -33,6 +30,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.TextView; +import de.greenrobot.event.EventBus; import org.spongycastle.bcpg.CompressionAlgorithmTags; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; @@ -41,9 +39,6 @@ import org.sufficientlysecure.keychain.operations.results.SignEncryptResult; import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.pgp.PgpConstants; import org.sufficientlysecure.keychain.pgp.SignEncryptParcel; -import org.sufficientlysecure.keychain.service.KeychainService; -import org.sufficientlysecure.keychain.service.ServiceProgressHandler; -import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.ui.base.CachingCryptoOperationFragment; import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.ui.util.Notify.ActionListener; @@ -55,7 +50,8 @@ import org.sufficientlysecure.keychain.util.ShareHelper; import java.util.HashSet; import java.util.Set; -public class EncryptTextFragment extends CachingCryptoOperationFragment { +public class EncryptTextFragment + extends CachingCryptoOperationFragment { public static final String ARG_TEXT = "text"; public static final String ARG_USE_COMPRESSION = "use_compression"; @@ -145,6 +141,7 @@ public class EncryptTextFragment extends CachingCryptoOperationFragment extends CryptoOperationFragment { +public abstract class CachingCryptoOperationFragment + extends CryptoOperationFragment { public static final String ARG_CACHED_ACTIONS = "cached_actions"; private T mCachedActionsParcel; - @Override - protected void cryptoOperation(CryptoInputParcel cryptoInput) { - cryptoOperation(cryptoInput, mCachedActionsParcel); - } - @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); @@ -37,21 +38,44 @@ public abstract class CachingCryptoOperationFragment exte } @Override - public boolean handlePendingMessage(Message message) { - // see if it's an InputPendingResult, and if so don't care - if (super.handlePendingMessage(message)) { - return true; - } - - // if it's a non-input-pending OKAY message, always clear the cached actions parcel - if (message.arg1 == ServiceProgressHandler.MessageStatus.OKAY.ordinal()) { - mCachedActionsParcel = null; - } - - return false; + protected void onCryptoOperationResult(S result) { + super.onCryptoOperationResult(result); + mCachedActionsParcel = null; } - protected abstract void cryptoOperation(CryptoInputParcel cryptoInput, T cachedActionsParcel); + protected abstract T createOperationInput(); + + protected void cryptoOperation(CryptoInputParcel cryptoInput) { + + if (mCachedActionsParcel == null) { + + mCachedActionsParcel = createOperationInput(); + // this is null if invalid, just return in that case + if (mCachedActionsParcel == null) { + // Notify was created by createCryptoInput. + return; + } + } + + // Send all information needed to service to edit key in other thread + Intent intent = new Intent(getActivity(), KeychainNewService.class); + + intent.putExtra(KeychainNewService.EXTRA_OPERATION_INPUT, mCachedActionsParcel); + intent.putExtra(KeychainNewService.EXTRA_CRYPTO_INPUT, cryptoInput); + + showProgressFragment( + getString(R.string.progress_start), + ProgressDialog.STYLE_HORIZONTAL, + false); + + // start service with intent + getActivity().startService(intent); + + } + + protected T getCachedActionsParcel() { + return mCachedActionsParcel; + } protected void cacheActionsParcel(T cachedActionsParcel) { mCachedActionsParcel = cachedActionsParcel; 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 7fc5eb1f4..407904369 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 @@ -19,28 +19,46 @@ package org.sufficientlysecure.keychain.ui.base; import android.app.Activity; +import android.app.ProgressDialog; import android.content.Intent; -import android.os.Bundle; -import android.os.Message; +import android.os.Parcelable; import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import de.greenrobot.event.EventBus; +import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.operations.results.InputPendingResult; import org.sufficientlysecure.keychain.operations.results.OperationResult; -import org.sufficientlysecure.keychain.service.ServiceProgressHandler; +import org.sufficientlysecure.keychain.service.KeychainNewService; +import org.sufficientlysecure.keychain.service.ProgressEvent; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.ui.NfcOperationActivity; import org.sufficientlysecure.keychain.ui.PassphraseDialogActivity; +import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment; /** * All fragments executing crypto operations need to extend this class. */ -public abstract class CryptoOperationFragment extends Fragment { +public abstract class CryptoOperationFragment + extends Fragment { public static final int REQUEST_CODE_PASSPHRASE = 0x00008001; public static final int REQUEST_CODE_NFC = 0x00008002; + @Override + public void onStart() { + super.onStart(); + EventBus.getDefault().register(this); + } + + @Override + public void onStop() { + EventBus.getDefault().unregister(this); + super.onStop(); + } + private void initiateInputActivity(RequiredInputParcel requiredInput) { switch (requiredInput.mType) { @@ -99,35 +117,118 @@ public abstract class CryptoOperationFragment extends Fragment { } } - public boolean handlePendingMessage(Message message) { + protected void dismissProgress() { - if (message.arg1 == ServiceProgressHandler.MessageStatus.OKAY.ordinal()) { - Bundle data = message.getData(); + ProgressDialogFragment progressDialogFragment = + (ProgressDialogFragment) getFragmentManager().findFragmentByTag("progressDialog"); - OperationResult result = data.getParcelable(OperationResult.EXTRA_RESULT); - if (result == null || !(result instanceof InputPendingResult)) { - return false; - } - - InputPendingResult pendingResult = (InputPendingResult) result; - if (pendingResult.isPending()) { - RequiredInputParcel requiredInput = pendingResult.getRequiredInputParcel(); - initiateInputActivity(requiredInput); - return true; - } + if (progressDialogFragment == null) { + return; } - return false; + progressDialogFragment.dismissAllowingStateLoss(); + + } + + public void showProgressFragment(String progressDialogMessage, + int progressDialogStyle, + boolean cancelable) { + + if (getFragmentManager().findFragmentByTag("progressDialog") != null) { + return; + } + + ProgressDialogFragment progressDialogFragment = ProgressDialogFragment.newInstance( + progressDialogMessage, progressDialogStyle, cancelable); + + FragmentManager manager = getFragmentManager(); + progressDialogFragment.show(manager, "progressDialog"); + + } + + protected abstract T createOperationInput(); + + protected void cryptoOperation(CryptoInputParcel cryptoInput) { + + T operationInput = createOperationInput(); + if (operationInput == null) { + return; + } + + // Send all information needed to service to edit key in other thread + Intent intent = new Intent(getActivity(), KeychainNewService.class); + + intent.putExtra(KeychainNewService.EXTRA_OPERATION_INPUT, operationInput); + intent.putExtra(KeychainNewService.EXTRA_CRYPTO_INPUT, cryptoInput); + + showProgressFragment( + getString(R.string.progress_start), + ProgressDialog.STYLE_HORIZONTAL, + false); + + // start service with intent + getActivity().startService(intent); + } protected void cryptoOperation() { cryptoOperation(new CryptoInputParcel()); } - protected abstract void cryptoOperation(CryptoInputParcel cryptoInput); - - protected void onCryptoOperationCancelled() { - // Nothing to do here, in most cases + protected void onCryptoOperationResult(S result) { + if (result.success()) { + onCryptoOperationSuccess(result); + } else { + onCryptoOperationError(result); + } } + abstract protected void onCryptoOperationSuccess(S result); + + protected void onCryptoOperationError(S result) { + result.createNotify(getActivity()).show(this); + } + + protected void onCryptoOperationCancelled() { + dismissProgress(); + } + + @SuppressWarnings("unused") // it's an EventBus method + public void onEventMainThread(OperationResult result) { + + if (result instanceof InputPendingResult) { + InputPendingResult pendingResult = (InputPendingResult) result; + if (pendingResult.isPending()) { + RequiredInputParcel requiredInput = pendingResult.getRequiredInputParcel(); + initiateInputActivity(requiredInput); + return; + } + } + + dismissProgress(); + + try { + // noinspection unchecked, because type erasure :( + onCryptoOperationResult((S) result); + } catch (ClassCastException e) { + throw new AssertionError("bad return class (" + + result.getClass().getSimpleName() + "), this is a programming error!"); + } + + } + + @SuppressWarnings("unused") // it's an EventBus method + public void onEventMainThread(ProgressEvent event) { + + ProgressDialogFragment progressDialogFragment = + (ProgressDialogFragment) getFragmentManager().findFragmentByTag("progressDialog"); + + if (progressDialogFragment == null) { + return; + } + + progressDialogFragment.setProgress(event.mMessage, event.mProgress, event.mMax); + } + + } diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 7323d19cd..ba2ae002e 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -341,6 +341,7 @@ "exporting keys…" + "preparing operation…" "extracting signature key…" "extracting key…" "preparing streams…"