diff options
Diffstat (limited to 'src')
16 files changed, 1310 insertions, 1072 deletions
diff --git a/src/org/thialfihar/android/apg/Apg.java b/src/org/thialfihar/android/apg/Apg.java index 26a053921..fd9d29ccc 100644 --- a/src/org/thialfihar/android/apg/Apg.java +++ b/src/org/thialfihar/android/apg/Apg.java @@ -98,6 +98,8 @@ public class Apg { public static class Intent {
public static final String DECRYPT = "org.thialfihar.android.apg.intent.DECRYPT";
public static final String ENCRYPT = "org.thialfihar.android.apg.intent.ENCRYPT";
+ public static final String DECRYPT_FILE = "org.thialfihar.android.apg.intent.DECRYPT_FILE";
+ public static final String ENCRYPT_FILE = "org.thialfihar.android.apg.intent.ENCRYPT_FILE";
}
public static String VERSION = "0.9.0";
@@ -121,8 +123,8 @@ public class Apg { CompressionAlgorithmTags.BZIP2,
CompressionAlgorithmTags.ZIP };
- protected static Vector<PGPPublicKeyRing> mPublicKeyRings;
- protected static Vector<PGPSecretKeyRing> mSecretKeyRings;
+ protected static Vector<PGPPublicKeyRing> mPublicKeyRings = new Vector<PGPPublicKeyRing>();
+ protected static Vector<PGPSecretKeyRing> mSecretKeyRings = new Vector<PGPSecretKeyRing>();
public static Pattern PGP_MESSAGE =
Pattern.compile(".*?(-----BEGIN PGP MESSAGE-----.*?-----END PGP MESSAGE-----).*",
@@ -139,9 +141,6 @@ public class Apg { protected static final int RETURN_OK = 0;
protected static final int RETURN_UPDATED = 1;
- protected static final int TYPE_PUBLIC = 0;
- protected static final int TYPE_SECRET = 1;
-
protected static HashMap<Long, Integer> mSecretKeyIdToIdMap;
protected static HashMap<Long, PGPSecretKeyRing> mSecretKeyIdToKeyRingMap;
protected static HashMap<Long, Integer> mPublicKeyIdToIdMap;
@@ -180,13 +179,12 @@ public class Apg { }
public static void initialize(Activity context) {
- setPassPhrase(null);
if (mInitialized) {
return;
}
- loadKeyRings(context, TYPE_PUBLIC);
- loadKeyRings(context, TYPE_SECRET);
+ loadKeyRings(context, Id.type.public_key);
+ loadKeyRings(context, Id.type.secret_key);
mInitialized = true;
}
@@ -546,8 +544,8 @@ public class Apg { saveKeyRing(context, secretKeyRing);
saveKeyRing(context, publicKeyRing);
- loadKeyRings(context, TYPE_PUBLIC);
- loadKeyRings(context, TYPE_SECRET);
+ loadKeyRings(context, Id.type.public_key);
+ loadKeyRings(context, Id.type.secret_key);
progress.setProgress("done.", 100, 100);
}
@@ -617,7 +615,7 @@ public class Apg { Bundle returnData = new Bundle();
PGPObjectFactory objectFactors = null;
- if (type == TYPE_SECRET) {
+ if (type == Id.type.secret_key) {
progress.setProgress("importing secret keys...", 0, 100);
} else {
progress.setProgress("importing public keys...", 0, 100);
@@ -647,7 +645,7 @@ public class Apg { PGPSecretKeyRing secretKeyRing;
int retValue;
- if (type == TYPE_SECRET) {
+ if (type == Id.type.secret_key) {
if (!(obj instanceof PGPSecretKeyRing)) {
continue;
}
@@ -729,7 +727,7 @@ public class Apg { private static void loadKeyRings(Activity context, int type) {
Cursor cursor;
- if (type == TYPE_SECRET) {
+ if (type == Id.type.secret_key) {
mSecretKeyRings.clear();
mSecretKeyIdToIdMap.clear();
mSecretKeyIdToKeyRingMap.clear();
@@ -757,7 +755,7 @@ public class Apg { long keyId = cursor.getLong(keyIdIndex);
try {
- if (type == TYPE_SECRET) {
+ if (type == Id.type.secret_key) {
PGPSecretKeyRing key = new PGPSecretKeyRing(keyData);
mSecretKeyRings.add(key);
mSecretKeyIdToIdMap.put(keyId, id);
@@ -775,7 +773,7 @@ public class Apg { }
}
- if (type == TYPE_SECRET) {
+ if (type == Id.type.secret_key) {
Collections.sort(mSecretKeyRings, new SecretKeySorter());
} else {
Collections.sort(mPublicKeyRings, new PublicKeySorter());
@@ -1059,14 +1057,14 @@ public class Apg { PGPPublicKey masterKey = getMasterKey(keyRing);
Uri uri = Uri.withAppendedPath(PublicKeys.CONTENT_URI_BY_KEY_ID, "" + masterKey.getKeyID());
context.getContentResolver().delete(uri, null, null);
- loadKeyRings(context, TYPE_PUBLIC);
+ loadKeyRings(context, Id.type.public_key);
}
public static void deleteKey(Activity context, PGPSecretKeyRing keyRing) {
PGPSecretKey masterKey = getMasterKey(keyRing);
Uri uri = Uri.withAppendedPath(SecretKeys.CONTENT_URI_BY_KEY_ID, "" + masterKey.getKeyID());
context.getContentResolver().delete(uri, null, null);
- loadKeyRings(context, TYPE_SECRET);
+ loadKeyRings(context, Id.type.secret_key);
}
public static PGPPublicKey findPublicKey(long keyId) {
diff --git a/src/org/thialfihar/android/apg/AskForSecretKeyPassPhrase.java b/src/org/thialfihar/android/apg/AskForSecretKeyPassPhrase.java index ed1c16833..06e9c6d0a 100644 --- a/src/org/thialfihar/android/apg/AskForSecretKeyPassPhrase.java +++ b/src/org/thialfihar/android/apg/AskForSecretKeyPassPhrase.java @@ -35,8 +35,6 @@ import android.widget.LinearLayout; import android.widget.Toast;
public class AskForSecretKeyPassPhrase {
- public static final int DIALOG_PASS_PHRASE = 12345;
-
public static interface PassPhraseCallbackInterface {
void passPhraseCallback(String passPhrase);
}
@@ -91,7 +89,7 @@ public class AskForSecretKeyPassPhrase { alert.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
- activity.removeDialog(DIALOG_PASS_PHRASE);
+ activity.removeDialog(Id.dialog.pass_phrase);
String passPhrase = "" + input.getText();
try {
secretKey.extractPrivateKey(passPhrase.toCharArray(),
@@ -109,7 +107,7 @@ public class AskForSecretKeyPassPhrase { alert.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
- activity.removeDialog(DIALOG_PASS_PHRASE);
+ activity.removeDialog(Id.dialog.pass_phrase);
}
});
diff --git a/src/org/thialfihar/android/apg/BaseActivity.java b/src/org/thialfihar/android/apg/BaseActivity.java new file mode 100644 index 000000000..09de2ae5a --- /dev/null +++ b/src/org/thialfihar/android/apg/BaseActivity.java @@ -0,0 +1,235 @@ +/*
+ * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
+ *
+ * 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;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.ProgressDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+
+public class BaseActivity extends Activity
+ implements Runnable, ProgressDialogUpdater,
+ AskForSecretKeyPassPhrase.PassPhraseCallbackInterface {
+
+ private ProgressDialog mProgressDialog = null;
+ private Thread mRunningThread = null;
+
+ private long mSecretKeyId = 0;
+
+ private Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ handlerCallback(msg);
+ }
+ };
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ Apg.initialize(this);
+ }
+
+ @Override
+ protected Dialog onCreateDialog(int id) {
+
+ // in case it is a progress dialog
+ mProgressDialog = new ProgressDialog(this);
+ mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
+ mProgressDialog.setCancelable(false);
+ switch (id) {
+ case Id.dialog.encrypting: {
+ mProgressDialog.setMessage("initializing...");
+ return mProgressDialog;
+ }
+
+ case Id.dialog.decrypting: {
+ mProgressDialog.setMessage("initializing...");
+ return mProgressDialog;
+ }
+
+ case Id.dialog.saving: {
+ mProgressDialog.setMessage("saving...");
+ return mProgressDialog;
+ }
+
+ case Id.dialog.importing: {
+ mProgressDialog.setMessage("importing...");
+ return mProgressDialog;
+ }
+
+ case Id.dialog.exporting: {
+ mProgressDialog.setMessage("exporting...");
+ return mProgressDialog;
+ }
+
+ default: {
+ break;
+ }
+ }
+ mProgressDialog = null;
+
+ switch (id) {
+ case Id.dialog.pass_phrase: {
+ return AskForSecretKeyPassPhrase.createDialog(this, getSecretKeyId(), this);
+ }
+
+ case Id.dialog.pass_phrases_do_not_match: {
+ AlertDialog.Builder alert = new AlertDialog.Builder(this);
+
+ alert.setIcon(android.R.drawable.ic_dialog_alert);
+ alert.setTitle("Error");
+ alert.setMessage("The pass phrases didn't match.");
+
+ alert.setPositiveButton(android.R.string.ok,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ removeDialog(Id.dialog.pass_phrases_do_not_match);
+ }
+ });
+ alert.setCancelable(false);
+
+ return alert.create();
+ }
+
+ case Id.dialog.no_pass_phrase: {
+ AlertDialog.Builder alert = new AlertDialog.Builder(this);
+
+ alert.setIcon(android.R.drawable.ic_dialog_alert);
+ alert.setTitle("Error");
+ alert.setMessage("Empty pass phrases are not supported.");
+
+ alert.setPositiveButton(android.R.string.ok,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ removeDialog(Id.dialog.no_pass_phrase);
+ }
+ });
+ alert.setCancelable(false);
+
+ return alert.create();
+ }
+
+
+ default: {
+ break;
+ }
+ }
+
+ return super.onCreateDialog(id);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ switch (requestCode) {
+ default: {
+ break;
+ }
+ }
+
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+
+ @Override
+ public void setProgress(int progress, int max) {
+ Message msg = new Message();
+ Bundle data = new Bundle();
+ data.putInt("type", Id.message.progress_update);
+ data.putInt("progress", progress);
+ data.putInt("max", max);
+ msg.setData(data);
+ mHandler.sendMessage(msg);
+ }
+
+ @Override
+ public void setProgress(String message, int progress, int max) {
+ Message msg = new Message();
+ Bundle data = new Bundle();
+ data.putInt("type", Id.message.progress_update);
+ data.putString("message", message);
+ data.putInt("progress", progress);
+ data.putInt("max", max);
+ msg.setData(data);
+ mHandler.sendMessage(msg);
+ }
+
+ public void handlerCallback(Message msg) {
+ Bundle data = msg.getData();
+ if (data == null) {
+ return;
+ }
+
+ int type = data.getInt("type");
+ switch (type) {
+ case Id.message.progress_update: {
+ String message = data.getString("message");
+ if (mProgressDialog != null) {
+ if (message != null) {
+ mProgressDialog.setMessage(message);
+ }
+ mProgressDialog.setMax(data.getInt("max"));
+ mProgressDialog.setProgress(data.getInt("progress"));
+ }
+ break;
+ }
+
+ case Id.message.import_done: // intentionall no break
+ case Id.message.export_done: // intentionall no break
+ case Id.message.done: {
+ mProgressDialog = null;
+ doneCallback(msg);
+ break;
+ }
+ }
+ }
+
+ public void doneCallback(Message msg) {
+
+ }
+
+ public void passPhraseCallback(String passPhrase) {
+ Log.e("oink", "setting pass phrase to " + passPhrase);
+ Apg.setPassPhrase(passPhrase);
+ }
+
+ public void sendMessage(Message msg) {
+ mHandler.sendMessage(msg);
+ }
+
+ public void startThread() {
+ mRunningThread = new Thread(this);
+ mRunningThread.start();
+ }
+
+ public void run() {
+
+ }
+
+ public void setSecretKeyId(long id) {
+ mSecretKeyId = id;
+ }
+
+ public long getSecretKeyId() {
+ return mSecretKeyId;
+ }
+}
diff --git a/src/org/thialfihar/android/apg/DecryptMessageActivity.java b/src/org/thialfihar/android/apg/DecryptMessageActivity.java index 8b7985c77..fc2c68ba4 100644 --- a/src/org/thialfihar/android/apg/DecryptMessageActivity.java +++ b/src/org/thialfihar/android/apg/DecryptMessageActivity.java @@ -29,13 +29,9 @@ import org.bouncycastle2.jce.provider.BouncyCastleProvider; import org.bouncycastle2.openpgp.PGPException; import org.bouncycastle2.util.Strings; -import android.app.Activity; -import android.app.Dialog; -import android.app.ProgressDialog; import android.content.Intent; import android.net.Uri; import android.os.Bundle; -import android.os.Handler; import android.os.Message; import android.text.ClipboardManager; import android.view.View; @@ -47,27 +43,13 @@ import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; -public class DecryptMessageActivity extends Activity - implements Runnable, ProgressDialogUpdater, - AskForSecretKeyPassPhrase.PassPhraseCallbackInterface { - static final int GET_PUCLIC_KEYS = 1; - static final int GET_SECRET_KEY = 2; - - static final int DIALOG_DECRYPTING = 1; - - static final int MESSAGE_PROGRESS_UPDATE = 1; - static final int MESSAGE_DONE = 2; - - private long mDecryptionKeyId = 0; +public class DecryptMessageActivity extends BaseActivity { private long mSignatureKeyId = 0; private String mReplyTo = null; private String mSubject = null; private boolean mSignedOnly = false; - private ProgressDialog mProgressDialog = null; - private Thread mRunningThread = null; - private EditText mMessage = null; private LinearLayout mSignatureLayout = null; private ImageView mSignatureStatusImage = null; @@ -75,90 +57,11 @@ public class DecryptMessageActivity extends Activity private TextView mUserIdRest = null; private Button mDecryptButton = null; - private Handler mHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - Bundle data = msg.getData(); - if (data != null) { - int type = data.getInt("type"); - switch (type) { - case MESSAGE_PROGRESS_UPDATE: { - String message = data.getString("message"); - if (mProgressDialog != null) { - if (message != null) { - mProgressDialog.setMessage(message); - } - mProgressDialog.setMax(data.getInt("max")); - mProgressDialog.setProgress(data.getInt("progress")); - } - break; - } - - case MESSAGE_DONE: { - removeDialog(DIALOG_DECRYPTING); - mProgressDialog = null; - mSignatureKeyId = 0; - String error = data.getString("error"); - String decryptedMessage = data.getString("decryptedMessage"); - if (error != null) { - Toast.makeText(DecryptMessageActivity.this, - "Error: " + data.getString("error"), - Toast.LENGTH_SHORT).show(); - } - mSignatureLayout.setVisibility(View.INVISIBLE); - if (decryptedMessage != null) { - mMessage.setText(decryptedMessage); - mDecryptButton.setText(R.string.btn_reply); - mDecryptButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - replyClicked(); - } - }); - - if (data.getBoolean("signature")) { - String userId = data.getString("signatureUserId"); - mSignatureKeyId = data.getLong("signatureKeyId"); - mUserIdRest.setText("id: " + - Long.toHexString(mSignatureKeyId & 0xffffffffL)); - if (userId == null) { - userId = - getResources() - .getString( - R.string.unknown_user_id); - } - String chunks[] = userId.split(" <", 2); - userId = chunks[0]; - if (chunks.length > 1) { - mUserIdRest.setText("<" + chunks[1]); - } - mUserId.setText(userId); - - if (data.getBoolean("signatureSuccess")) { - mSignatureStatusImage.setImageResource(R.drawable.overlay_ok); - } else if (data.getBoolean("signatureUnknown")) { - mSignatureStatusImage.setImageResource(R.drawable.overlay_error); - } else { - mSignatureStatusImage.setImageResource(R.drawable.overlay_error); - } - mSignatureLayout.setVisibility(View.VISIBLE); - } - } - - break; - } - } - } - } - }; - @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.decrypt_message); - Apg.initialize(this); - mMessage = (EditText) findViewById(R.id.message); mDecryptButton = (Button) findViewById(R.id.btn_decrypt); mSignatureLayout = (LinearLayout) findViewById(R.id.layout_signature); @@ -232,48 +135,6 @@ public class DecryptMessageActivity extends Activity } } - @Override - protected Dialog onCreateDialog(int id) { - switch (id) { - case DIALOG_DECRYPTING: { - mProgressDialog = new ProgressDialog(this); - mProgressDialog.setMessage("initializing..."); - mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); - mProgressDialog.setCancelable(false); - return mProgressDialog; - } - - case AskForSecretKeyPassPhrase.DIALOG_PASS_PHRASE: { - return AskForSecretKeyPassPhrase.createDialog(this, mDecryptionKeyId, this); - } - } - - return super.onCreateDialog(id); - } - - @Override - public void setProgress(int progress, int max) { - Message msg = new Message(); - Bundle data = new Bundle(); - data.putInt("type", MESSAGE_PROGRESS_UPDATE); - data.putInt("progress", progress); - data.putInt("max", max); - msg.setData(data); - mHandler.sendMessage(msg); - } - - @Override - public void setProgress(String message, int progress, int max) { - Message msg = new Message(); - Bundle data = new Bundle(); - data.putInt("type", MESSAGE_PROGRESS_UPDATE); - data.putString("message", message); - data.putInt("progress", progress); - data.putInt("max", max); - msg.setData(data); - mHandler.sendMessage(msg); - } - private void decryptClicked() { String error = null; String messageData = mMessage.getText().toString(); @@ -289,8 +150,8 @@ public class DecryptMessageActivity extends Activity ByteArrayInputStream in = new ByteArrayInputStream(messageData.getBytes()); try { - mDecryptionKeyId = Apg.getDecryptionKeyId(in); - showDialog(AskForSecretKeyPassPhrase.DIALOG_PASS_PHRASE); + setSecretKeyId(Apg.getDecryptionKeyId(in)); + showDialog(Id.dialog.pass_phrase); } catch (IOException e) { error = e.getLocalizedMessage(); } catch (Apg.GeneralException e) { @@ -311,22 +172,23 @@ public class DecryptMessageActivity extends Activity intent.putExtra("subject", "Re: " + mSubject); intent.putExtra("sendTo", mReplyTo); intent.putExtra("eyId", mSignatureKeyId); - intent.putExtra("signatureKeyId", mDecryptionKeyId); + intent.putExtra("signatureKeyId", getSecretKeyId()); intent.putExtra("encryptionKeyIds", new long[] { mSignatureKeyId }); startActivity(intent); } + @Override public void passPhraseCallback(String passPhrase) { - Apg.setPassPhrase(passPhrase); + super.passPhraseCallback(passPhrase); decryptStart(); } private void decryptStart() { - showDialog(DIALOG_DECRYPTING); - mRunningThread = new Thread(this); - mRunningThread.start(); + showDialog(Id.dialog.decrypting); + startThread(); } + @Override public void run() { String error = null; Security.addProvider(new BouncyCastleProvider()); @@ -356,7 +218,7 @@ public class DecryptMessageActivity extends Activity error = e.getMessage(); } - data.putInt("type", MESSAGE_DONE); + data.putInt("type", Id.message.done); if (error != null) { data.putString("error", error); @@ -365,6 +227,61 @@ public class DecryptMessageActivity extends Activity } msg.setData(data); - mHandler.sendMessage(msg); + sendMessage(msg); + } + + @Override + public void doneCallback(Message msg) { + super.doneCallback(msg); + + Bundle data = msg.getData(); + removeDialog(Id.dialog.decrypting); + mSignatureKeyId = 0; + String error = data.getString("error"); + String decryptedMessage = data.getString("decryptedMessage"); + if (error != null) { + Toast.makeText(DecryptMessageActivity.this, + "Error: " + data.getString("error"), + Toast.LENGTH_SHORT).show(); + } + mSignatureLayout.setVisibility(View.INVISIBLE); + if (decryptedMessage != null) { + mMessage.setText(decryptedMessage); + mDecryptButton.setText(R.string.btn_reply); + mDecryptButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + replyClicked(); + } + }); + + if (data.getBoolean("signature")) { + String userId = data.getString("signatureUserId"); + mSignatureKeyId = data.getLong("signatureKeyId"); + mUserIdRest.setText("id: " + + Long.toHexString(mSignatureKeyId & 0xffffffffL)); + if (userId == null) { + userId = + getResources() + .getString( + R.string.unknown_user_id); + } + String chunks[] = userId.split(" <", 2); + userId = chunks[0]; + if (chunks.length > 1) { + mUserIdRest.setText("<" + chunks[1]); + } + mUserId.setText(userId); + + if (data.getBoolean("signatureSuccess")) { + mSignatureStatusImage.setImageResource(R.drawable.overlay_ok); + } else if (data.getBoolean("signatureUnknown")) { + mSignatureStatusImage.setImageResource(R.drawable.overlay_error); + } else { + mSignatureStatusImage.setImageResource(R.drawable.overlay_error); + } + mSignatureLayout.setVisibility(View.VISIBLE); + } + } } } diff --git a/src/org/thialfihar/android/apg/EditKeyActivity.java b/src/org/thialfihar/android/apg/EditKeyActivity.java index b5b7045b7..6f13efabb 100644 --- a/src/org/thialfihar/android/apg/EditKeyActivity.java +++ b/src/org/thialfihar/android/apg/EditKeyActivity.java @@ -27,18 +27,16 @@ import org.bouncycastle2.openpgp.PGPSecretKeyRing; import org.thialfihar.android.apg.ui.widget.SectionView; import org.thialfihar.android.apg.utils.IterableIterator; -import android.app.Activity; 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.text.InputType; import android.text.method.PasswordTransformationMethod; +import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; @@ -50,17 +48,7 @@ import android.widget.EditText; import android.widget.LinearLayout; import android.widget.Toast; -public class EditKeyActivity extends Activity - implements OnClickListener, ProgressDialogUpdater, Runnable { - static final int OPTION_MENU_NEW_PASS_PHRASE = 1; - - static final int DIALOG_NEW_PASS_PHRASE = 1; - static final int DIALOG_PASS_PHRASES_DO_NOT_MATCH = 2; - static final int DIALOG_NO_PASS_PHRASE = 3; - static final int DIALOG_SAVING = 4; - - static final int MESSAGE_PROGRESS_UPDATE = 1; - static final int MESSAGE_DONE = 2; +public class EditKeyActivity extends BaseActivity implements OnClickListener { private PGPSecretKeyRing mKeyRing = null; @@ -70,56 +58,8 @@ public class EditKeyActivity extends Activity private Button mSaveButton; private Button mDiscardButton; - private ProgressDialog mProgressDialog = null; - private Thread mRunningThread = null; - private String mNewPassPhrase = null; - private Handler mHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - Bundle data = msg.getData(); - if (data != null) { - int type = data.getInt("type"); - switch (type) { - case MESSAGE_PROGRESS_UPDATE: { - String message = data.getString("message"); - if (mProgressDialog != null) { - if (message != null) { - mProgressDialog.setMessage(message); - } - mProgressDialog.setMax(data.getInt("max")); - mProgressDialog.setProgress(data.getInt("progress")); - } - break; - } - - case MESSAGE_DONE: { - removeDialog(DIALOG_SAVING); - mProgressDialog = null; - - String error = data.getString("error"); - if (error != null) { - Toast.makeText(EditKeyActivity.this, - "Error: " + data.getString("error"), - Toast.LENGTH_SHORT).show(); - } else { - Toast.makeText(EditKeyActivity.this, R.string.key_saved, - Toast.LENGTH_SHORT).show(); - setResult(RESULT_OK); - finish(); - } - break; - } - - default: { - break; - } - } - } - } - }; - @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -176,13 +116,14 @@ public class EditKeyActivity extends Activity } public boolean havePassPhrase() { + Log.e("oink", "password is " + Apg.getPassPhrase()); return (Apg.getPassPhrase() != null && !Apg.getPassPhrase().equals("")) || (mNewPassPhrase != null && mNewPassPhrase.equals("")); } @Override public boolean onCreateOptionsMenu(Menu menu) { - menu.add(0, OPTION_MENU_NEW_PASS_PHRASE, 0, + menu.add(0, Id.menu.option.new_pass_phrase, 0, (havePassPhrase() ? "Change Pass Phrase" : "Set Pass Phrase")) .setIcon(android.R.drawable.ic_menu_add); return true; @@ -191,8 +132,8 @@ public class EditKeyActivity extends Activity @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { - case OPTION_MENU_NEW_PASS_PHRASE: { - showDialog(DIALOG_NEW_PASS_PHRASE); + case Id.menu.option.new_pass_phrase: { + showDialog(Id.dialog.new_pass_phrase); return true; } @@ -206,15 +147,7 @@ public class EditKeyActivity extends Activity @Override protected Dialog onCreateDialog(int id) { switch (id) { - case DIALOG_SAVING: { - mProgressDialog = new ProgressDialog(this); - mProgressDialog.setMessage("saving..."); - mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); - mProgressDialog.setCancelable(false); - return mProgressDialog; - } - - case DIALOG_NEW_PASS_PHRASE: { + case Id.dialog.new_pass_phrase: { AlertDialog.Builder alert = new AlertDialog.Builder(this); if (havePassPhrase()) { @@ -252,17 +185,17 @@ public class EditKeyActivity extends Activity alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { - removeDialog(DIALOG_NEW_PASS_PHRASE); + removeDialog(Id.dialog.new_pass_phrase); String passPhrase1 = "" + input1.getText(); String passPhrase2 = "" + input2.getText(); if (!passPhrase1.equals(passPhrase2)) { - showDialog(DIALOG_PASS_PHRASES_DO_NOT_MATCH); + showDialog(Id.dialog.pass_phrases_do_not_match); return; } if (passPhrase1.equals("")) { - showDialog(DIALOG_NO_PASS_PHRASE); + showDialog(Id.dialog.no_pass_phrase); return; } @@ -273,45 +206,9 @@ public class EditKeyActivity extends Activity alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { - removeDialog(DIALOG_NEW_PASS_PHRASE); - } - }); - - return alert.create(); - } - - case DIALOG_PASS_PHRASES_DO_NOT_MATCH: { - AlertDialog.Builder alert = new AlertDialog.Builder(this); - - alert.setIcon(android.R.drawable.ic_dialog_alert); - alert.setTitle("Error"); - alert.setMessage("The pass phrases didn't match."); - - alert.setPositiveButton(android.R.string.ok, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - removeDialog(DIALOG_PASS_PHRASES_DO_NOT_MATCH); - } - }); - alert.setCancelable(false); - - return alert.create(); - } - - case DIALOG_NO_PASS_PHRASE: { - AlertDialog.Builder alert = new AlertDialog.Builder(this); - - alert.setIcon(android.R.drawable.ic_dialog_alert); - alert.setTitle("Error"); - alert.setMessage("Empty pass phrases are not supported."); - - alert.setPositiveButton(android.R.string.ok, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - removeDialog(DIALOG_NO_PASS_PHRASE); + removeDialog(Id.dialog.new_pass_phrase); } }); - alert.setCancelable(false); return alert.create(); } @@ -334,16 +231,15 @@ public class EditKeyActivity extends Activity } private void saveClicked() { - if ((Apg.getPassPhrase() == null || Apg.getPassPhrase().equals("")) && - (mNewPassPhrase == null || mNewPassPhrase.equals(""))) { + if (!havePassPhrase()) { Toast.makeText(this, R.string.set_a_pass_phrase, Toast.LENGTH_SHORT).show(); return; } - showDialog(DIALOG_SAVING); - mRunningThread = new Thread(this); - mRunningThread.start(); + showDialog(Id.dialog.saving); + startThread(); } + @Override public void run() { String error = null; Bundle data = new Bundle(); @@ -368,34 +264,32 @@ public class EditKeyActivity extends Activity error = e.getMessage(); } - data.putInt("type", MESSAGE_DONE); + data.putInt("type", Id.message.done); if (error != null) { data.putString("error", error); } msg.setData(data); - mHandler.sendMessage(msg); + sendMessage(msg); } - public void setProgress(int progress, int max) { - Message msg = new Message(); - Bundle data = new Bundle(); - data.putInt("type", MESSAGE_PROGRESS_UPDATE); - data.putInt("progress", progress); - data.putInt("max", max); - msg.setData(data); - mHandler.sendMessage(msg); - } + @Override + public void doneCallback(Message msg) { + super.doneCallback(msg); - public void setProgress(String message, int progress, int max) { - Message msg = new Message(); - Bundle data = new Bundle(); - data.putInt("type", MESSAGE_PROGRESS_UPDATE); - data.putString("message", message); - data.putInt("progress", progress); - data.putInt("max", max); - msg.setData(data); - mHandler.sendMessage(msg); + Bundle data = msg.getData(); + removeDialog(Id.dialog.saving); + + String error = data.getString("error"); + if (error != null) { + Toast.makeText(EditKeyActivity.this, + "Error: " + data.getString("error"), + Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(EditKeyActivity.this, R.string.key_saved, Toast.LENGTH_SHORT).show(); + setResult(RESULT_OK); + finish(); + } } }
\ No newline at end of file diff --git a/src/org/thialfihar/android/apg/EncryptFileActivity.java b/src/org/thialfihar/android/apg/EncryptFileActivity.java new file mode 100644 index 000000000..a9b05c687 --- /dev/null +++ b/src/org/thialfihar/android/apg/EncryptFileActivity.java @@ -0,0 +1,304 @@ +/*
+ * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
+ *
+ * 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;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.SignatureException;
+import java.util.Collections;
+import java.util.Vector;
+
+import org.bouncycastle2.bcpg.HashAlgorithmTags;
+import org.bouncycastle2.openpgp.PGPException;
+import org.bouncycastle2.openpgp.PGPPublicKeyRing;
+import org.bouncycastle2.openpgp.PGPSecretKey;
+import org.bouncycastle2.openpgp.PGPSecretKeyRing;
+import org.openintents.intents.FileManager;
+
+import android.content.ActivityNotFoundException;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Message;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.ImageButton;
+import android.widget.ListView;
+import android.widget.TabHost;
+import android.widget.TextView;
+import android.widget.Toast;
+import android.widget.TabHost.TabSpec;
+
+public class EncryptFileActivity extends BaseActivity {
+
+ private EditText mFilename = null;
+ private ImageButton mBrowse = null;
+ private CheckBox mSign = null;
+ private TextView mMainUserId = null;
+ private TextView mMainUserIdRest = null;
+ private ListView mList;
+ private Button mEncryptButton = null;
+
+ private long mEncryptionKeyIds[] = null;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.encrypt_file);
+
+ TabHost tabHost = (TabHost) findViewById(R.id.tab_host);
+ tabHost.setup();
+
+ TabSpec ts1 = tabHost.newTabSpec("TAB_ASYMMETRIC");
+ ts1.setIndicator(getString(R.string.tab_asymmetric),
+ getResources().getDrawable(R.drawable.key));
+ ts1.setContent(R.id.tab_asymmetric);
+ tabHost.addTab(ts1);
+
+ TabSpec ts2 = tabHost.newTabSpec("TAB_SYMMETRIC");
+ ts2.setIndicator(getString(R.string.tab_symmetric),
+ getResources().getDrawable(R.drawable.encrypted));
+ ts2.setContent(R.id.tab_symmetric);
+ tabHost.addTab(ts2);
+
+ tabHost.setCurrentTab(0);
+
+ Vector<PGPPublicKeyRing> keyRings =
+ (Vector<PGPPublicKeyRing>) Apg.getPublicKeyRings().clone();
+ Collections.sort(keyRings, new Apg.PublicKeySorter());
+ mList = (ListView) findViewById(R.id.public_key_list);
+ mList.setAdapter(new SelectPublicKeyListAdapter(mList, keyRings));
+
+ mFilename = (EditText) findViewById(R.id.filename);
+ mBrowse = (ImageButton) findViewById(R.id.btn_browse);
+ mBrowse.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ openFile();
+ }
+ });
+
+ mEncryptButton = (Button) findViewById(R.id.btn_encrypt);
+ mSign = (CheckBox) findViewById(R.id.sign);
+ mMainUserId = (TextView) findViewById(R.id.main_user_id);
+ mMainUserIdRest = (TextView) findViewById(R.id.main_user_id_rest);
+
+ mSign.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ CheckBox checkBox = (CheckBox) v;
+ if (checkBox.isChecked()) {
+ selectSecretKey();
+ } else {
+ setSecretKeyId(0);
+ Apg.setPassPhrase(null);
+ updateView();
+ }
+ }
+ });
+
+ mEncryptButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ encryptClicked();
+ }
+ });
+
+ updateView();
+ }
+
+ private void updateView() {
+ if (getSecretKeyId() == 0) {
+ mSign.setText(R.string.sign);
+ mSign.setChecked(false);
+ mMainUserId.setText("");
+ mMainUserIdRest.setText("");
+ } else {
+ String uid = getResources().getString(R.string.unknown_user_id);
+ String uidExtra = "";
+ PGPSecretKeyRing keyRing = Apg.getSecretKeyRing(getSecretKeyId());
+ if (keyRing != null) {
+ PGPSecretKey key = Apg.getMasterKey(keyRing);
+ if (key != null) {
+ String userId = Apg.getMainUserIdSafe(this, key);
+ String chunks[] = userId.split(" <", 2);
+ uid = chunks[0];
+ if (chunks.length > 1) {
+ uidExtra = "<" + chunks[1];
+ }
+ }
+ }
+ mMainUserId.setText(uid);
+ mMainUserIdRest.setText(uidExtra);
+ mSign.setText(R.string.sign_as);
+ mSign.setChecked(true);
+ }
+ }
+
+ private void openFile() {
+ String filename = mFilename.getText().toString();
+
+ Intent intent = new Intent(FileManager.ACTION_PICK_FILE);
+
+ intent.setData(Uri.parse("file://" + filename));
+
+ intent.putExtra(FileManager.EXTRA_TITLE, "Select file to encrypt...");
+ intent.putExtra(FileManager.EXTRA_BUTTON_TEXT, "Open");
+
+ try {
+ startActivityForResult(intent, Id.request.filename);
+ } catch (ActivityNotFoundException e) {
+ // No compatible file manager was found.
+ Toast.makeText(this, R.string.no_filemanager_installed, Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ private void selectSecretKey() {
+ Intent intent = new Intent(this, SelectSecretKeyListActivity.class);
+ startActivityForResult(intent, Id.request.secret_keys);
+ }
+
+ private void encryptClicked() {
+ if (getSecretKeyId() != 0 && Apg.getPassPhrase() == null) {
+ showDialog(Id.dialog.pass_phrase);
+ } else {
+ encryptStart();
+ }
+ }
+
+ @Override
+ public void passPhraseCallback(String passPhrase) {
+ super.passPhraseCallback(passPhrase);
+ encryptStart();
+ }
+
+ private void encryptStart() {
+ showDialog(Id.dialog.encrypting);
+ startThread();
+ }
+
+ @Override
+ public void run() {
+ String error = null;
+ Bundle data = new Bundle();
+ Message msg = new Message();
+
+ try {
+ InputStream in = new FileInputStream(mFilename.getText().toString());
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ if (mEncryptionKeyIds != null && mEncryptionKeyIds.length > 0) {
+ Apg.encrypt(in, out, true, mEncryptionKeyIds, getSecretKeyId(),
+ Apg.getPassPhrase(), this);
+ data.putString("message", new String(out.toByteArray()));
+ } else {
+ Apg.signText(in, out, getSecretKeyId(),
+ Apg.getPassPhrase(), HashAlgorithmTags.SHA256, this);
+ data.putString("message", new String(out.toByteArray()));
+ }
+ } catch (IOException e) {
+ error = e.getMessage();
+ } catch (PGPException e) {
+ error = e.getMessage();
+ } catch (NoSuchProviderException e) {
+ error = e.getMessage();
+ } catch (NoSuchAlgorithmException e) {
+ error = e.getMessage();
+ } catch (SignatureException e) {
+ error = e.getMessage();
+ } catch (Apg.GeneralException e) {
+ error = e.getMessage();
+ }
+
+ data.putInt("type", Id.message.done);
+
+ if (error != null) {
+ data.putString("error", error);
+ }
+
+ msg.setData(data);
+ sendMessage(msg);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ switch (requestCode) {
+ case Id.request.filename: {
+ if (resultCode == RESULT_OK && data != null) {
+ String filename = data.getDataString();
+ if (filename != null) {
+ // Get rid of URI prefix:
+ if (filename.startsWith("file://")) {
+ filename = filename.substring(7);
+ }
+ // replace %20 and so on
+ filename = Uri.decode(filename);
+
+ mFilename.setText(filename);
+ }
+ }
+ return;
+ }
+
+ case Id.request.secret_keys: {
+ if (resultCode == RESULT_OK) {
+ Bundle bundle = data.getExtras();
+ long newId = bundle.getLong("selectedKeyId");
+ if (getSecretKeyId() != newId) {
+ Apg.setPassPhrase(null);
+ }
+ setSecretKeyId(newId);
+ } else {
+ setSecretKeyId(0);
+ Apg.setPassPhrase(null);
+ }
+ updateView();
+ break;
+ }
+
+ default: {
+ break;
+ }
+ }
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+
+ @Override
+ public void doneCallback(Message msg) {
+ super.doneCallback(msg);
+ Bundle data = msg.getData();
+ removeDialog(Id.dialog.encrypting);
+
+ String error = data.getString("error");
+ if (error != null) {
+ Toast.makeText(EncryptFileActivity.this,
+ "Error: " + data.getString("error"),
+ Toast.LENGTH_SHORT).show();
+ } else {
+ Toast.makeText(EncryptFileActivity.this,
+ "Successfully encrypted.",
+ Toast.LENGTH_SHORT).show();
+ }
+ }
+}
diff --git a/src/org/thialfihar/android/apg/EncryptMessageActivity.java b/src/org/thialfihar/android/apg/EncryptMessageActivity.java index b954f31a1..d89e62bd0 100644 --- a/src/org/thialfihar/android/apg/EncryptMessageActivity.java +++ b/src/org/thialfihar/android/apg/EncryptMessageActivity.java @@ -32,12 +32,8 @@ import org.bouncycastle2.openpgp.PGPSecretKey; import org.bouncycastle2.openpgp.PGPSecretKeyRing; import org.bouncycastle2.util.Strings; -import android.app.Activity; -import android.app.Dialog; -import android.app.ProgressDialog; import android.content.Intent; import android.os.Bundle; -import android.os.Handler; import android.os.Message; import android.view.View; import android.view.View.OnClickListener; @@ -47,25 +43,11 @@ import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; -public class EncryptMessageActivity extends Activity - implements Runnable, ProgressDialogUpdater, - AskForSecretKeyPassPhrase.PassPhraseCallbackInterface { - static final int GET_PUCLIC_KEYS = 1; - static final int GET_SECRET_KEY = 2; - - static final int DIALOG_ENCRYPTING = 1; - - static final int MESSAGE_PROGRESS_UPDATE = 1; - static final int MESSAGE_DONE = 2; - +public class EncryptMessageActivity extends BaseActivity { private String mSubject = null; private String mSendTo = null; private long mEncryptionKeyIds[] = null; - private long mSignatureKeyId = 0; - - private ProgressDialog mProgressDialog = null; - private Thread mRunningThread = null; private EditText mMessage = null; private Button mSelectKeysButton = null; @@ -74,92 +56,11 @@ public class EncryptMessageActivity extends Activity private TextView mMainUserId = null; private TextView mMainUserIdRest = null; - private Handler mhandler = new Handler() { - @Override - public void handleMessage(Message mSg) { - Bundle data = mSg.getData(); - if (data != null) { - int type = data.getInt("type"); - switch (type) { - case MESSAGE_PROGRESS_UPDATE: { - String message = data.getString("message"); - if (mProgressDialog != null) { - if (message != null) { - mProgressDialog.setMessage(message); - } - mProgressDialog.setMax(data.getInt("max")); - mProgressDialog.setProgress(data.getInt("progress")); - } - break; - } - - case MESSAGE_DONE: { - removeDialog(DIALOG_ENCRYPTING); - mProgressDialog = null; - - String error = data.getString("error"); - if (error != null) { - Toast.makeText(EncryptMessageActivity.this, - "Error: " + data.getString("error"), - Toast.LENGTH_SHORT).show(); - return; - } else { - String message = data.getString("message"); - Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND); - emailIntent.setType("text/plain; charset=utf-8"); - emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, message); - if (mSubject != null) { - emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, - mSubject); - } - if (mSendTo != null) { - emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, - new String[] { mSendTo }); - } - EncryptMessageActivity.this. - startActivity(Intent.createChooser(emailIntent, "Send mail...")); - } - break; - } - - default: { - break; - } - } - } - } - }; - - @Override - public void setProgress(int progress, int max) { - Message msg = new Message(); - Bundle data = new Bundle(); - data.putInt("type", MESSAGE_PROGRESS_UPDATE); - data.putInt("progress", progress); - data.putInt("max", max); - msg.setData(data); - mhandler.sendMessage(msg); - } - - @Override - public void setProgress(String message, int progress, int max) { - Message msg = new Message(); - Bundle data = new Bundle(); - data.putInt("type", MESSAGE_PROGRESS_UPDATE); - data.putString("message", message); - data.putInt("progress", progress); - data.putInt("max", max); - msg.setData(data); - mhandler.sendMessage(msg); - } - @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.encrypt_message); - Apg.initialize(this); - mMessage = (EditText) findViewById(R.id.message); mSelectKeysButton = (Button) findViewById(R.id.btn_selectEncryptKeys); mSendButton = (Button) findViewById(R.id.btn_send); @@ -183,7 +84,7 @@ public class EncryptMessageActivity extends Activity if (masterKey != null) { Vector<PGPSecretKey> signKeys = Apg.getUsableSigningKeys(keyRing); if (signKeys.size() > 0) { - mSignatureKeyId = masterKey.getKeyID(); + setSecretKeyId(masterKey.getKeyID()); } } } @@ -240,7 +141,7 @@ public class EncryptMessageActivity extends Activity if (checkBox.isChecked()) { selectSecretKey(); } else { - mSignatureKeyId = 0; + setSecretKeyId(0); Apg.setPassPhrase(null); updateView(); } @@ -250,69 +151,56 @@ public class EncryptMessageActivity extends Activity updateView(); } - @Override - protected Dialog onCreateDialog(int id) { - switch (id) { - case DIALOG_ENCRYPTING: { - mProgressDialog = new ProgressDialog(this); - mProgressDialog.setMessage("initializing..."); - mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); - mProgressDialog.setCancelable(false); - return mProgressDialog; - } - - case AskForSecretKeyPassPhrase.DIALOG_PASS_PHRASE: { - return AskForSecretKeyPassPhrase.createDialog(this, mSignatureKeyId, this); - } - } - - return super.onCreateDialog(id); - } - private void sendClicked() { - if (mSignatureKeyId != 0 && Apg.getPassPhrase() == null) { - showDialog(AskForSecretKeyPassPhrase.DIALOG_PASS_PHRASE); + if (getSecretKeyId() != 0 && Apg.getPassPhrase() == null) { + showDialog(Id.dialog.pass_phrase); } else { encryptStart(); } } + @Override public void passPhraseCallback(String passPhrase) { - Apg.setPassPhrase(passPhrase); + super.passPhraseCallback(passPhrase); encryptStart(); } private void encryptStart() { - showDialog(DIALOG_ENCRYPTING); - mRunningThread = new Thread(this); - mRunningThread.start(); + showDialog(Id.dialog.encrypting); + startThread(); } + @Override public void run() { String error = null; Bundle data = new Bundle(); Message msg = new Message(); - String message = mMessage.getText().toString(); - // fix the message a bit, trailing spaces and newlines break stuff, - // because GMail sends as HTML and such things fuck up the signature, - // TODO: things like "<" and ">" also fuck up the signature - message = message.replaceAll(" +\n", "\n"); - message = message.replaceAll("\n\n+", "\n\n"); - message = message.replaceFirst("^\n+", ""); - // make sure there'll be exactly one newline at the end - message = message.replaceFirst("\n*$", "\n"); - - ByteArrayInputStream in = - new ByteArrayInputStream(Strings.toUTF8ByteArray(message)); - ByteArrayOutputStream out = new ByteArrayOutputStream(); try { - if (mEncryptionKeyIds != null && mEncryptionKeyIds.length > 0) { - Apg.encrypt(in, out, true, mEncryptionKeyIds, mSignatureKeyId, + boolean encryptIt = mEncryptionKeyIds != null && mEncryptionKeyIds.length > 0; + + String message = mMessage.getText().toString(); + if (!encryptIt) { + // fix the message a bit, trailing spaces and newlines break stuff, + // because GMail sends as HTML and such things fuck up the signature, + // TODO: things like "<" and ">" also fuck up the signature + message = message.replaceAll(" +\n", "\n"); + message = message.replaceAll("\n\n+", "\n\n"); + message = message.replaceFirst("^\n+", ""); + // make sure there'll be exactly one newline at the end + message = message.replaceFirst("\n*$", "\n"); + } + + ByteArrayInputStream in = + new ByteArrayInputStream(Strings.toUTF8ByteArray(message)); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + + if (encryptIt) { + Apg.encrypt(in, out, true, mEncryptionKeyIds, getSecretKeyId(), Apg.getPassPhrase(), this); data.putString("message", new String(out.toByteArray())); } else { - Apg.signText(in, out, mSignatureKeyId, + Apg.signText(in, out, getSecretKeyId(), Apg.getPassPhrase(), HashAlgorithmTags.SHA256, this); data.putString("message", new String(out.toByteArray())); } @@ -330,14 +218,14 @@ public class EncryptMessageActivity extends Activity error = e.getMessage(); } - data.putInt("type", MESSAGE_DONE); + data.putInt("type", Id.message.done); if (error != null) { data.putString("error", error); } msg.setData(data); - mhandler.sendMessage(msg); + sendMessage(msg); } private void updateView() { @@ -350,7 +238,7 @@ public class EncryptMessageActivity extends Activity getResources().getString(R.string.n_keys_selected)); } - if (mSignatureKeyId == 0) { + if (getSecretKeyId() == 0) { mSign.setText(R.string.sign); mSign.setChecked(false); mMainUserId.setText(""); @@ -358,7 +246,7 @@ public class EncryptMessageActivity extends Activity } else { String uid = getResources().getString(R.string.unknown_user_id); String uidExtra = ""; - PGPSecretKeyRing keyRing = Apg.getSecretKeyRing(mSignatureKeyId); + PGPSecretKeyRing keyRing = Apg.getSecretKeyRing(getSecretKeyId()); if (keyRing != null) { PGPSecretKey key = Apg.getMasterKey(keyRing); if (key != null) { @@ -380,18 +268,18 @@ public class EncryptMessageActivity extends Activity private void selectPublicKeys() { Intent intent = new Intent(this, SelectPublicKeyListActivity.class); intent.putExtra("selection", mEncryptionKeyIds); - startActivityForResult(intent, GET_PUCLIC_KEYS); + startActivityForResult(intent, Id.request.public_keys); } private void selectSecretKey() { Intent intent = new Intent(this, SelectSecretKeyListActivity.class); - startActivityForResult(intent, GET_SECRET_KEY); + startActivityForResult(intent, Id.request.secret_keys); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { - case GET_PUCLIC_KEYS: { + case Id.request.public_keys: { if (resultCode == RESULT_OK) { Bundle bundle = data.getExtras(); mEncryptionKeyIds = bundle.getLongArray("selection"); @@ -400,26 +288,58 @@ public class EncryptMessageActivity extends Activity break; } - case GET_SECRET_KEY: { + case Id.request.secret_keys: { if (resultCode == RESULT_OK) { Bundle bundle = data.getExtras(); long newId = bundle.getLong("selectedKeyId"); - if (mSignatureKeyId != newId) { + if (getSecretKeyId() != newId) { Apg.setPassPhrase(null); } - mSignatureKeyId = newId; + setSecretKeyId(newId); } else { - mSignatureKeyId = 0; + setSecretKeyId(0); Apg.setPassPhrase(null); } updateView(); break; } - default: + default: { break; + } } super.onActivityResult(requestCode, resultCode, data); } + + @Override + public void doneCallback(Message msg) { + super.doneCallback(msg); + + removeDialog(Id.dialog.encrypting); + + Bundle data = msg.getData(); + String error = data.getString("error"); + if (error != null) { + Toast.makeText(EncryptMessageActivity.this, + "Error: " + data.getString("error"), + Toast.LENGTH_SHORT).show(); + return; + } else { + String message = data.getString("message"); + Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND); + emailIntent.setType("text/plain; charset=utf-8"); + emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, message); + if (mSubject != null) { + emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, + mSubject); + } + if (mSendTo != null) { + emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, + new String[] { mSendTo }); + } + EncryptMessageActivity.this. + startActivity(Intent.createChooser(emailIntent, "Send mail...")); + } + } }
\ No newline at end of file diff --git a/src/org/thialfihar/android/apg/FileDialog.java b/src/org/thialfihar/android/apg/FileDialog.java index c2e7ec4b3..653ca1005 100644 --- a/src/org/thialfihar/android/apg/FileDialog.java +++ b/src/org/thialfihar/android/apg/FileDialog.java @@ -32,8 +32,7 @@ import android.widget.ImageButton; import android.widget.Toast;
public class FileDialog {
- public static final int REQUEST_CODE_PICK_FILE_OR_DIRECTORY = 12345;
- private static EditText mInput;
+ private static EditText mFilename;
private static ImageButton mBrowse;
private static Activity mActivity;
private static String mFileManagerTitle;
@@ -57,8 +56,8 @@ public class FileDialog { View view = (View) inflater.inflate(R.layout.file_dialog, null);
mActivity = activity;
- mInput = (EditText) view.findViewById(R.id.input);
- mInput.setText(defaultFile);
+ mFilename = (EditText) view.findViewById(R.id.input);
+ mFilename.setText(defaultFile);
mBrowse = (ImageButton) view.findViewById(R.id.btn_browse);
mBrowse.setOnClickListener(new View.OnClickListener() {
@Override
@@ -75,7 +74,7 @@ public class FileDialog { alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
- clickListener.onOkClick(mInput.getText().toString());
+ clickListener.onOkClick(mFilename.getText().toString());
}
});
@@ -89,8 +88,8 @@ public class FileDialog { }
public static void setFilename(String filename) {
- if (mInput != null) {
- mInput.setText(filename);
+ if (mFilename != null) {
+ mFilename.setText(filename);
}
}
@@ -98,17 +97,17 @@ public class FileDialog { * Opens the file manager to select a file to open.
*/
private static void openFile() {
- String fileName = mInput.getText().toString();
+ String filename = mFilename.getText().toString();
Intent intent = new Intent(FileManager.ACTION_PICK_FILE);
- intent.setData(Uri.parse("file://" + fileName));
+ intent.setData(Uri.parse("file://" + filename));
intent.putExtra(FileManager.EXTRA_TITLE, mFileManagerTitle);
intent.putExtra(FileManager.EXTRA_BUTTON_TEXT, mFileManagerButton);
try {
- mActivity.startActivityForResult(intent, REQUEST_CODE_PICK_FILE_OR_DIRECTORY);
+ mActivity.startActivityForResult(intent, Id.request.filename);
} catch (ActivityNotFoundException e) {
// No compatible file manager was found.
Toast.makeText(mActivity, R.string.no_filemanager_installed, Toast.LENGTH_SHORT).show();
diff --git a/src/org/thialfihar/android/apg/Id.java b/src/org/thialfihar/android/apg/Id.java new file mode 100644 index 000000000..7a57b706d --- /dev/null +++ b/src/org/thialfihar/android/apg/Id.java @@ -0,0 +1,82 @@ +/*
+ * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
+ *
+ * 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;
+
+public final class Id {
+ public static final class menu {
+ public static final int export = 0x21070001;
+ public static final int delete = 0x21070002;
+ public static final int edit = 0x21070003;
+
+ public static final class option {
+ public static final int new_pass_phrase = 0x21070001;
+ public static final int create = 0x21070002;
+ public static final int about = 0x21070003;
+ public static final int manage_public_keys = 0x21070004;
+ public static final int manage_secret_keys = 0x21070005;
+ public static final int import_keys = 0x21070006;
+ public static final int export_keys = 0x21070007;
+ }
+ }
+
+ public static final class message {
+ public static final int progress_update = 0x21070001;
+ public static final int done = 0x21070002;
+ public static final int import_keys = 0x21070003;
+ public static final int export_keys = 0x21070004;
+ public static final int import_done = 0x21070005;
+ public static final int export_done = 0x21070006;
+ public static final int create_key = 0x21070007;
+ public static final int edit_key = 0x21070008;
+ }
+
+ public static final class request {
+ public static final int public_keys = 0x21070001;
+ public static final int secret_keys = 0x21070002;
+ public static final int filename = 0x21070003;
+ }
+
+ public static final class dialog {
+ public static final int pass_phrase = 0x21070001;
+ public static final int encrypting = 0x21070002;
+ public static final int decrypting = 0x21070003;
+ public static final int new_pass_phrase = 0x21070004;
+ public static final int pass_phrases_do_not_match = 0x21070005;
+ public static final int no_pass_phrase = 0x21070006;
+ public static final int saving = 0x21070007;
+ public static final int delete_key = 0x21070008;
+ public static final int import_keys = 0x21070009;
+ public static final int importing = 0x2107000a;
+ public static final int export_key = 0x2107000b;
+ public static final int export_keys = 0x2107000c;
+ public static final int exporting = 0x2107000d;
+ public static final int new_account = 0x2107000e;
+ public static final int about = 0x2107000f;
+ public static final int change_log = 0x21070010;
+ }
+
+ public static final class task {
+ public static final int import_keys = 0x21070001;
+ public static final int export_keys = 0x21070002;
+ }
+
+ public static final class type {
+ public static final int public_key = 0x21070001;
+ public static final int secret_key = 0x21070002;
+ }
+}
+
diff --git a/src/org/thialfihar/android/apg/MailListActivity.java b/src/org/thialfihar/android/apg/MailListActivity.java index ed207d4cd..c0bed5985 100644 --- a/src/org/thialfihar/android/apg/MailListActivity.java +++ b/src/org/thialfihar/android/apg/MailListActivity.java @@ -37,7 +37,7 @@ import android.widget.TextView; import android.widget.AdapterView.OnItemClickListener;
public class MailListActivity extends ListActivity {
- LayoutInflater minflater = null;
+ LayoutInflater mInflater = null;
private static class Conversation {
public long id;
@@ -82,7 +82,7 @@ public class MailListActivity extends ListActivity { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- minflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mconversations = new Vector<Conversation>();
mmessages = new Vector<Message>();
@@ -191,7 +191,7 @@ public class MailListActivity extends ListActivity { @Override
public View getView(int position, View convertView, ViewGroup parent) {
- View view = minflater.inflate(R.layout.mailbox_message_item, null);
+ View view = mInflater.inflate(R.layout.mailbox_message_item, null);
Message message = (Message) getItem(position);
diff --git a/src/org/thialfihar/android/apg/MainActivity.java b/src/org/thialfihar/android/apg/MainActivity.java index 1c0361dec..8cd9df6bf 100644 --- a/src/org/thialfihar/android/apg/MainActivity.java +++ b/src/org/thialfihar/android/apg/MainActivity.java @@ -51,17 +51,7 @@ import android.widget.TextView; import android.widget.Toast; import android.widget.AdapterView.OnItemClickListener; -public class MainActivity extends Activity { - private static final int DIALOG_NEW_ACCOUNT = 1; - private static final int DIALOG_ABOUT = 2; - private static final int DIALOG_CHANGE_LOG = 3; - - private static final int OPTION_MENU_ADD_ACCOUNT = 1; - private static final int OPTION_MENU_ABOUT = 2; - private static final int OPTION_MENU_MANAGE_PUBLIC_KEYS = 3; - private static final int OPTION_MENU_MANAGE_SECRET_KEYS = 4; - - private static final int MENU_DELETE_ACCOUNT = 1; +public class MainActivity extends BaseActivity { private static String PREF_SEEN_CHANGE_LOG = "seenChangeLogDialog" + Apg.VERSION; @@ -72,10 +62,10 @@ public class MainActivity extends Activity { super.onCreate(savedInstanceState); setContentView(R.layout.main); - Apg.initialize(this); - Button encryptMessageButton = (Button) findViewById(R.id.btn_encryptMessage); Button decryptMessageButton = (Button) findViewById(R.id.btn_decryptMessage); + Button encryptFileButton = (Button) findViewById(R.id.btn_encryptFile); + Button decryptFileButton = (Button) findViewById(R.id.btn_decryptFile); mAccounts = (ListView) findViewById(R.id.account_list); encryptMessageButton.setOnClickListener(new OnClickListener() { @@ -92,6 +82,20 @@ public class MainActivity extends Activity { } }); + encryptFileButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + startEncryptFileActivity(); + } + }); + + decryptFileButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + startDecryptFileActivity(); + } + }); + Cursor accountCursor = managedQuery(Accounts.CONTENT_URI, null, null, null, null); mAccounts.setAdapter(new AccountListAdapter(this, accountCursor)); @@ -113,14 +117,14 @@ public class MainActivity extends Activity { SharedPreferences prefs = getPreferences(MODE_PRIVATE); if (!prefs.getBoolean(PREF_SEEN_CHANGE_LOG, false)) { - showDialog(DIALOG_CHANGE_LOG); + showDialog(Id.dialog.change_log); } } @Override protected Dialog onCreateDialog(int id) { switch (id) { - case DIALOG_NEW_ACCOUNT: { + case Id.dialog.new_account: { AlertDialog.Builder alert = new AlertDialog.Builder(this); alert.setTitle("Add Account"); @@ -132,7 +136,7 @@ public class MainActivity extends Activity { alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { - MainActivity.this.removeDialog(DIALOG_NEW_ACCOUNT); + MainActivity.this.removeDialog(Id.dialog.new_account); String accountName = "" + input.getText(); Cursor testCursor = @@ -165,14 +169,14 @@ public class MainActivity extends Activity { alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { - MainActivity.this.removeDialog(DIALOG_NEW_ACCOUNT); + MainActivity.this.removeDialog(Id.dialog.new_account); } }); return alert.create(); } - case DIALOG_ABOUT: { + case Id.dialog.about: { AlertDialog.Builder alert = new AlertDialog.Builder(this); alert.setTitle("About " + Apg.FULL_VERSION); @@ -205,14 +209,14 @@ public class MainActivity extends Activity { alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { - MainActivity.this.removeDialog(DIALOG_ABOUT); + MainActivity.this.removeDialog(Id.dialog.about); } }); return alert.create(); } - case DIALOG_CHANGE_LOG: { + case Id.dialog.change_log: { AlertDialog.Builder alert = new AlertDialog.Builder(this); alert.setTitle("Changes " + Apg.FULL_VERSION); @@ -246,7 +250,7 @@ public class MainActivity extends Activity { alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { - MainActivity.this.removeDialog(DIALOG_CHANGE_LOG); + MainActivity.this.removeDialog(Id.dialog.change_log); SharedPreferences prefs = getPreferences(MODE_PRIVATE); SharedPreferences.Editor editor = prefs.edit(); editor.putBoolean(PREF_SEEN_CHANGE_LOG, true); @@ -261,18 +265,19 @@ public class MainActivity extends Activity { break; } } + return super.onCreateDialog(id); } @Override public boolean onCreateOptionsMenu(Menu menu) { - menu.add(0, OPTION_MENU_MANAGE_PUBLIC_KEYS, 0, R.string.menu_managePublicKeys) + menu.add(0, Id.menu.option.manage_public_keys, 0, R.string.menu_managePublicKeys) .setIcon(android.R.drawable.ic_menu_manage); - menu.add(0, OPTION_MENU_MANAGE_SECRET_KEYS, 1, R.string.menu_manageSecretKeys) + menu.add(0, Id.menu.option.manage_secret_keys, 1, R.string.menu_manageSecretKeys) .setIcon(android.R.drawable.ic_menu_manage); - menu.add(1, OPTION_MENU_ADD_ACCOUNT, 2, R.string.menu_addAccount) + menu.add(1, Id.menu.option.create, 2, R.string.menu_addAccount) .setIcon(android.R.drawable.ic_menu_add); - menu.add(1, OPTION_MENU_ABOUT, 3, R.string.menu_about) + menu.add(1, Id.menu.option.about, 3, R.string.menu_about) .setIcon(android.R.drawable.ic_menu_info_details); return true; } @@ -280,22 +285,22 @@ public class MainActivity extends Activity { @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { - case OPTION_MENU_ADD_ACCOUNT: { - showDialog(DIALOG_NEW_ACCOUNT); + case Id.menu.option.create: { + showDialog(Id.dialog.new_account); return true; } - case OPTION_MENU_ABOUT: { - showDialog(DIALOG_ABOUT); + case Id.menu.option.about: { + showDialog(Id.dialog.about); return true; } - case OPTION_MENU_MANAGE_PUBLIC_KEYS: { + case Id.menu.option.manage_public_keys: { startPublicKeyManager(); return true; } - case OPTION_MENU_MANAGE_SECRET_KEYS: { + case Id.menu.option.manage_secret_keys: { startSecretKeyManager(); return true; } @@ -314,7 +319,7 @@ public class MainActivity extends Activity { TextView nameTextView = (TextView) v.findViewById(R.id.account_name); if (nameTextView != null) { menu.setHeaderTitle(nameTextView.getText()); - menu.add(0, MENU_DELETE_ACCOUNT, 0, "Delete Account"); + menu.add(0, Id.menu.delete, 0, "Delete Account"); } } @@ -324,7 +329,7 @@ public class MainActivity extends Activity { (AdapterView.AdapterContextMenuInfo) menuItem.getMenuInfo(); switch (menuItem.getItemId()) { - case MENU_DELETE_ACCOUNT: { + case Id.menu.delete: { Uri uri = Uri.withAppendedPath(Accounts.CONTENT_URI, "" + info.id); this.getContentResolver().delete(uri, null, null); return true; @@ -342,7 +347,6 @@ public class MainActivity extends Activity { public void startSecretKeyManager() { startActivity(new Intent(this, SecretKeyListActivity.class)); - //startActivity(new Intent(this, EditKeyActivity.class)); } public void startEncryptMessageActivity() { @@ -353,6 +357,14 @@ public class MainActivity extends Activity { startActivity(new Intent(this, DecryptMessageActivity.class)); } + public void startEncryptFileActivity() { + startActivity(new Intent(this, EncryptFileActivity.class)); + } + + public void startDecryptFileActivity() { + //startActivity(new Intent(this, DecryptFileActivity.class)); + } + public void startMailListActivity(String account) { startActivity(new Intent(this, MailListActivity.class).putExtra("account", account)); } diff --git a/src/org/thialfihar/android/apg/PublicKeyListActivity.java b/src/org/thialfihar/android/apg/PublicKeyListActivity.java index 1e4dc081d..d6a2aa577 100644 --- a/src/org/thialfihar/android/apg/PublicKeyListActivity.java +++ b/src/org/thialfihar/android/apg/PublicKeyListActivity.java @@ -27,17 +27,13 @@ import org.thialfihar.android.apg.utils.IterableIterator; import android.app.AlertDialog;
import android.app.Dialog;
-import android.app.ExpandableListActivity;
-import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
-import android.os.Handler;
import android.os.Message;
-import android.util.Log;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -52,155 +48,30 @@ import android.widget.TextView; import android.widget.Toast;
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
-public class PublicKeyListActivity extends ExpandableListActivity
- implements Runnable, ProgressDialogUpdater {
- static final int MENU_DELETE = 1;
- static final int MENU_EXPORT = 2;
-
- static final int OPTION_MENU_IMPORT_KEYS = 1;
- static final int OPTION_MENU_EXPORT_KEYS = 2;
-
- static final int MESSAGE_PROGRESS_UPDATE = 1;
- static final int MESSAGE_IMPORT_DONE = 2;
- static final int MESSAGE_EXPORT_DONE = 3;
-
- static final int DIALOG_DELETE_KEY = 1;
- static final int DIALOG_IMPORT_KEYS = 2;
- static final int DIALOG_IMPORTING = 3;
- static final int DIALOG_EXPORT_KEYS = 4;
- static final int DIALOG_EXPORTING = 5;
- static final int DIALOG_EXPORT_KEY = 6;
-
- static final int TASK_IMPORT = 1;
- static final int TASK_EXPORT = 2;
+public class PublicKeyListActivity extends BaseActivity {
+ ExpandableListView mList;
protected int mSelectedItem = -1;
protected int mTask = 0;
- private ProgressDialog mProgressDialog = null;
- private Thread mRunningThread = null;
-
private String mImportFilename = Environment.getExternalStorageDirectory() + "/pubring.gpg";
private String mExportFilename = Environment.getExternalStorageDirectory() + "/pubexport.asc";
- private Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- Bundle data = msg.getData();
- if (data != null) {
- int type = data.getInt("type");
- switch (type) {
- case MESSAGE_PROGRESS_UPDATE: {
- String message = data.getString("message");
- if (mProgressDialog != null) {
- if (message != null) {
- mProgressDialog.setMessage(message);
- }
- mProgressDialog.setMax(data.getInt("max"));
- mProgressDialog.setProgress(data.getInt("progress"));
- }
- break;
- }
-
- case MESSAGE_IMPORT_DONE: {
- removeDialog(DIALOG_IMPORTING);
- mProgressDialog = null;
-
- String error = data.getString("error");
- if (error != null) {
- Toast.makeText(PublicKeyListActivity.this,
- "Error: " + data.getString("error"),
- Toast.LENGTH_SHORT).show();
- } else {
- int added = data.getInt("added");
- int updated = data.getInt("updated");
- String message;
- if (added > 0 && updated > 0) {
- message = "Succssfully added " + added + " keys and updated " +
- updated + " keys.";
- } else if (added > 0) {
- message = "Succssfully added " + added + " keys.";
- } else if (updated > 0) {
- message = "Succssfully updated " + updated + " keys.";
- } else {
- message = "No keys added or updated.";
- }
- Toast.makeText(PublicKeyListActivity.this, message,
- Toast.LENGTH_SHORT).show();
- }
- refreshList();
- break;
- }
-
- case MESSAGE_EXPORT_DONE: {
- removeDialog(DIALOG_EXPORTING);
- mProgressDialog = null;
-
- String error = data.getString("error");
- if (error != null) {
- Toast.makeText(PublicKeyListActivity.this,
- "Error: " + data.getString("error"),
- Toast.LENGTH_SHORT).show();
- } else {
- int exported = data.getInt("exported");
- String message;
- if (exported == 1) {
- message = "Succssfully exported 1 key.";
- } else if (exported > 0) {
- message = "Succssfully exported " + exported + " keys.";
- } else{
- message = "No keys exported.";
- }
- Toast.makeText(PublicKeyListActivity.this, message,
- Toast.LENGTH_SHORT).show();
- }
- break;
- }
-
- default: {
- break;
- }
- }
- }
- }
- };
-
- public void setProgress(int progress, int max) {
- Message msg = new Message();
- Bundle data = new Bundle();
- data.putInt("type", MESSAGE_PROGRESS_UPDATE);
- data.putInt("progress", progress);
- data.putInt("max", max);
- msg.setData(data);
- mHandler.sendMessage(msg);
- }
-
- public void setProgress(String message, int progress, int max) {
- Message msg = new Message();
- Bundle data = new Bundle();
- data.putInt("type", MESSAGE_PROGRESS_UPDATE);
- data.putString("message", message);
- data.putInt("progress", progress);
- data.putInt("max", max);
- msg.setData(data);
- mHandler.sendMessage(msg);
- }
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ setContentView(R.layout.key_list);
- Apg.initialize(this);
-
- setListAdapter(new PublicKeyListAdapter(this));
- registerForContextMenu(getExpandableListView());
+ mList = (ExpandableListView) findViewById(R.id.list);
+ mList.setAdapter(new PublicKeyListAdapter(this));
+ registerForContextMenu(mList);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
- menu.add(0, OPTION_MENU_IMPORT_KEYS, 0, "Import Keys")
+ menu.add(0, Id.menu.option.import_keys, 0, "Import Keys")
.setIcon(android.R.drawable.ic_menu_add);
- menu.add(0, OPTION_MENU_EXPORT_KEYS, 1, "Export Keys")
+ menu.add(0, Id.menu.option.export_keys, 1, "Export Keys")
.setIcon(android.R.drawable.ic_menu_save);
return true;
}
@@ -208,13 +79,13 @@ public class PublicKeyListActivity extends ExpandableListActivity @Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
- case OPTION_MENU_IMPORT_KEYS: {
- showDialog(DIALOG_IMPORT_KEYS);
+ case Id.menu.option.import_keys: {
+ showDialog(Id.dialog.import_keys);
return true;
}
- case OPTION_MENU_EXPORT_KEYS: {
- showDialog(DIALOG_EXPORT_KEYS);
+ case Id.menu.option.export_keys: {
+ showDialog(Id.dialog.export_keys);
return true;
}
@@ -237,8 +108,8 @@ public class PublicKeyListActivity extends ExpandableListActivity PGPPublicKeyRing keyRing = Apg.getPublicKeyRings().get(groupPosition);
String userId = Apg.getMainUserIdSafe(this, Apg.getMasterKey(keyRing));
menu.setHeaderTitle(userId);
- menu.add(0, MENU_EXPORT, 0, "Export Key");
- menu.add(0, MENU_DELETE, 1, "Delete Key");
+ menu.add(0, Id.menu.export, 0, "Export Key");
+ menu.add(0, Id.menu.delete, 1, "Delete Key");
}
}
@@ -253,15 +124,15 @@ public class PublicKeyListActivity extends ExpandableListActivity }
switch (menuItem.getItemId()) {
- case MENU_EXPORT: {
+ case Id.menu.export: {
mSelectedItem = groupPosition;
- showDialog(DIALOG_EXPORT_KEY);
+ showDialog(Id.dialog.export_key);
return true;
}
- case MENU_DELETE: {
+ case Id.menu.delete: {
mSelectedItem = groupPosition;
- showDialog(DIALOG_DELETE_KEY);
+ showDialog(Id.dialog.delete_key);
return true;
}
@@ -276,7 +147,7 @@ public class PublicKeyListActivity extends ExpandableListActivity boolean singleKeyExport = false;
switch (id) {
- case DIALOG_DELETE_KEY: {
+ case Id.dialog.delete_key: {
PGPPublicKeyRing keyRing = Apg.getPublicKeyRings().get(mSelectedItem);
String userId = Apg.getMainUserIdSafe(this, Apg.getMasterKey(keyRing));
@@ -289,20 +160,20 @@ public class PublicKeyListActivity extends ExpandableListActivity public void onClick(DialogInterface dialog, int id) {
deleteKey(mSelectedItem);
mSelectedItem = -1;
- removeDialog(DIALOG_DELETE_KEY);
+ removeDialog(Id.dialog.delete_key);
}
});
builder.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mSelectedItem = -1;
- removeDialog(DIALOG_DELETE_KEY);
+ removeDialog(Id.dialog.delete_key);
}
});
return builder.create();
}
- case DIALOG_IMPORT_KEYS: {
+ case Id.dialog.import_keys: {
return FileDialog.build(this, "Import Keys",
"Please specify which file to import from.",
mImportFilename,
@@ -310,33 +181,33 @@ public class PublicKeyListActivity extends ExpandableListActivity @Override
public void onOkClick(String filename) {
- removeDialog(DIALOG_IMPORT_KEYS);
+ removeDialog(Id.dialog.import_keys);
mImportFilename = filename;
importKeys();
}
@Override
public void onCancelClick() {
- removeDialog(DIALOG_IMPORT_KEYS);
+ removeDialog(Id.dialog.import_keys);
}
},
getString(R.string.filemanager_title_open),
getString(R.string.filemanager_btn_open));
}
- case DIALOG_EXPORT_KEY: {
+ case Id.dialog.export_key: {
singleKeyExport = true;
- // break intentionally omitted, to use the DIALOG_EXPORT_KEYS dialog
+ // break intentionally omitted, to use the Id.dialog.export_keys dialog
}
- case DIALOG_EXPORT_KEYS: {
+ case Id.dialog.export_keys: {
String title = "Export Key";
if (!singleKeyExport) {
// plural "Keys"
title += "s";
}
- final int thisDialogId = (singleKeyExport ? DIALOG_EXPORT_KEY : DIALOG_EXPORT_KEYS);
+ final int thisDialogId = (singleKeyExport ? Id.dialog.export_key : Id.dialog.export_keys);
return FileDialog.build(this, title,
"Please specify which file to export to.\n" +
@@ -360,54 +231,42 @@ public class PublicKeyListActivity extends ExpandableListActivity getString(R.string.filemanager_btn_save));
}
- case DIALOG_IMPORTING: {
- mProgressDialog = new ProgressDialog(this);
- mProgressDialog.setMessage("importing...");
- mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
- mProgressDialog.setCancelable(false);
- return mProgressDialog;
- }
-
- case DIALOG_EXPORTING: {
- mProgressDialog = new ProgressDialog(this);
- mProgressDialog.setMessage("exporting...");
- mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
- mProgressDialog.setCancelable(false);
- return mProgressDialog;
+ default: {
+ break;
}
}
+
return super.onCreateDialog(id);
}
public void importKeys() {
- showDialog(DIALOG_IMPORTING);
- mTask = TASK_IMPORT;
- mRunningThread = new Thread(this);
- mRunningThread.start();
+ showDialog(Id.dialog.importing);
+ mTask = Id.task.import_keys;
+ startThread();
}
public void exportKeys() {
- showDialog(DIALOG_EXPORTING);
- mTask = TASK_EXPORT;
- mRunningThread = new Thread(this);
- mRunningThread.start();
+ showDialog(Id.dialog.exporting);
+ mTask = Id.task.export_keys;
+ startThread();
}
+ @Override
public void run() {
String error = null;
Bundle data = new Bundle();
Message msg = new Message();
String filename = null;
- if (mTask == TASK_IMPORT) {
+ if (mTask == Id.task.import_keys) {
filename = mImportFilename;
} else {
filename = mExportFilename;
}
try {
- if (mTask == TASK_IMPORT) {
- data = Apg.importKeyRings(this, Apg.TYPE_PUBLIC, filename, this);
+ if (mTask == Id.task.import_keys) {
+ data = Apg.importKeyRings(this, Id.type.public_key, filename, this);
} else {
Vector<Object> keys = new Vector<Object>();
if (mSelectedItem == -1) {
@@ -429,10 +288,10 @@ public class PublicKeyListActivity extends ExpandableListActivity error = e.getMessage();
}
- if (mTask == TASK_IMPORT) {
- data.putInt("type", MESSAGE_IMPORT_DONE);
+ if (mTask == Id.task.import_keys) {
+ data.putInt("type", Id.message.import_done);
} else {
- data.putInt("type", MESSAGE_EXPORT_DONE);
+ data.putInt("type", Id.message.export_done);
}
if (error != null) {
@@ -440,7 +299,7 @@ public class PublicKeyListActivity extends ExpandableListActivity }
msg.setData(data);
- mHandler.sendMessage(msg);
+ sendMessage(msg);
}
private void deleteKey(int index) {
@@ -450,7 +309,75 @@ public class PublicKeyListActivity extends ExpandableListActivity }
private void refreshList() {
- ((PublicKeyListAdapter) getExpandableListAdapter()).notifyDataSetChanged();
+ ((PublicKeyListAdapter) mList.getExpandableListAdapter()).notifyDataSetChanged();
+ }
+
+ @Override
+ public void doneCallback(Message msg) {
+ super.doneCallback(msg);
+
+ Bundle data = msg.getData();
+ if (data != null) {
+ int type = data.getInt("type");
+ switch (type) {
+ case Id.message.import_done: {
+ removeDialog(Id.dialog.importing);
+
+ String error = data.getString("error");
+ if (error != null) {
+ Toast.makeText(PublicKeyListActivity.this,
+ "Error: " + data.getString("error"),
+ Toast.LENGTH_SHORT).show();
+ } else {
+ int added = data.getInt("added");
+ int updated = data.getInt("updated");
+ String message;
+ if (added > 0 && updated > 0) {
+ message = "Succssfully added " + added + " keys and updated " +
+ updated + " keys.";
+ } else if (added > 0) {
+ message = "Succssfully added " + added + " keys.";
+ } else if (updated > 0) {
+ message = "Succssfully updated " + updated + " keys.";
+ } else {
+ message = "No keys added or updated.";
+ }
+ Toast.makeText(PublicKeyListActivity.this, message,
+ Toast.LENGTH_SHORT).show();
+ }
+ refreshList();
+ break;
+ }
+
+ case Id.message.export_done: {
+ removeDialog(Id.dialog.exporting);
+
+ String error = data.getString("error");
+ if (error != null) {
+ Toast.makeText(PublicKeyListActivity.this,
+ "Error: " + data.getString("error"),
+ Toast.LENGTH_SHORT).show();
+ } else {
+ int exported = data.getInt("exported");
+ String message;
+ if (exported == 1) {
+ message = "Succssfully exported 1 key.";
+ } else if (exported > 0) {
+ message = "Succssfully exported " + exported + " keys.";
+ } else{
+ message = "No keys exported.";
+ }
+ Toast.makeText(PublicKeyListActivity.this, message,
+ Toast.LENGTH_SHORT).show();
+ }
+ break;
+ }
+
+ default: {
+ break;
+ }
+ }
+ }
}
private static class PublicKeyListAdapter extends BaseExpandableListAdapter {
@@ -633,7 +560,7 @@ public class PublicKeyListActivity extends ExpandableListActivity @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
- case FileDialog.REQUEST_CODE_PICK_FILE_OR_DIRECTORY: {
+ case Id.request.filename: {
if (resultCode == RESULT_OK && data != null) {
String filename = data.getDataString();
if (filename != null) {
diff --git a/src/org/thialfihar/android/apg/SecretKeyListActivity.java b/src/org/thialfihar/android/apg/SecretKeyListActivity.java index 794b30ea2..9eff85d24 100644 --- a/src/org/thialfihar/android/apg/SecretKeyListActivity.java +++ b/src/org/thialfihar/android/apg/SecretKeyListActivity.java @@ -27,15 +27,12 @@ import org.thialfihar.android.apg.utils.IterableIterator; import android.app.AlertDialog;
import android.app.Dialog;
-import android.app.ExpandableListActivity;
-import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
-import android.os.Handler;
import android.os.Message;
import android.view.ContextMenu;
import android.view.LayoutInflater;
@@ -52,165 +49,33 @@ import android.widget.Toast; import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
import android.widget.ExpandableListView.OnChildClickListener;
-public class SecretKeyListActivity extends ExpandableListActivity
- implements Runnable, ProgressDialogUpdater, OnChildClickListener,
- AskForSecretKeyPassPhrase.PassPhraseCallbackInterface {
- static final int CREATE_SECRET_KEY = 1;
- static final int EDIT_SECRET_KEY = 2;
-
- static final int MENU_EDIT = 1;
- static final int MENU_EXPORT = 2;
- static final int MENU_DELETE = 3;
-
- static final int OPTION_MENU_IMPORT_KEYS = 1;
- static final int OPTION_MENU_EXPORT_KEYS = 2;
- static final int OPTION_MENU_CREATE_KEY = 3;
-
- static final int MESSAGE_PROGRESS_UPDATE = 1;
- static final int MESSAGE_DONE = 2;
- static final int MESSAGE_IMPORT_DONE = 2;
- static final int MESSAGE_EXPORT_DONE = 3;
-
- static final int DIALOG_DELETE_KEY = 1;
- static final int DIALOG_IMPORT_KEYS = 2;
- static final int DIALOG_IMPORTING = 3;
- static final int DIALOG_EXPORT_KEYS = 4;
- static final int DIALOG_EXPORTING = 5;
- static final int DIALOG_EXPORT_KEY = 6;
-
- static final int TASK_IMPORT = 1;
- static final int TASK_EXPORT = 2;
+public class SecretKeyListActivity extends BaseActivity implements OnChildClickListener {
+ ExpandableListView mList;
protected int mSelectedItem = -1;
protected int mTask = 0;
- private ProgressDialog mProgressDialog = null;
- private Thread mRunningThread = null;
-
private String mImportFilename = Environment.getExternalStorageDirectory() + "/secring.gpg";
private String mExportFilename = Environment.getExternalStorageDirectory() + "/secexport.asc";
- private Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- Bundle data = msg.getData();
- if (data != null) {
- int type = data.getInt("type");
- switch (type) {
- case MESSAGE_PROGRESS_UPDATE: {
- String message = data.getString("message");
- if (mProgressDialog != null) {
- if (message != null) {
- mProgressDialog.setMessage(message);
- }
- mProgressDialog.setMax(data.getInt("max"));
- mProgressDialog.setProgress(data.getInt("progress"));
- }
- break;
- }
-
- case MESSAGE_IMPORT_DONE: {
- removeDialog(DIALOG_IMPORTING);
- mProgressDialog = null;
-
- String error = data.getString("error");
- if (error != null) {
- Toast.makeText(SecretKeyListActivity.this,
- "Error: " + data.getString("error"),
- Toast.LENGTH_SHORT).show();
- } else {
- int added = data.getInt("added");
- int updated = data.getInt("updated");
- String message;
- if (added > 0 && updated > 0) {
- message = "Succssfully added " + added + " keys and updated " +
- updated + " keys.";
- } else if (added > 0) {
- message = "Succssfully added " + added + " keys.";
- } else if (updated > 0) {
- message = "Succssfully updated " + updated + " keys.";
- } else {
- message = "No keys added or updated.";
- }
- Toast.makeText(SecretKeyListActivity.this, message,
- Toast.LENGTH_SHORT).show();
- }
- refreshList();
- break;
- }
-
- case MESSAGE_EXPORT_DONE: {
- removeDialog(DIALOG_EXPORTING);
- mProgressDialog = null;
-
- String error = data.getString("error");
- if (error != null) {
- Toast.makeText(SecretKeyListActivity.this,
- "Error: " + data.getString("error"),
- Toast.LENGTH_SHORT).show();
- } else {
- int exported = data.getInt("exported");
- String message;
- if (exported == 1) {
- message = "Succssfully exported 1 key.";
- } else if (exported > 0) {
- message = "Succssfully exported " + exported + " keys.";
- } else{
- message = "No keys exported.";
- }
- Toast.makeText(SecretKeyListActivity.this, message,
- Toast.LENGTH_SHORT).show();
- }
- break;
- }
-
- default: {
- break;
- }
- }
- }
- }
- };
-
- public void setProgress(int progress, int max) {
- Message msg = new Message();
- Bundle data = new Bundle();
- data.putInt("type", MESSAGE_PROGRESS_UPDATE);
- data.putInt("progress", progress);
- data.putInt("max", max);
- msg.setData(data);
- mHandler.sendMessage(msg);
- }
-
- public void setProgress(String message, int progress, int max) {
- Message msg = new Message();
- Bundle data = new Bundle();
- data.putInt("type", MESSAGE_PROGRESS_UPDATE);
- data.putString("message", message);
- data.putInt("progress", progress);
- data.putInt("max", max);
- msg.setData(data);
- mHandler.sendMessage(msg);
- }
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ setContentView(R.layout.key_list);
- Apg.initialize(this);
-
- setListAdapter(new SecretKeyListAdapter(this));
- registerForContextMenu(getExpandableListView());
- getExpandableListView().setOnChildClickListener(this);
+ mList = (ExpandableListView) findViewById(R.id.list);
+ mList.setAdapter(new SecretKeyListAdapter(this));
+ registerForContextMenu(mList);
+ mList.setOnChildClickListener(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
- menu.add(0, OPTION_MENU_IMPORT_KEYS, 0, "Import Keys")
+ menu.add(0, Id.menu.option.import_keys, 0, "Import Keys")
.setIcon(android.R.drawable.ic_menu_add);
- menu.add(0, OPTION_MENU_EXPORT_KEYS, 1, "Export Keys")
+ menu.add(0, Id.menu.option.export_keys, 1, "Export Keys")
.setIcon(android.R.drawable.ic_menu_save);
- menu.add(1, OPTION_MENU_CREATE_KEY, 2, "Create Key")
+ menu.add(1, Id.menu.option.create, 2, "Create Key")
.setIcon(android.R.drawable.ic_menu_add);
return true;
}
@@ -218,17 +83,17 @@ public class SecretKeyListActivity extends ExpandableListActivity @Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
- case OPTION_MENU_IMPORT_KEYS: {
- showDialog(DIALOG_IMPORT_KEYS);
+ case Id.menu.option.import_keys: {
+ showDialog(Id.dialog.import_keys);
return true;
}
- case OPTION_MENU_EXPORT_KEYS: {
- showDialog(DIALOG_EXPORT_KEYS);
+ case Id.menu.option.export_keys: {
+ showDialog(Id.dialog.export_keys);
return true;
}
- case OPTION_MENU_CREATE_KEY: {
+ case Id.menu.option.create: {
createKey();
return true;
}
@@ -241,8 +106,7 @@ public class SecretKeyListActivity extends ExpandableListActivity }
@Override
- public void onCreateContextMenu(ContextMenu menu, View v,
- ContextMenuInfo menuInfo) {
+ public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
ExpandableListView.ExpandableListContextMenuInfo info =
(ExpandableListView.ExpandableListContextMenuInfo) menuInfo;
@@ -253,9 +117,9 @@ public class SecretKeyListActivity extends ExpandableListActivity PGPSecretKeyRing keyRing = Apg.getSecretKeyRings().get(groupPosition);
String userId = Apg.getMainUserIdSafe(this, Apg.getMasterKey(keyRing));
menu.setHeaderTitle(userId);
- menu.add(0, MENU_EDIT, 0, "Edit Key");
- menu.add(0, MENU_EXPORT, 1, "Export Key");
- menu.add(0, MENU_DELETE, 2, "Delete Key");
+ menu.add(0, Id.menu.edit, 0, "Edit Key");
+ menu.add(0, Id.menu.export, 1, "Export Key");
+ menu.add(0, Id.menu.delete, 2, "Delete Key");
}
}
@@ -270,21 +134,21 @@ public class SecretKeyListActivity extends ExpandableListActivity }
switch (menuItem.getItemId()) {
- case MENU_EDIT: {
+ case Id.menu.edit: {
mSelectedItem = groupPosition;
- showDialog(AskForSecretKeyPassPhrase.DIALOG_PASS_PHRASE);
+ showDialog(Id.dialog.pass_phrase);
return true;
}
- case MENU_EXPORT: {
+ case Id.menu.export: {
mSelectedItem = groupPosition;
- showDialog(DIALOG_EXPORT_KEY);
+ showDialog(Id.dialog.export_key);
return true;
}
- case MENU_DELETE: {
+ case Id.menu.delete: {
mSelectedItem = groupPosition;
- showDialog(DIALOG_DELETE_KEY);
+ showDialog(Id.dialog.delete_key);
return true;
}
@@ -298,7 +162,7 @@ public class SecretKeyListActivity extends ExpandableListActivity public boolean onChildClick(ExpandableListView parent, View v, int groupPosition,
int childPosition, long id) {
mSelectedItem = groupPosition;
- showDialog(AskForSecretKeyPassPhrase.DIALOG_PASS_PHRASE);
+ showDialog(Id.dialog.pass_phrase);
return true;
}
@@ -307,7 +171,7 @@ public class SecretKeyListActivity extends ExpandableListActivity boolean singleKeyExport = false;
switch (id) {
- case DIALOG_DELETE_KEY: {
+ case Id.dialog.delete_key: {
PGPSecretKeyRing keyRing = Apg.getSecretKeyRings().get(mSelectedItem);
String userId = Apg.getMainUserIdSafe(this, Apg.getMasterKey(keyRing));
@@ -321,20 +185,20 @@ public class SecretKeyListActivity extends ExpandableListActivity public void onClick(DialogInterface dialog, int id) {
deleteKey(mSelectedItem);
mSelectedItem = -1;
- removeDialog(DIALOG_DELETE_KEY);
+ removeDialog(Id.dialog.delete_key);
}
});
builder.setNegativeButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mSelectedItem = -1;
- removeDialog(DIALOG_DELETE_KEY);
+ removeDialog(Id.dialog.delete_key);
}
});
return builder.create();
}
- case DIALOG_IMPORT_KEYS: {
+ case Id.dialog.import_keys: {
return FileDialog.build(this, "Import Keys",
"Please specify which file to import from.",
mImportFilename,
@@ -342,33 +206,33 @@ public class SecretKeyListActivity extends ExpandableListActivity @Override
public void onOkClick(String filename) {
- removeDialog(DIALOG_IMPORT_KEYS);
+ removeDialog(Id.dialog.import_keys);
mImportFilename = filename;
importKeys();
}
@Override
public void onCancelClick() {
- removeDialog(DIALOG_IMPORT_KEYS);
+ removeDialog(Id.dialog.import_keys);
}
},
getString(R.string.filemanager_title_open),
getString(R.string.filemanager_btn_open));
}
- case DIALOG_EXPORT_KEY: {
+ case Id.dialog.export_key: {
singleKeyExport = true;
- // break intentionally omitted, to use the DIALOG_EXPORT_KEYS dialog
+ // break intentionally omitted, to use the Id.dialog.export_keys dialog
}
- case DIALOG_EXPORT_KEYS: {
+ case Id.dialog.export_keys: {
String title = "Export Key";
if (!singleKeyExport) {
// plural "Keys"
title += "s";
}
- final int thisDialogId = (singleKeyExport ? DIALOG_DELETE_KEY : DIALOG_EXPORT_KEYS);
+ final int thisDialogId = (singleKeyExport ? Id.dialog.delete_key : Id.dialog.export_keys);
return FileDialog.build(this, title,
"Please specify which file to export to.\n" +
@@ -393,23 +257,7 @@ public class SecretKeyListActivity extends ExpandableListActivity getString(R.string.filemanager_btn_save));
}
- case DIALOG_IMPORTING: {
- mProgressDialog = new ProgressDialog(this);
- mProgressDialog.setMessage("importing...");
- mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
- mProgressDialog.setCancelable(false);
- return mProgressDialog;
- }
-
- case DIALOG_EXPORTING: {
- mProgressDialog = new ProgressDialog(this);
- mProgressDialog.setMessage("exporting...");
- mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
- mProgressDialog.setCancelable(false);
- return mProgressDialog;
- }
-
- case AskForSecretKeyPassPhrase.DIALOG_PASS_PHRASE: {
+ case Id.dialog.pass_phrase: {
PGPSecretKeyRing keyRing = Apg.getSecretKeyRings().get(mSelectedItem);
long keyId = keyRing.getSecretKey().getKeyID();
return AskForSecretKeyPassPhrase.createDialog(this, keyId, this);
@@ -418,14 +266,15 @@ public class SecretKeyListActivity extends ExpandableListActivity return super.onCreateDialog(id);
}
+ @Override
public void passPhraseCallback(String passPhrase) {
- Apg.setPassPhrase(passPhrase);
+ super.passPhraseCallback(passPhrase);
editKey();
}
private void createKey() {
Intent intent = new Intent(this, EditKeyActivity.class);
- startActivityForResult(intent, CREATE_SECRET_KEY);
+ startActivityForResult(intent, Id.message.create_key);
}
private void editKey() {
@@ -433,21 +282,21 @@ public class SecretKeyListActivity extends ExpandableListActivity long keyId = keyRing.getSecretKey().getKeyID();
Intent intent = new Intent(this, EditKeyActivity.class);
intent.putExtra("keyId", keyId);
- startActivityForResult(intent, EDIT_SECRET_KEY);
+ startActivityForResult(intent, Id.message.edit_key);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
- case CREATE_SECRET_KEY: // intentionally no break
- case EDIT_SECRET_KEY: {
+ case Id.message.create_key: // intentionally no break
+ case Id.message.edit_key: {
if (resultCode == RESULT_OK) {
refreshList();
}
break;
}
- case FileDialog.REQUEST_CODE_PICK_FILE_OR_DIRECTORY: {
+ case Id.request.filename: {
if (resultCode == RESULT_OK && data != null) {
String filename = data.getDataString();
if (filename != null) {
@@ -465,42 +314,42 @@ public class SecretKeyListActivity extends ExpandableListActivity return;
}
- default:
+ default: {
break;
+ }
}
super.onActivityResult(requestCode, resultCode, data);
}
public void importKeys() {
- showDialog(DIALOG_IMPORTING);
- mTask = TASK_IMPORT;
- mRunningThread = new Thread(this);
- mRunningThread.start();
+ showDialog(Id.dialog.importing);
+ mTask = Id.task.import_keys;
+ startThread();
}
public void exportKeys() {
- showDialog(DIALOG_EXPORTING);
- mTask = TASK_EXPORT;
- mRunningThread = new Thread(this);
- mRunningThread.start();
+ showDialog(Id.dialog.exporting);
+ mTask = Id.task.export_keys;
+ startThread();
}
+ @Override
public void run() {
String error = null;
Bundle data = new Bundle();
Message msg = new Message();
String filename = null;
- if (mTask == TASK_IMPORT) {
+ if (mTask == Id.task.import_keys) {
filename = mImportFilename;
} else {
filename = mExportFilename;
}
try {
- if (mTask == TASK_IMPORT) {
- data = Apg.importKeyRings(this, Apg.TYPE_SECRET, filename, this);
+ if (mTask == Id.task.import_keys) {
+ data = Apg.importKeyRings(this, Id.type.secret_key, filename, this);
} else {
Vector<Object> keys = new Vector<Object>();
if (mSelectedItem == -1) {
@@ -522,10 +371,10 @@ public class SecretKeyListActivity extends ExpandableListActivity error = e.getMessage();
}
- if (mTask == TASK_IMPORT) {
- data.putInt("type", MESSAGE_IMPORT_DONE);
+ if (mTask == Id.task.import_keys) {
+ data.putInt("type", Id.message.import_done);
} else {
- data.putInt("type", MESSAGE_EXPORT_DONE);
+ data.putInt("type", Id.message.export_done);
}
if (error != null) {
@@ -533,7 +382,7 @@ public class SecretKeyListActivity extends ExpandableListActivity }
msg.setData(data);
- mHandler.sendMessage(msg);
+ sendMessage(msg);
}
private void deleteKey(int index) {
@@ -543,8 +392,75 @@ public class SecretKeyListActivity extends ExpandableListActivity }
private void refreshList() {
- ((SecretKeyListAdapter) getExpandableListAdapter())
- .notifyDataSetChanged();
+ ((SecretKeyListAdapter) mList.getExpandableListAdapter()).notifyDataSetChanged();
+ }
+
+ @Override
+ public void doneCallback(Message msg) {
+ super.doneCallback(msg);
+
+ Bundle data = msg.getData();
+ if (data != null) {
+ int type = data.getInt("type");
+ switch (type) {
+ case Id.message.import_done: {
+ removeDialog(Id.dialog.importing);
+
+ String error = data.getString("error");
+ if (error != null) {
+ Toast.makeText(SecretKeyListActivity.this,
+ "Error: " + data.getString("error"),
+ Toast.LENGTH_SHORT).show();
+ } else {
+ int added = data.getInt("added");
+ int updated = data.getInt("updated");
+ String message;
+ if (added > 0 && updated > 0) {
+ message = "Succssfully added " + added + " keys and updated " +
+ updated + " keys.";
+ } else if (added > 0) {
+ message = "Succssfully added " + added + " keys.";
+ } else if (updated > 0) {
+ message = "Succssfully updated " + updated + " keys.";
+ } else {
+ message = "No keys added or updated.";
+ }
+ Toast.makeText(SecretKeyListActivity.this, message,
+ Toast.LENGTH_SHORT).show();
+ }
+ refreshList();
+ break;
+ }
+
+ case Id.message.export_done: {
+ removeDialog(Id.dialog.exporting);
+
+ String error = data.getString("error");
+ if (error != null) {
+ Toast.makeText(SecretKeyListActivity.this,
+ "Error: " + data.getString("error"),
+ Toast.LENGTH_SHORT).show();
+ } else {
+ int exported = data.getInt("exported");
+ String message;
+ if (exported == 1) {
+ message = "Succssfully exported 1 key.";
+ } else if (exported > 0) {
+ message = "Succssfully exported " + exported + " keys.";
+ } else{
+ message = "No keys exported.";
+ }
+ Toast.makeText(SecretKeyListActivity.this, message,
+ Toast.LENGTH_SHORT).show();
+ }
+ break;
+ }
+
+ default: {
+ break;
+ }
+ }
+ }
}
private static class SecretKeyListAdapter extends BaseExpandableListAdapter {
diff --git a/src/org/thialfihar/android/apg/SelectPublicKeyListActivity.java b/src/org/thialfihar/android/apg/SelectPublicKeyListActivity.java index 551d9508e..7874555df 100644 --- a/src/org/thialfihar/android/apg/SelectPublicKeyListActivity.java +++ b/src/org/thialfihar/android/apg/SelectPublicKeyListActivity.java @@ -16,40 +16,28 @@ package org.thialfihar.android.apg; -import java.text.DateFormat; import java.util.Collections; -import java.util.Date; import java.util.Vector; import org.bouncycastle2.openpgp.PGPPublicKey; import org.bouncycastle2.openpgp.PGPPublicKeyRing; -import org.thialfihar.android.apg.utils.IterableIterator; import android.app.Activity; -import android.content.Context; import android.content.Intent; import android.os.Bundle; -import android.view.LayoutInflater; import android.view.View; -import android.view.ViewGroup; import android.view.View.OnClickListener; -import android.widget.BaseAdapter; import android.widget.Button; -import android.widget.CheckBox; import android.widget.ListView; -import android.widget.TextView; -public class SelectPublicKeyListActivity extends Activity { - protected Vector<PGPPublicKeyRing> mKeyRings; - protected LayoutInflater mInflater; +public class SelectPublicKeyListActivity extends BaseActivity { protected Intent mIntent; protected ListView mList; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - - mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); + setContentView(R.layout.select_public_key); // fill things mIntent = getIntent(); @@ -58,17 +46,15 @@ public class SelectPublicKeyListActivity extends Activity { selectedKeyIds = mIntent.getExtras().getLongArray("selection"); } - Apg.initialize(this); - mKeyRings = (Vector<PGPPublicKeyRing>) Apg.getPublicKeyRings().clone(); - Collections.sort(mKeyRings, new Apg.PublicKeySorter()); - - setContentView(R.layout.select_public_key); - mList = (ListView) findViewById(R.id.list); - mList.setAdapter(new PublicKeyListAdapter(this)); + Vector<PGPPublicKeyRing> keyRings = + (Vector<PGPPublicKeyRing>) Apg.getPublicKeyRings().clone(); + Collections.sort(keyRings, new Apg.PublicKeySorter()); + mList.setAdapter(new SelectPublicKeyListAdapter(mList, keyRings)); + if (selectedKeyIds != null) { - for (int i = 0; i < mKeyRings.size(); ++i) { - PGPPublicKeyRing keyRing = mKeyRings.get(i); + for (int i = 0; i < keyRings.size(); ++i) { + PGPPublicKeyRing keyRing = keyRings.get(i); PGPPublicKey key = Apg.getMasterKey(keyRing); if (key == null) { continue; @@ -122,138 +108,4 @@ public class SelectPublicKeyListActivity extends Activity { setResult(RESULT_OK, data); finish(); } - - private class PublicKeyListAdapter extends BaseAdapter { - public PublicKeyListAdapter(Context context) { - } - - @Override - public boolean isEnabled(int position) { - PGPPublicKeyRing keyRing = mKeyRings.get(position); - - if (Apg.getMasterKey(keyRing) == null) { - return false; - } - - Vector<PGPPublicKey> encryptKeys = Apg.getUsableEncryptKeys(keyRing); - if (encryptKeys.size() == 0) { - return false; - } - - return true; - } - - @Override - public boolean hasStableIds() { - return true; - } - - @Override - public int getCount() { - return mKeyRings.size(); - } - - @Override - public Object getItem(int position) { - return mKeyRings.get(position); - } - - @Override - public long getItemId(int position) { - PGPPublicKeyRing keyRing = mKeyRings.get(position); - PGPPublicKey key = Apg.getMasterKey(keyRing); - if (key != null) { - return key.getKeyID(); - } - - return 0; - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - View view = mInflater.inflate(R.layout.select_public_key_item, null); - boolean enabled = isEnabled(position); - - PGPPublicKeyRing keyRing = mKeyRings.get(position); - PGPPublicKey key = null; - for (PGPPublicKey tKey : new IterableIterator<PGPPublicKey>(keyRing.getPublicKeys())) { - if (tKey.isMasterKey()) { - key = tKey; - break; - } - } - - Vector<PGPPublicKey> encryptKeys = Apg.getEncryptKeys(keyRing); - Vector<PGPPublicKey> usableKeys = Apg.getUsableEncryptKeys(keyRing); - - TextView mainUserId = (TextView) view.findViewById(R.id.main_user_id); - mainUserId.setText(R.string.unknown_user_id); - TextView mainUserIdRest = (TextView) view.findViewById(R.id.main_user_id_rest); - mainUserIdRest.setText(""); - TextView keyId = (TextView) view.findViewById(R.id.key_id); - keyId.setText("<no key>"); - TextView creation = (TextView) view.findViewById(R.id.creation); - creation.setText("-"); - TextView expiry = (TextView) view.findViewById(R.id.expiry); - expiry.setText("no expire"); - TextView status = (TextView) view.findViewById(R.id.status); - status.setText("???"); - - if (key != null) { - String userId = Apg.getMainUserId(key); - if (userId != null) { - String chunks[] = userId.split(" <", 2); - userId = chunks[0]; - if (chunks.length > 1) { - mainUserIdRest.setText("<" + chunks[1]); - } - mainUserId.setText(userId); - } - - keyId.setText("" + Long.toHexString(key.getKeyID() & 0xffffffffL)); - } - - if (mainUserIdRest.getText().length() == 0) { - mainUserIdRest.setVisibility(View.GONE); - } - - PGPPublicKey timespanKey = key; - if (usableKeys.size() > 0) { - timespanKey = usableKeys.get(0); - status.setText("can encrypt"); - } else if (encryptKeys.size() > 0) { - timespanKey = encryptKeys.get(0); - Date now = new Date(); - if (now.compareTo(Apg.getCreationDate(timespanKey)) > 0) { - status.setText("not valid"); - } else { - status.setText("expired"); - } - } else { - status.setText("no key"); - } - - creation.setText(DateFormat.getDateInstance().format(Apg.getCreationDate(timespanKey))); - Date expiryDate = Apg.getExpiryDate(timespanKey); - if (expiryDate != null) { - expiry.setText(DateFormat.getDateInstance().format(expiryDate)); - } - - status.setText(status.getText() + " "); - - CheckBox selected = (CheckBox) view.findViewById(R.id.selected); - selected.setChecked(mList.isItemChecked(position)); - - view.setEnabled(enabled); - mainUserId.setEnabled(enabled); - mainUserIdRest.setEnabled(enabled); - keyId.setEnabled(enabled); - creation.setEnabled(enabled); - expiry.setEnabled(enabled); - selected.setEnabled(enabled); - status.setEnabled(enabled); - - return view; - } - } }
\ No newline at end of file diff --git a/src/org/thialfihar/android/apg/SelectPublicKeyListAdapter.java b/src/org/thialfihar/android/apg/SelectPublicKeyListAdapter.java new file mode 100644 index 000000000..12d0c5d53 --- /dev/null +++ b/src/org/thialfihar/android/apg/SelectPublicKeyListAdapter.java @@ -0,0 +1,186 @@ +/*
+ * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
+ *
+ * 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;
+
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.Vector;
+
+import org.bouncycastle2.openpgp.PGPPublicKey;
+import org.bouncycastle2.openpgp.PGPPublicKeyRing;
+import org.thialfihar.android.apg.utils.IterableIterator;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.CheckBox;
+import android.widget.ListView;
+import android.widget.TextView;
+
+public class SelectPublicKeyListAdapter extends BaseAdapter {
+ protected Vector<PGPPublicKeyRing> mKeyRings;
+ protected LayoutInflater mInflater;
+ protected ListView mParent;
+
+ public SelectPublicKeyListAdapter(ListView parent,
+ Vector<PGPPublicKeyRing> keyRings) {
+ setKeyRings(keyRings);
+ mParent = parent;
+ mInflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ }
+
+ public void setKeyRings(Vector<PGPPublicKeyRing> keyRings) {
+ mKeyRings = keyRings;
+ notifyDataSetChanged();
+ }
+
+ public Vector<PGPPublicKeyRing> getKeyRings() {
+ return mKeyRings;
+ }
+
+ @Override
+ public boolean isEnabled(int position) {
+ PGPPublicKeyRing keyRing = mKeyRings.get(position);
+
+ if (Apg.getMasterKey(keyRing) == null) {
+ return false;
+ }
+
+ Vector<PGPPublicKey> encryptKeys = Apg.getUsableEncryptKeys(keyRing);
+ if (encryptKeys.size() == 0) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean hasStableIds() {
+ return true;
+ }
+
+ @Override
+ public int getCount() {
+ return mKeyRings.size();
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return mKeyRings.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ PGPPublicKeyRing keyRing = mKeyRings.get(position);
+ PGPPublicKey key = Apg.getMasterKey(keyRing);
+ if (key != null) {
+ return key.getKeyID();
+ }
+
+ return 0;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View view = mInflater.inflate(R.layout.select_public_key_item, null);
+ boolean enabled = isEnabled(position);
+
+ PGPPublicKeyRing keyRing = mKeyRings.get(position);
+ PGPPublicKey key = null;
+ for (PGPPublicKey tKey : new IterableIterator<PGPPublicKey>(keyRing.getPublicKeys())) {
+ if (tKey.isMasterKey()) {
+ key = tKey;
+ break;
+ }
+ }
+
+ Vector<PGPPublicKey> encryptKeys = Apg.getEncryptKeys(keyRing);
+ Vector<PGPPublicKey> usableKeys = Apg.getUsableEncryptKeys(keyRing);
+
+ TextView mainUserId = (TextView) view.findViewById(R.id.main_user_id);
+ mainUserId.setText(R.string.unknown_user_id);
+ TextView mainUserIdRest = (TextView) view.findViewById(R.id.main_user_id_rest);
+ mainUserIdRest.setText("");
+ TextView keyId = (TextView) view.findViewById(R.id.key_id);
+ keyId.setText("<no key>");
+ TextView creation = (TextView) view.findViewById(R.id.creation);
+ creation.setText("-");
+ TextView expiry = (TextView) view.findViewById(R.id.expiry);
+ expiry.setText("no expire");
+ TextView status = (TextView) view.findViewById(R.id.status);
+ status.setText("???");
+
+ if (key != null) {
+ String userId = Apg.getMainUserId(key);
+ if (userId != null) {
+ String chunks[] = userId.split(" <", 2);
+ userId = chunks[0];
+ if (chunks.length > 1) {
+ mainUserIdRest.setText("<" + chunks[1]);
+ }
+ mainUserId.setText(userId);
+ }
+
+ keyId.setText("" + Long.toHexString(key.getKeyID() & 0xffffffffL));
+ }
+
+ if (mainUserIdRest.getText().length() == 0) {
+ mainUserIdRest.setVisibility(View.GONE);
+ }
+
+ PGPPublicKey timespanKey = key;
+ if (usableKeys.size() > 0) {
+ timespanKey = usableKeys.get(0);
+ status.setText("can encrypt");
+ } else if (encryptKeys.size() > 0) {
+ timespanKey = encryptKeys.get(0);
+ Date now = new Date();
+ if (now.compareTo(Apg.getCreationDate(timespanKey)) > 0) {
+ status.setText("not valid");
+ } else {
+ status.setText("expired");
+ }
+ } else {
+ status.setText("no key");
+ }
+
+ creation.setText(DateFormat.getDateInstance().format(Apg.getCreationDate(timespanKey)));
+ Date expiryDate = Apg.getExpiryDate(timespanKey);
+ if (expiryDate != null) {
+ expiry.setText(DateFormat.getDateInstance().format(expiryDate));
+ }
+
+ status.setText(status.getText() + " ");
+
+ CheckBox selected = (CheckBox) view.findViewById(R.id.selected);
+
+ selected.setChecked(mParent.isItemChecked(position));
+
+ view.setEnabled(enabled);
+ mainUserId.setEnabled(enabled);
+ mainUserIdRest.setEnabled(enabled);
+ keyId.setEnabled(enabled);
+ creation.setEnabled(enabled);
+ expiry.setEnabled(enabled);
+ selected.setEnabled(enabled);
+ status.setEnabled(enabled);
+
+ return view;
+ }
+}
diff --git a/src/org/thialfihar/android/apg/SelectSecretKeyListActivity.java b/src/org/thialfihar/android/apg/SelectSecretKeyListActivity.java index da7094c53..2d117e5f3 100644 --- a/src/org/thialfihar/android/apg/SelectSecretKeyListActivity.java +++ b/src/org/thialfihar/android/apg/SelectSecretKeyListActivity.java @@ -38,7 +38,7 @@ import android.widget.ListView; import android.widget.TextView; import android.widget.AdapterView.OnItemClickListener; -public class SelectSecretKeyListActivity extends Activity { +public class SelectSecretKeyListActivity extends BaseActivity { protected Vector<PGPSecretKeyRing> mKeyRings; protected LayoutInflater mInflater; protected Intent mIntent; @@ -55,8 +55,6 @@ public class SelectSecretKeyListActivity extends Activity { // fill things mIntent = getIntent(); - Apg.initialize(this); - mKeyRings = (Vector<PGPSecretKeyRing>) Apg.getSecretKeyRings().clone(); Collections.sort(mKeyRings, new Apg.SecretKeySorter()); |