From fd32537407f865cc1074b7122e2c89381f9d75c9 Mon Sep 17 00:00:00 2001 From: Dominik Date: Wed, 5 Sep 2012 22:35:55 +0200 Subject: [PATCH] dialog for setting passphrase is now in a fragment --- README.md | 5 + .../org/thialfihar/android/apg/Constants.java | 2 + .../android/apg/service/ApgService.java | 2 +- .../android/apg/ui/DecryptActivity.java | 17 -- .../android/apg/ui/EditKeyActivity.java | 163 +++++++++++------- .../dialog/SetPassphraseDialogFragment.java | 153 ++++++++++++++++ .../android/apg/ui/widget/SectionView.java | 1 + 7 files changed, 261 insertions(+), 82 deletions(-) create mode 100644 org_apg/src/org/thialfihar/android/apg/ui/dialog/SetPassphraseDialogFragment.java diff --git a/README.md b/README.md index e8d08a0f3..6db2e1444 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,11 @@ see https://github.com/rtyley/spongycastle # Notes +## Eclipse: "GC overhead limit exceeded" + +If you have problems starting APG from Eclipse, consider increasing the memory limits in eclipse.ini. +See http://docs.oseems.com/general/application/eclipse/fix-gc-overhead-limit-exceeded for more information. + ## Generate pressed dashboard icons 1. Open svg file in Inkscape diff --git a/org_apg/src/org/thialfihar/android/apg/Constants.java b/org_apg/src/org/thialfihar/android/apg/Constants.java index 16d3ddf90..c0ae2794e 100644 --- a/org_apg/src/org/thialfihar/android/apg/Constants.java +++ b/org_apg/src/org/thialfihar/android/apg/Constants.java @@ -29,6 +29,8 @@ public final class Constants { /* * TODO: * + * this would require patching K9Mail + * * better naming scheme would be: * * - x.action.DECRYPT (with action as preferred in Android) diff --git a/org_apg/src/org/thialfihar/android/apg/service/ApgService.java b/org_apg/src/org/thialfihar/android/apg/service/ApgService.java index f8b05bad3..59b7d038d 100644 --- a/org_apg/src/org/thialfihar/android/apg/service/ApgService.java +++ b/org_apg/src/org/thialfihar/android/apg/service/ApgService.java @@ -67,7 +67,7 @@ public class ApgService extends IntentService implements ProgressDialogUpdater { /* keys for data bundle */ // encrypt and decrypt - public static final String TARGET = "type"; + public static final String TARGET = "target"; // possible targets: public static final int TARGET_BYTES = 1; public static final int TARGET_FILE = 2; diff --git a/org_apg/src/org/thialfihar/android/apg/ui/DecryptActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/DecryptActivity.java index 75bc04dee..c3380962c 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/DecryptActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/DecryptActivity.java @@ -525,7 +525,6 @@ public class DecryptActivity extends SherlockFragmentActivity { // if we need a symmetric passphrase or a passphrase to use a sekret key ask for it if (getSecretKeyId() == Id.key.symmetric || PGPMain.getCachedPassPhrase(getSecretKeyId()) == null) { - // showDialog(Id.dialog.pass_phrase); showPassphraseDialog(); } else { if (mDecryptTarget == Id.target.file) { @@ -1019,22 +1018,6 @@ public class DecryptActivity extends SherlockFragmentActivity { @Override protected Dialog onCreateDialog(int id) { switch (id) { - // case Id.dialog.output_filename: { - // return FileDialog.build(this, getString(R.string.title_decryptToFile), - // getString(R.string.specifyFileToDecryptTo), mOutputFilename, - // new FileDialog.OnClickListener() { - // public void onOkClick(String filename, boolean checked) { - // removeDialog(Id.dialog.output_filename); - // mOutputFilename = filename; - // decryptStart(); - // } - // - // public void onCancelClick() { - // removeDialog(Id.dialog.output_filename); - // } - // }, getString(R.string.filemanager_titleSave), - // getString(R.string.filemanager_btnSave), null, Id.request.output_filename); - // } case Id.dialog.lookup_unknown_key: { AlertDialog.Builder alert = new AlertDialog.Builder(this); diff --git a/org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java index b9270e22f..c151da07c 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java @@ -27,6 +27,7 @@ import org.thialfihar.android.apg.helper.PGPConversionHelper; import org.thialfihar.android.apg.service.ApgHandler; import org.thialfihar.android.apg.service.ApgService; import org.thialfihar.android.apg.ui.dialog.ProgressDialogFragment; +import org.thialfihar.android.apg.ui.dialog.SetPassphraseDialogFragment; import org.thialfihar.android.apg.ui.widget.KeyEditor; import org.thialfihar.android.apg.ui.widget.SectionView; import org.thialfihar.android.apg.ui.widget.UserIdEditor; @@ -38,13 +39,11 @@ import com.actionbarsherlock.app.SherlockFragmentActivity; import com.actionbarsherlock.view.Menu; import com.actionbarsherlock.view.MenuItem; -import android.app.AlertDialog; -import android.app.Dialog; import android.app.ProgressDialog; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; +import android.os.Handler; import android.os.Message; import android.os.Messenger; import org.thialfihar.android.apg.util.Log; @@ -55,7 +54,6 @@ import android.view.View.OnClickListener; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; -import android.widget.EditText; import android.widget.LinearLayout; import android.widget.Toast; import android.widget.CompoundButton.OnCheckedChangeListener; @@ -227,11 +225,13 @@ public class EditKeyActivity extends SherlockFragmentActivity { .getByteArray(ApgService.RESULT_NEW_KEY2)); // add master key + @SuppressWarnings("unchecked") Iterator masterIt = masterKeyRing.getSecretKeys(); mKeys.add(masterIt.next()); mKeysUsages.add(Id.choice.usage.sign_only); // add sub key + @SuppressWarnings("unchecked") Iterator subIt = subKeyRing.getSecretKeys(); subIt.next(); // masterkey mKeys.add(subIt.next()); @@ -296,7 +296,7 @@ public class EditKeyActivity extends SherlockFragmentActivity { mChangePassPhrase.setOnClickListener(new OnClickListener() { public void onClick(View v) { - showDialog(Id.dialog.new_pass_phrase); + showSetPassphraseDialog(); } }); @@ -321,6 +321,43 @@ public class EditKeyActivity extends SherlockFragmentActivity { } } + /** + * Shows the dialog to set a new passphrase + */ + private void showSetPassphraseDialog() { + // Message is received after passphrase is cached + Handler returnHandler = new Handler() { + @Override + public void handleMessage(Message message) { + if (message.what == SetPassphraseDialogFragment.MESSAGE_OKAY) { + Bundle data = message.getData(); + + // set new returned passphrase! + mNewPassPhrase = data + .getString(SetPassphraseDialogFragment.MESSAGE_NEW_PASSPHRASE); + + updatePassPhraseButtonText(); + } + } + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(returnHandler); + + // set title based on isPassphraseSet() + int title = -1; + if (isPassphraseSet()) { + title = R.string.title_changePassPhrase; + } else { + title = R.string.title_setPassPhrase; + } + + SetPassphraseDialogFragment setPassphraseDialog = SetPassphraseDialogFragment.newInstance( + messenger, title); + + setPassphraseDialog.show(getSupportFragmentManager(), "setPassphraseDialog"); + } + /** * Build layout based on mUserId, mKeys and mKeysUsages Vectors. It creates Views for every user * id and key. @@ -360,64 +397,63 @@ public class EditKeyActivity extends SherlockFragmentActivity { } } - @Override - protected Dialog onCreateDialog(int id) { - switch (id) { - case Id.dialog.new_pass_phrase: { - AlertDialog.Builder alert = new AlertDialog.Builder(this); - - if (isPassphraseSet()) { - alert.setTitle(R.string.title_changePassPhrase); - } else { - alert.setTitle(R.string.title_setPassPhrase); - } - alert.setMessage(R.string.enterPassPhraseTwice); - - LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); - View view = inflater.inflate(R.layout.passphrase, null); - final EditText input1 = (EditText) view.findViewById(R.id.passphrase_passphrase); - final EditText input2 = (EditText) view.findViewById(R.id.passphrase_passphrase_again); - - alert.setView(view); - - alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - removeDialog(Id.dialog.new_pass_phrase); - - String passPhrase1 = "" + input1.getText(); - String passPhrase2 = "" + input2.getText(); - if (!passPhrase1.equals(passPhrase2)) { - showDialog(Id.dialog.pass_phrases_do_not_match); - return; - } - - if (passPhrase1.equals("")) { - showDialog(Id.dialog.no_pass_phrase); - return; - } - - mNewPassPhrase = passPhrase1; - updatePassPhraseButtonText(); - } - }); - - alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - removeDialog(Id.dialog.new_pass_phrase); - } - }); - - return alert.create(); - } - - default: { - return super.onCreateDialog(id); - } - } - } + // @Override + // protected Dialog onCreateDialog(int id) { + // switch (id) { + // case Id.dialog.new_pass_phrase: { + // AlertDialog.Builder alert = new AlertDialog.Builder(this); + // + // if (isPassphraseSet()) { + // alert.setTitle(R.string.title_changePassPhrase); + // } else { + // alert.setTitle(R.string.title_setPassPhrase); + // } + // alert.setMessage(R.string.enterPassPhraseTwice); + // + // LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); + // View view = inflater.inflate(R.layout.passphrase, null); + // final EditText input1 = (EditText) view.findViewById(R.id.passphrase_passphrase); + // final EditText input2 = (EditText) view.findViewById(R.id.passphrase_passphrase_again); + // + // alert.setView(view); + // + // alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + // public void onClick(DialogInterface dialog, int id) { + // removeDialog(Id.dialog.new_pass_phrase); + // + // String passPhrase1 = "" + input1.getText(); + // String passPhrase2 = "" + input2.getText(); + // if (!passPhrase1.equals(passPhrase2)) { + // showDialog(Id.dialog.pass_phrases_do_not_match); + // return; + // } + // + // if (passPhrase1.equals("")) { + // showDialog(Id.dialog.no_pass_phrase); + // return; + // } + // + // mNewPassPhrase = passPhrase1; + // updatePassPhraseButtonText(); + // } + // }); + // + // alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { + // public void onClick(DialogInterface dialog, int id) { + // removeDialog(Id.dialog.new_pass_phrase); + // } + // }); + // + // return alert.create(); + // } + // + // default: { + // return super.onCreateDialog(id); + // } + // } + // } private void saveClicked() { - try { if (!isPassphraseSet()) { throw new PGPMain.GeneralException(this.getString(R.string.setAPassPhrase)); @@ -460,7 +496,7 @@ public class EditKeyActivity extends SherlockFragmentActivity { Messenger messenger = new Messenger(saveHandler); intent.putExtra(ApgService.EXTRA_MESSENGER, messenger); - mSavingDialog.show(getSupportFragmentManager(), "dialog"); + mSavingDialog.show(getSupportFragmentManager(), "savingDialog"); // start service with intent startService(intent); @@ -488,8 +524,7 @@ public class EditKeyActivity extends SherlockFragmentActivity { try { userId = editor.getValue(); } catch (UserIdEditor.NoNameException e) { - throw new PGPMain.GeneralException( - this.getString(R.string.error_userIdNeedsAName)); + throw new PGPMain.GeneralException(this.getString(R.string.error_userIdNeedsAName)); } catch (UserIdEditor.NoEmailException e) { throw new PGPMain.GeneralException( this.getString(R.string.error_userIdNeedsAnEmailAddress)); diff --git a/org_apg/src/org/thialfihar/android/apg/ui/dialog/SetPassphraseDialogFragment.java b/org_apg/src/org/thialfihar/android/apg/ui/dialog/SetPassphraseDialogFragment.java new file mode 100644 index 000000000..5bd5342dd --- /dev/null +++ b/org_apg/src/org/thialfihar/android/apg/ui/dialog/SetPassphraseDialogFragment.java @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2012 Dominik Schürmann + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.thialfihar.android.apg.ui.dialog; + +import org.thialfihar.android.apg.Constants; +import org.thialfihar.android.apg.R; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; +import android.os.Bundle; +import android.os.Message; +import android.os.Messenger; +import android.os.RemoteException; +import android.support.v4.app.DialogFragment; +import org.thialfihar.android.apg.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.EditText; +import android.widget.Toast; + +public class SetPassphraseDialogFragment extends DialogFragment { + private Messenger mMessenger; + + private static final String ARG_MESSENGER = "messenger"; + private static final String ARG_TITLE = "title"; + + public static final int MESSAGE_OKAY = 1; + + public static final String MESSAGE_NEW_PASSPHRASE = "new_passphrase"; + + /** + * Creates new instance of this dialog fragment + * + * @param title + * title of dialog + * @param messenger + * to communicate back after setting the passphrase + * @return + */ + public static SetPassphraseDialogFragment newInstance(Messenger messenger, int title) { + SetPassphraseDialogFragment frag = new SetPassphraseDialogFragment(); + Bundle args = new Bundle(); + args.putInt(ARG_TITLE, title); + args.putParcelable(ARG_MESSENGER, messenger); + + frag.setArguments(args); + + return frag; + } + + /** + * Creates dialog + */ + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + final Activity activity = getActivity(); + + int title = getArguments().getInt(ARG_TITLE); + mMessenger = getArguments().getParcelable(ARG_MESSENGER); + + AlertDialog.Builder alert = new AlertDialog.Builder(activity); + + alert.setTitle(title); + alert.setMessage(R.string.enterPassPhraseTwice); + + LayoutInflater inflater = (LayoutInflater) activity + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + View view = inflater.inflate(R.layout.passphrase, null); + final EditText input1 = (EditText) view.findViewById(R.id.passphrase_passphrase); + final EditText input2 = (EditText) view.findViewById(R.id.passphrase_passphrase_again); + + alert.setView(view); + + alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + dismiss(); + + String passPhrase1 = input1.getText().toString(); + String passPhrase2 = input2.getText().toString(); + if (!passPhrase1.equals(passPhrase2)) { + Toast.makeText( + activity, + getString(R.string.errorMessage, + getString(R.string.passPhrasesDoNotMatch)), Toast.LENGTH_SHORT) + .show(); + return; + } + + if (passPhrase1.equals("")) { + Toast.makeText( + activity, + getString(R.string.errorMessage, + getString(R.string.passPhraseMustNotBeEmpty)), + Toast.LENGTH_SHORT).show(); + return; + } + + // return resulting data back to activity + Bundle data = new Bundle(); + data.putString(MESSAGE_NEW_PASSPHRASE, passPhrase1); + + sendMessageToHandler(MESSAGE_OKAY, data); + } + }); + + alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + dismiss(); + } + }); + + return alert.create(); + } + + /** + * 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); + } + } +} \ No newline at end of file diff --git a/org_apg/src/org/thialfihar/android/apg/ui/widget/SectionView.java b/org_apg/src/org/thialfihar/android/apg/ui/widget/SectionView.java index 4bedd1ede..6fc8d8425 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/widget/SectionView.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/widget/SectionView.java @@ -292,6 +292,7 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor // take only the key from this ring PGPSecretKey newKey = null; + @SuppressWarnings("unchecked") Iterator it = newKeyRing.getSecretKeys(); if (isMasterKey) {