From 94e7bbb67bbebd2e4cff66991a8fa98ad12adfb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 25 Oct 2014 22:56:27 +0200 Subject: [PATCH] Remove PassphraseDialogFragment --- .../keychain/ui/MultiCertifyKeyFragment.java | 6 +- .../ui/dialog/PassphraseDialogFragment.java | 431 ------------------ 2 files changed, 2 insertions(+), 435 deletions(-) delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MultiCertifyKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MultiCertifyKeyFragment.java index cf757ff94..d2a3e632c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MultiCertifyKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MultiCertifyKeyFragment.java @@ -26,7 +26,6 @@ import android.database.MatrixCursor; import android.graphics.PorterDuff; import android.net.Uri; import android.os.Bundle; -import android.os.Handler; import android.os.Message; import android.os.Messenger; import android.os.Parcel; @@ -44,6 +43,8 @@ import android.widget.ListView; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.operations.results.CertifyResult; +import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing; @@ -55,10 +56,7 @@ import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyActio import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; import org.sufficientlysecure.keychain.service.PassphraseCacheService; -import org.sufficientlysecure.keychain.operations.results.CertifyResult; -import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.ui.adapter.MultiUserIdsAdapter; -import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.ui.widget.CertifyKeySpinner; import org.sufficientlysecure.keychain.ui.widget.KeySpinner; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java deleted file mode 100644 index 40ee8e0e9..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Copyright (C) 2012-2014 Dominik Schürmann - * - * 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.ui.dialog; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Dialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; -import android.os.AsyncTask; -import android.os.Bundle; -import android.os.Handler; -import android.os.Message; -import android.os.Messenger; -import android.os.RemoteException; -import android.support.v4.app.DialogFragment; -import android.support.v4.app.FragmentActivity; -import android.text.InputType; -import android.text.method.PasswordTransformationMethod; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.View; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputMethodManager; -import android.widget.Button; -import android.widget.EditText; -import android.widget.TextView; -import android.widget.TextView.OnEditorActionListener; -import android.widget.Toast; - -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround; -import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey; -import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing; -import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; -import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; -import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing; -import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; -import org.sufficientlysecure.keychain.provider.ProviderHelper; -import org.sufficientlysecure.keychain.service.PassphraseCacheService; -import org.sufficientlysecure.keychain.util.Log; -import org.sufficientlysecure.keychain.util.Preferences; - -public class PassphraseDialogFragment extends DialogFragment implements OnEditorActionListener { - private static final String ARG_MESSENGER = "messenger"; - private static final String ARG_SECRET_KEY_ID = "secret_key_id"; - - public static final int MESSAGE_OKAY = 1; - public static final int MESSAGE_CANCEL = 2; - - public static final String MESSAGE_DATA_PASSPHRASE = "passphrase"; - - private Messenger mMessenger; - private EditText mPassphraseEditText; - private View mInput, mProgress; - - /** - * Shows passphrase dialog to cache a new passphrase the user enters for using it later for - * encryption. Based on mSecretKeyId it asks for a passphrase to open a private key or it asks - * for a symmetric passphrase - */ - public static void show(final FragmentActivity context, final long keyId, final Handler returnHandler) { - // Create a new Messenger for the communication back - final Messenger messenger = new Messenger(returnHandler); - - DialogFragmentWorkaround.INTERFACE.runnableRunDelayed(new Runnable() { - public void run() { - try { - PassphraseDialogFragment passphraseDialog = - PassphraseDialogFragment.newInstance(messenger, keyId); - - passphraseDialog.show(context.getSupportFragmentManager(), "passphraseDialog"); - } catch (PgpGeneralException e) { - Log.d(Constants.TAG, "No passphrase for this secret key!"); - // send message to handler to start encryption directly - returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY); - } - } - }); - } - - /** - * Creates new instance of this dialog fragment - * - * @param secretKeyId secret key id you want to use - * @param messenger to communicate back after caching the passphrase - * @return - * @throws PgpGeneralException - */ - public static PassphraseDialogFragment newInstance(Messenger messenger, long secretKeyId) - throws PgpGeneralException { - // do NOT check if the key even needs a passphrase. that's not our job here. - PassphraseDialogFragment frag = new PassphraseDialogFragment(); - Bundle args = new Bundle(); - args.putLong(ARG_SECRET_KEY_ID, secretKeyId); - args.putParcelable(ARG_MESSENGER, messenger); - - frag.setArguments(args); - - return frag; - } - - CanonicalizedSecretKeyRing mSecretRing = null; - boolean mIsCancelled = false; - long mSubKeyId; - - /** - * Creates dialog - */ - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - final Activity activity = getActivity(); - mSubKeyId = getArguments().getLong(ARG_SECRET_KEY_ID); - mMessenger = getArguments().getParcelable(ARG_MESSENGER); - - CustomAlertDialogBuilder alert = new CustomAlertDialogBuilder(activity); - - alert.setTitle(R.string.title_authentication); - - String userId; - CanonicalizedSecretKey.SecretKeyType keyType = CanonicalizedSecretKey.SecretKeyType.PASSPHRASE; - - if (mSubKeyId == Constants.key.symmetric || mSubKeyId == Constants.key.none) { - alert.setMessage(R.string.passphrase_for_symmetric_encryption); - } else { - String message; - try { - ProviderHelper helper = new ProviderHelper(activity); - mSecretRing = helper.getCanonicalizedSecretKeyRing( - KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(mSubKeyId)); - // yes the inner try/catch block is necessary, otherwise the final variable - // above can't be statically verified to have been set in all cases because - // the catch clause doesn't return. - try { - userId = mSecretRing.getPrimaryUserIdWithFallback(); - } catch (PgpKeyNotFoundException e) { - userId = null; - } - - /* Get key type for message */ - // find a master key id for our key - long masterKeyId = new ProviderHelper(getActivity()).getMasterKeyId(mSubKeyId); - CachedPublicKeyRing keyRing = new ProviderHelper(getActivity()).getCachedPublicKeyRing(masterKeyId); - // get the type of key (from the database) - keyType = keyRing.getSecretKeyType(mSubKeyId); - switch (keyType) { - case PASSPHRASE: - message = getString(R.string.passphrase_for, userId); - break; - case DIVERT_TO_CARD: - message = getString(R.string.yubikey_pin, userId); - break; - default: - message = "This should not happen!"; - break; - } - - } catch (ProviderHelper.NotFoundException e) { - alert.setTitle(R.string.title_key_not_found); - alert.setMessage(getString(R.string.key_not_found, mSubKeyId)); - alert.setPositiveButton(android.R.string.ok, new OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - dismiss(); - } - }); - alert.setCancelable(false); - return alert.create(); - } - - alert.setMessage(message); - } - - LayoutInflater inflater = activity.getLayoutInflater(); - View view = inflater.inflate(R.layout.passphrase_dialog, null); - alert.setView(view); - - mPassphraseEditText = (EditText) view.findViewById(R.id.passphrase_passphrase); - mInput = view.findViewById(R.id.input); - mProgress = view.findViewById(R.id.progress); - - alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int id) { - dialog.cancel(); - } - }); - - // Hack to open keyboard. - // This is the only method that I found to work across all Android versions - // http://turbomanage.wordpress.com/2012/05/02/show-soft-keyboard-automatically-when-edittext-receives-focus/ - // Notes: * onCreateView can't be used because we want to add buttons to the dialog - // * opening in onActivityCreated does not work on Android 4.4 - mPassphraseEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() { - @Override - public void onFocusChange(View v, boolean hasFocus) { - mPassphraseEditText.post(new Runnable() { - @Override - public void run() { - // The activity might already be gone! Nvm in that case. - if (getActivity() == null) { - return; - } - InputMethodManager imm = (InputMethodManager) getActivity() - .getSystemService(Context.INPUT_METHOD_SERVICE); - imm.showSoftInput(mPassphraseEditText, InputMethodManager.SHOW_IMPLICIT); - } - }); - } - }); - mPassphraseEditText.requestFocus(); - - mPassphraseEditText.setImeActionLabel(getString(android.R.string.ok), EditorInfo.IME_ACTION_DONE); - mPassphraseEditText.setOnEditorActionListener(this); - - if (keyType == CanonicalizedSecretKey.SecretKeyType.DIVERT_TO_CARD && Preferences.getPreferences(activity).useNumKeypadForYubikeyPin()) { - mPassphraseEditText.setRawInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_TEXT_VARIATION_PASSWORD); - } else { - mPassphraseEditText.setRawInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); - } - mPassphraseEditText.setTransformationMethod(PasswordTransformationMethod.getInstance()); - - AlertDialog dialog = alert.create(); - dialog.setButton(DialogInterface.BUTTON_POSITIVE, - activity.getString(android.R.string.ok), (DialogInterface.OnClickListener) null); - - return dialog; - } - - @Override - public void onStart() { - super.onStart(); - - // Override the default behavior so the dialog is NOT dismissed on click - final Button positive = ((AlertDialog) getDialog()).getButton(DialogInterface.BUTTON_POSITIVE); - positive.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - final String passphrase = mPassphraseEditText.getText().toString(); - - // Early breakout if we are dealing with a symmetric key - if (mSecretRing == null) { - PassphraseCacheService.addCachedPassphrase(getActivity(), Constants.key.symmetric, - Constants.key.symmetric, passphrase, getString(R.string.passp_cache_notif_pwd)); - // also return passphrase back to activity - Bundle data = new Bundle(); - data.putString(MESSAGE_DATA_PASSPHRASE, passphrase); - sendMessageToHandler(MESSAGE_OKAY, data); - dismiss(); - return; - } - - mInput.setVisibility(View.GONE); - mProgress.setVisibility(View.VISIBLE); - positive.setEnabled(false); - - new AsyncTask() { - @Override - protected Boolean doInBackground(Void... params) { - try { - // wait some 100ms here, give the user time to appreciate the progress bar - try { - Thread.sleep(100); - } catch (InterruptedException e) { - // never mind - } - // make sure this unlocks - return mSecretRing.getSecretKey(mSubKeyId).unlock(passphrase); - } catch (PgpGeneralException e) { - Toast.makeText(getActivity(), R.string.error_could_not_extract_private_key, - Toast.LENGTH_SHORT).show(); - - sendMessageToHandler(MESSAGE_CANCEL); - dismiss(); - return false; - } - } - - /** Handle a good or bad passphrase. This happens in the UI thread! */ - @Override - protected void onPostExecute(Boolean result) { - super.onPostExecute(result); - - // if we were cancelled in the meantime, the result isn't relevant anymore - if (mIsCancelled) { - return; - } - - // if the passphrase was wrong, reset and re-enable the dialogue - if (!result) { - mPassphraseEditText.setText(""); - mPassphraseEditText.setError(getString(R.string.wrong_passphrase)); - mInput.setVisibility(View.VISIBLE); - mProgress.setVisibility(View.GONE); - positive.setEnabled(true); - return; - } - - // cache the new passphrase - Log.d(Constants.TAG, "Everything okay! Caching entered passphrase"); - - try { - PassphraseCacheService.addCachedPassphrase(getActivity(), - mSecretRing.getMasterKeyId(), mSubKeyId, passphrase, - mSecretRing.getPrimaryUserIdWithFallback()); - } catch (PgpKeyNotFoundException e) { - Log.e(Constants.TAG, "adding of a passphrase failed", e); - } - - // also return passphrase back to activity - Bundle data = new Bundle(); - data.putString(MESSAGE_DATA_PASSPHRASE, passphrase); - sendMessageToHandler(MESSAGE_OKAY, data); - dismiss(); - } - }.execute(); - } - }); - - } - - @Override - public void onCancel(DialogInterface dialog) { - super.onCancel(dialog); - - // note we need no synchronization here, this variable is only accessed in the ui thread - mIsCancelled = true; - - // dismiss the dialogue - dismiss(); - sendMessageToHandler(MESSAGE_CANCEL); - } - - @Override - public void onDismiss(DialogInterface dialog) { - super.onDismiss(dialog); - Log.d(Constants.TAG, "onDismiss"); - - // hide keyboard on dismiss - hideKeyboard(); - } - - private void hideKeyboard() { - // The activity which called the dialog might no longer exist. Nvm in that case... - if (getActivity() == null) { - return; - } - InputMethodManager inputManager = (InputMethodManager) getActivity() - .getSystemService(Context.INPUT_METHOD_SERVICE); - - //check if no view has focus: - View v = getActivity().getCurrentFocus(); - if (v == null) { - return; - } - - inputManager.hideSoftInputFromWindow(v.getWindowToken(), 0); - } - - /** - * Associate the "done" button on the soft keyboard with the okay button in the view - */ - @Override - public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { - if (EditorInfo.IME_ACTION_DONE == actionId) { - AlertDialog dialog = ((AlertDialog) getDialog()); - Button bt = dialog.getButton(AlertDialog.BUTTON_POSITIVE); - - bt.performClick(); - return true; - } - return false; - } - - /** - * Send message back to handler which is initialized in a activity - * - * @param what Message integer you want to send - */ - private void sendMessageToHandler(Integer what) { - Message msg = Message.obtain(); - msg.what = what; - - try { - mMessenger.send(msg); - } catch (RemoteException e) { - Log.w(Constants.TAG, "Exception sending message, Is handler present?", e); - } catch (NullPointerException e) { - Log.w(Constants.TAG, "Messenger is null!", e); - } - } - - /** - * Send message back to handler which is initialized in a activity - * - * @param what Message integer you want to send - */ - private void sendMessageToHandler(Integer what, Bundle data) { - Message msg = Message.obtain(); - msg.what = what; - if (data != null) { - msg.setData(data); - } - - try { - mMessenger.send(msg); - } catch (RemoteException e) { - Log.w(Constants.TAG, "Exception sending message, Is handler present?", e); - } catch (NullPointerException e) { - Log.w(Constants.TAG, "Messenger is null!", e); - } - } - -}