diff options
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base')
2 files changed, 111 insertions, 38 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CachingCryptoOperationFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CachingCryptoOperationFragment.java index d0b6f502f..87c6ee3ca 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CachingCryptoOperationFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CachingCryptoOperationFragment.java @@ -2,25 +2,19 @@ package org.sufficientlysecure.keychain.ui.base; import android.os.Bundle; -import android.os.Message; import android.os.Parcelable; -import org.sufficientlysecure.keychain.service.ServiceProgressHandler; -import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; +import org.sufficientlysecure.keychain.operations.results.OperationResult; -public abstract class CachingCryptoOperationFragment <T extends Parcelable> extends CryptoOperationFragment { +public abstract class CachingCryptoOperationFragment <T extends Parcelable, S extends OperationResult> + extends CryptoOperationFragment<T, S> { 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,22 +31,17 @@ public abstract class CachingCryptoOperationFragment <T extends Parcelable> 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; - } + protected void onCryptoOperationResult(S result) { + super.onCryptoOperationResult(result); + mCachedActionsParcel = null; + } - // if it's a non-input-pending OKAY message, always clear the cached actions parcel - if (message.arg1 == ServiceProgressHandler.MessageStatus.OKAY.ordinal()) { - mCachedActionsParcel = null; - } + protected abstract T createOperationInput(); - return false; + protected T getCachedActionsParcel() { + return mCachedActionsParcel; } - protected abstract void cryptoOperation(CryptoInputParcel cryptoInput, T cachedActionsParcel); - 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..2be162e95 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,24 +19,32 @@ 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.Messenger; +import android.os.Parcelable; import android.support.v4.app.Fragment; +import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.operations.results.InputPendingResult; import org.sufficientlysecure.keychain.operations.results.OperationResult; +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; 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 <T extends Parcelable, S extends OperationResult> + extends Fragment { public static final int REQUEST_CODE_PASSPHRASE = 0x00008001; public static final int REQUEST_CODE_NFC = 0x00008002; @@ -99,35 +107,111 @@ 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; - } + if (progressDialogFragment == null) { + return; + } - InputPendingResult pendingResult = (InputPendingResult) result; - if (pendingResult.isPending()) { - RequiredInputParcel requiredInput = pendingResult.getRequiredInputParcel(); - initiateInputActivity(requiredInput); - return true; - } + progressDialogFragment.dismissAllowingStateLoss(); + + } + + protected abstract T createOperationInput(); + + protected void cryptoOperation(CryptoInputParcel cryptoInput) { + + T operationInput = createOperationInput(); + if (operationInput == null) { + return; } - return false; + // 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); + + ServiceProgressHandler saveHandler = new ServiceProgressHandler(getActivity()) { + @Override + public void handleMessage(Message message) { + // handle messages by standard KeychainIntentServiceHandler first + super.handleMessage(message); + + 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); + + onHandleResult(result); + } + } + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(saveHandler); + intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger); + + saveHandler.showProgressDialog( + getString(R.string.progress_building_key), + ProgressDialog.STYLE_HORIZONTAL, false); + + getActivity().startService(intent); + } protected void cryptoOperation() { cryptoOperation(new CryptoInputParcel()); } - protected abstract void cryptoOperation(CryptoInputParcel cryptoInput); + 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(); + } protected void onCryptoOperationCancelled() { - // Nothing to do here, in most cases } + public void onHandleResult(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!"); + } + + } + + } |