diff options
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java')
-rw-r--r-- | OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java | 118 |
1 files changed, 101 insertions, 17 deletions
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..637a7dcff 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(this); + } 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!"); + } + + } + + } |