externalizing code into service

This commit is contained in:
Dominik 2012-04-25 15:10:12 +02:00
parent da96aacf55
commit f06fcd989b
10 changed files with 686 additions and 551 deletions

View File

@ -77,6 +77,7 @@ import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment; import android.os.Environment;
import android.os.Message; import android.os.Message;
import android.util.Log;
import android.view.ViewGroup; import android.view.ViewGroup;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
@ -110,7 +111,8 @@ import java.util.Vector;
import java.util.regex.Pattern; import java.util.regex.Pattern;
public class Apg { public class Apg {
private static final String PACKAGE_NAME = "org.thialfihar.android.apg"; public static final String PACKAGE_NAME = "org.thialfihar.android.apg";
private static final String INTENT_PREFIX = "org.thialfihar.android.apg.intent."; private static final String INTENT_PREFIX = "org.thialfihar.android.apg.intent.";
public static class Intent { public static class Intent {
@ -378,14 +380,16 @@ public class Apg {
secretKey = it.next(); secretKey = it.next();
} }
Log.d(Constants.TAG, "new secretkey: " + secretKey.toString());
return secretKey; return secretKey;
} }
public static void buildSecretKey(Context context, ArrayList<String> userIds, public static void buildSecretKey(Context context, ArrayList<String> userIds,
ArrayList<PGPSecretKey> keys, ArrayList<Integer> keysUsages, long masterKeyId, String oldPassPhrase, String newPassPhrase, ArrayList<PGPSecretKey> keys, ArrayList<Integer> keysUsages, long masterKeyId,
ProgressDialogUpdater progress) throws Apg.GeneralException, NoSuchProviderException, String oldPassPhrase, String newPassPhrase, ProgressDialogUpdater progress)
PGPException, NoSuchAlgorithmException, SignatureException, IOException, throws Apg.GeneralException, NoSuchProviderException, PGPException,
Database.GeneralException { NoSuchAlgorithmException, SignatureException, IOException, Database.GeneralException {
if (progress != null) if (progress != null)
progress.setProgress(R.string.progress_buildingKey, 0, 100); progress.setProgress(R.string.progress_buildingKey, 0, 100);
@ -400,64 +404,63 @@ public class Apg {
newPassPhrase = ""; newPassPhrase = "";
} }
// Vector<String> userIds = new Vector<String>(); // Vector<String> userIds = new Vector<String>();
// Vector<PGPSecretKey> keys = new Vector<PGPSecretKey>(); // Vector<PGPSecretKey> keys = new Vector<PGPSecretKey>();
// ViewGroup userIdEditors = userIdsView.getEditors(); // ViewGroup userIdEditors = userIdsView.getEditors();
// ViewGroup keyEditors = keysView.getEditors(); // ViewGroup keyEditors = keysView.getEditors();
// //
// boolean gotMainUserId = false; // boolean gotMainUserId = false;
// for (int i = 0; i < userIdEditors.getChildCount(); ++i) { // for (int i = 0; i < userIdEditors.getChildCount(); ++i) {
// UserIdEditor editor = (UserIdEditor) userIdEditors.getChildAt(i); // UserIdEditor editor = (UserIdEditor) userIdEditors.getChildAt(i);
// String userId = null; // String userId = null;
// try { // try {
// userId = editor.getValue(); // userId = editor.getValue();
// } catch (UserIdEditor.NoNameException e) { // } catch (UserIdEditor.NoNameException e) {
// throw new Apg.GeneralException(context.getString(R.string.error_userIdNeedsAName)); // throw new Apg.GeneralException(context.getString(R.string.error_userIdNeedsAName));
// } catch (UserIdEditor.NoEmailException e) { // } catch (UserIdEditor.NoEmailException e) {
// throw new Apg.GeneralException( // throw new Apg.GeneralException(
// context.getString(R.string.error_userIdNeedsAnEmailAddress)); // context.getString(R.string.error_userIdNeedsAnEmailAddress));
// } catch (UserIdEditor.InvalidEmailException e) { // } catch (UserIdEditor.InvalidEmailException e) {
// throw new Apg.GeneralException("" + e); // throw new Apg.GeneralException("" + e);
// } // }
// //
// if (userId.equals("")) { // if (userId.equals("")) {
// continue; // continue;
// } // }
// //
// if (editor.isMainUserId()) { // if (editor.isMainUserId()) {
// userIds.insertElementAt(userId, 0); // userIds.insertElementAt(userId, 0);
// gotMainUserId = true; // gotMainUserId = true;
// } else { // } else {
// userIds.add(userId); // userIds.add(userId);
// } // }
// } // }
// if (userIds.size() == 0) { // if (userIds.size() == 0) {
// throw new Apg.GeneralException(context.getString(R.string.error_keyNeedsAUserId)); // throw new Apg.GeneralException(context.getString(R.string.error_keyNeedsAUserId));
// } // }
// //
// if (!gotMainUserId) { // if (!gotMainUserId) {
// throw new Apg.GeneralException( // throw new Apg.GeneralException(
// context.getString(R.string.error_mainUserIdMustNotBeEmpty)); // context.getString(R.string.error_mainUserIdMustNotBeEmpty));
// } // }
// if (keyEditors.getChildCount() == 0) { // if (keyEditors.getChildCount() == 0) {
// throw new Apg.GeneralException(context.getString(R.string.error_keyNeedsMasterKey)); // throw new Apg.GeneralException(context.getString(R.string.error_keyNeedsMasterKey));
// } // }
// //
// for (int i = 0; i < keyEditors.getChildCount(); ++i) { // for (int i = 0; i < keyEditors.getChildCount(); ++i) {
// KeyEditor editor = (KeyEditor) keyEditors.getChildAt(i); // KeyEditor editor = (KeyEditor) keyEditors.getChildAt(i);
// keys.add(editor.getValue()); // keys.add(editor.getValue());
// } // }
if (progress != null) if (progress != null)
progress.setProgress(R.string.progress_preparingMasterKey, 10, 100); progress.setProgress(R.string.progress_preparingMasterKey, 10, 100);
// KeyEditor keyEditor = (KeyEditor) keyEditors.getChildAt(0);
// KeyEditor keyEditor = (KeyEditor) keyEditors.getChildAt(0); // int usageId = keyEditor.getUsage();
// int usageId = keyEditor.getUsage();
int usageId = keysUsages.get(0); int usageId = keysUsages.get(0);
boolean canSign = (usageId == Id.choice.usage.sign_only || usageId == Id.choice.usage.sign_and_encrypt); boolean canSign = (usageId == Id.choice.usage.sign_only || usageId == Id.choice.usage.sign_and_encrypt);
boolean canEncrypt = (usageId == Id.choice.usage.encrypt_only || usageId == Id.choice.usage.sign_and_encrypt); boolean canEncrypt = (usageId == Id.choice.usage.encrypt_only || usageId == Id.choice.usage.sign_and_encrypt);
@ -504,17 +507,17 @@ public class Apg {
hashedPacketsGen.setPreferredCompressionAlgorithms(true, PREFERRED_COMPRESSION_ALGORITHMS); hashedPacketsGen.setPreferredCompressionAlgorithms(true, PREFERRED_COMPRESSION_ALGORITHMS);
// TODO: this doesn't work quite right yet // TODO: this doesn't work quite right yet
// if (keyEditor.getExpiryDate() != null) { // if (keyEditor.getExpiryDate() != null) {
// GregorianCalendar creationDate = new GregorianCalendar(); // GregorianCalendar creationDate = new GregorianCalendar();
// creationDate.setTime(getCreationDate(masterKey)); // creationDate.setTime(getCreationDate(masterKey));
// GregorianCalendar expiryDate = keyEditor.getExpiryDate(); // GregorianCalendar expiryDate = keyEditor.getExpiryDate();
// long numDays = Utils.getNumDaysBetween(creationDate, expiryDate); // long numDays = Utils.getNumDaysBetween(creationDate, expiryDate);
// if (numDays <= 0) { // if (numDays <= 0) {
// throw new GeneralException( // throw new GeneralException(
// context.getString(R.string.error_expiryMustComeAfterCreation)); // context.getString(R.string.error_expiryMustComeAfterCreation));
// } // }
// hashedPacketsGen.setKeyExpirationTime(true, numDays * 86400); // hashedPacketsGen.setKeyExpirationTime(true, numDays * 86400);
// } // }
if (progress != null) { if (progress != null) {
progress.setProgress(R.string.progress_buildingMasterKeyRing, 30, 100); progress.setProgress(R.string.progress_buildingMasterKeyRing, 30, 100);
@ -531,7 +534,7 @@ public class Apg {
if (progress != null) if (progress != null)
progress.setProgress(40 + 50 * (i - 1) / (keys.size() - 1), 100); progress.setProgress(40 + 50 * (i - 1) / (keys.size() - 1), 100);
PGPSecretKey subKey = keys.get(i); PGPSecretKey subKey = keys.get(i);
// keyEditor = (KeyEditor) keyEditors.getChildAt(i); // keyEditor = (KeyEditor) keyEditors.getChildAt(i);
PGPPublicKey subPublicKey = subKey.getPublicKey(); PGPPublicKey subPublicKey = subKey.getPublicKey();
PGPPrivateKey subPrivateKey = subKey.extractPrivateKey(oldPassPhrase.toCharArray(), PGPPrivateKey subPrivateKey = subKey.extractPrivateKey(oldPassPhrase.toCharArray(),
new BouncyCastleProvider()); new BouncyCastleProvider());
@ -543,8 +546,8 @@ public class Apg {
unhashedPacketsGen = new PGPSignatureSubpacketGenerator(); unhashedPacketsGen = new PGPSignatureSubpacketGenerator();
keyFlags = 0; keyFlags = 0;
// usageId = keyEditor.getUsage(); // usageId = keyEditor.getUsage();
usageId = keysUsages.get(i); usageId = keysUsages.get(i);
canSign = (usageId == Id.choice.usage.sign_only || usageId == Id.choice.usage.sign_and_encrypt); canSign = (usageId == Id.choice.usage.sign_only || usageId == Id.choice.usage.sign_and_encrypt);
canEncrypt = (usageId == Id.choice.usage.encrypt_only || usageId == Id.choice.usage.sign_and_encrypt); canEncrypt = (usageId == Id.choice.usage.encrypt_only || usageId == Id.choice.usage.sign_and_encrypt);
@ -557,17 +560,17 @@ public class Apg {
hashedPacketsGen.setKeyFlags(true, keyFlags); hashedPacketsGen.setKeyFlags(true, keyFlags);
// TODO: this doesn't work quite right yet // TODO: this doesn't work quite right yet
// if (keyEditor.getExpiryDate() != null) { // if (keyEditor.getExpiryDate() != null) {
// GregorianCalendar creationDate = new GregorianCalendar(); // GregorianCalendar creationDate = new GregorianCalendar();
// creationDate.setTime(getCreationDate(masterKey)); // creationDate.setTime(getCreationDate(masterKey));
// GregorianCalendar expiryDate = keyEditor.getExpiryDate(); // GregorianCalendar expiryDate = keyEditor.getExpiryDate();
// long numDays = Utils.getNumDaysBetween(creationDate, expiryDate); // long numDays = Utils.getNumDaysBetween(creationDate, expiryDate);
// if (numDays <= 0) { // if (numDays <= 0) {
// throw new GeneralException( // throw new GeneralException(
// context.getString(R.string.error_expiryMustComeAfterCreation)); // context.getString(R.string.error_expiryMustComeAfterCreation));
// } // }
// hashedPacketsGen.setKeyExpirationTime(true, numDays * 86400); // hashedPacketsGen.setKeyExpirationTime(true, numDays * 86400);
// } // }
keyGen.addSubKey(subKeyPair, hashedPacketsGen.generate(), unhashedPacketsGen.generate()); keyGen.addSubKey(subKeyPair, hashedPacketsGen.generate(), unhashedPacketsGen.generate());
} }

View File

@ -55,20 +55,35 @@ public final class Id {
} }
} }
// use only lower 16 bits due to compatibility lib
public static final class message { public static final class message {
public static final int progress_update = 0x21070001; public static final int progress_update = 0x00006001;
public static final int done = 0x21070002; public static final int done = 0x00006002;
public static final int import_keys = 0x21070003; public static final int import_keys = 0x00006003;
public static final int export_keys = 0x21070004; public static final int export_keys = 0x00006004;
public static final int import_done = 0x21070005; public static final int import_done = 0x00006005;
public static final int export_done = 0x21070006; public static final int export_done = 0x00006006;
public static final int create_key = 0x21070007; public static final int create_key = 0x00006007;
public static final int edit_key = 0x21070008; public static final int edit_key = 0x00006008;
public static final int delete_done = 0x21070009; public static final int delete_done = 0x00006009;
public static final int query_done = 0x21070010; public static final int query_done = 0x00006010;
public static final int unknown_signature_key = 0x21070011; public static final int unknown_signature_key = 0x00006011;
} }
// 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 int delete_done = 0x21070009;
// public static final int query_done = 0x21070010;
// public static final int unknown_signature_key = 0x21070011;
// }
public static final class request { public static final class request {
public static final int public_keys = 0x21070001; public static final int public_keys = 0x21070001;
public static final int secret_keys = 0x21070002; public static final int secret_keys = 0x21070002;

View File

@ -0,0 +1,103 @@
/*
* Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de>
*
* 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.service;
import org.thialfihar.android.apg.R;
import org.thialfihar.android.apg.ui.ProgressDialogFragment;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.Toast;
public class ApgHandler extends Handler {
// possible messages send from this service to handler on ui
public static final int MESSAGE_OKAY = 1;
public static final int MESSAGE_EXCEPTION = 2;
public static final int MESSAGE_UPDATE_PROGRESS = 3;
// possible data keys for messages
public static final String ERROR = "error";
public static final String PROGRESS = "progress";
public static final String PROGRESS_MAX = "max";
public static final String MESSAGE = "message";
public static final String MESSAGE_ID = "message_id";
// generate key results
public static final String NEW_KEY = "new_key";
Activity mActivity;
ProgressDialogFragment mProgressDialogFragment;
public ApgHandler(Activity activity) {
this.mActivity = activity;
}
public ApgHandler(Activity activity, ProgressDialogFragment progressDialogFragment) {
this.mActivity = activity;
this.mProgressDialogFragment = progressDialogFragment;
}
@Override
public void handleMessage(Message message) {
Bundle data = message.getData();
switch (message.arg1) {
case MESSAGE_OKAY:
mProgressDialogFragment.dismiss();
break;
case MESSAGE_EXCEPTION:
mProgressDialogFragment.dismiss();
if (data.containsKey(ERROR)) {
Toast.makeText(mActivity,
mActivity.getString(R.string.errorMessage, data.getString(ERROR)),
Toast.LENGTH_SHORT).show();
}
break;
case MESSAGE_UPDATE_PROGRESS:
if (data.containsKey(PROGRESS) && data.containsKey(PROGRESS_MAX)) {
if (data.containsKey(MESSAGE)) {
mProgressDialogFragment.setProgress(data.getString(MESSAGE),
data.getInt(PROGRESS), data.getInt(PROGRESS_MAX));
} else if (data.containsKey(MESSAGE_ID)) {
mProgressDialogFragment.setProgress(data.getInt(MESSAGE_ID),
data.getInt(PROGRESS), data.getInt(PROGRESS_MAX));
} else {
mProgressDialogFragment.setProgress(data.getInt(PROGRESS),
data.getInt(PROGRESS_MAX));
}
}
break;
default:
break;
}
}
}

View File

@ -1,24 +1,28 @@
/** /*
* TODO: * Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de>
* - Reimplement all the threads in the activitys as intents in this intentService *
* - This IntentService stopps itself after an action is executed * 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.service; package org.thialfihar.android.apg.service;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator;
import java.util.Vector;
import org.spongycastle.openpgp.PGPObjectFactory;
import org.spongycastle.openpgp.PGPSecretKey; import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.thialfihar.android.apg.Apg; import org.thialfihar.android.apg.Apg;
import org.thialfihar.android.apg.Constants; import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.ProgressDialogUpdater; import org.thialfihar.android.apg.ProgressDialogUpdater;
import org.thialfihar.android.apg.ui.widget.KeyEditor; import org.thialfihar.android.apg.util.Utils;
import org.thialfihar.android.apg.ui.widget.SectionView;
import android.app.IntentService; import android.app.IntentService;
import android.content.Intent; import android.content.Intent;
@ -28,7 +32,12 @@ import android.os.Messenger;
import android.os.RemoteException; import android.os.RemoteException;
import android.util.Log; import android.util.Log;
//TODO: ProgressDialogUpdater rework??? /**
* This Service contains all important long lasting operations for APG. It receives Intents with
* data from the activities or other apps, queues these intents, executes them, and stops itself
* doing it.
*/
// TODO: ProgressDialogUpdater rework???
public class ApgService extends IntentService implements ProgressDialogUpdater { public class ApgService extends IntentService implements ProgressDialogUpdater {
// extras that can be given by intent // extras that can be given by intent
@ -38,22 +47,22 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
// keys for data bundle // keys for data bundle
// edit keys // edit keys
public static final String DATA_NEW_PASSPHRASE = "new_passphrase"; public static final String NEW_PASSPHRASE = "new_passphrase";
public static final String DATA_CURRENT_PASSPHRASE = "current_passphrase"; public static final String CURRENT_PASSPHRASE = "current_passphrase";
public static final String DATA_USER_IDS = "user_ids"; public static final String USER_IDS = "user_ids";
public static final String DATA_KEYS = "keys"; public static final String KEYS = "keys";
public static final String DATA_KEYS_USAGES = "keys_usages"; public static final String KEYS_USAGES = "keys_usages";
public static final String DATA_MASTER_KEY_ID = "master_key_id"; public static final String MASTER_KEY_ID = "master_key_id";
// generate key
public static final String ALGORITHM = "algorithm";
public static final String KEY_SIZE = "key_size";
public static final String PASSPHRASE = "passphrase";
public static final String MASTER_KEY = "master_key";
// possible ints for EXTRA_ACTION // possible ints for EXTRA_ACTION
public static final int ACTION_SAVE_KEYRING = 1; public static final int ACTION_SAVE_KEYRING = 1;
public static final int ACTION_GENERATE_KEY = 2;
// possible messages send from this service to handler on ui
public static final int MESSAGE_OKAY = 1;
public static final int MESSAGE_EXCEPTION = 2;
// possible data keys for messages
public static final String MESSAGE_DATA_ERROR = "error";
Messenger mMessenger; Messenger mMessenger;
@ -69,89 +78,104 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
@Override @Override
protected void onHandleIntent(Intent intent) { protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras(); Bundle extras = intent.getExtras();
if (extras != null) { if (extras == null) {
Log.e(Constants.TAG, "Extra bundle is null!");
return;
}
if (!extras.containsKey(EXTRA_ACTION)) { if (!extras.containsKey(EXTRA_MESSENGER)) {
Log.e(Constants.TAG, "Extra bundle must contain a action!"); Log.e(Constants.TAG, "Extra bundle must contain a messenger!");
return; return;
}
mMessenger = (Messenger) extras.get(EXTRA_MESSENGER);
if (!extras.containsKey(EXTRA_DATA)) {
Log.e(Constants.TAG, "Extra bundle must contain data bundle!");
return;
}
Bundle data = extras.getBundle(EXTRA_DATA);
if (!extras.containsKey(EXTRA_ACTION)) {
Log.e(Constants.TAG, "Extra bundle must contain a action!");
return;
}
int action = extras.getInt(EXTRA_ACTION);
// execute action from extra bundle
switch (action) {
case ACTION_SAVE_KEYRING:
try {
// Input
String oldPassPhrase = data.getString(CURRENT_PASSPHRASE);
String newPassPhrase = data.getString(NEW_PASSPHRASE);
if (newPassPhrase == null) {
newPassPhrase = oldPassPhrase;
}
@SuppressWarnings("unchecked")
ArrayList<String> userIds = (ArrayList<String>) data.getSerializable(USER_IDS);
ArrayList<PGPSecretKey> keys = Utils.BytesToPGPSecretKeyList(data
.getByteArray(KEYS));
@SuppressWarnings("unchecked")
ArrayList<Integer> keysUsages = (ArrayList<Integer>) data
.getSerializable(KEYS_USAGES);
long masterKeyId = data.getLong(MASTER_KEY_ID);
// Operation
Apg.buildSecretKey(this, userIds, keys, keysUsages, masterKeyId, oldPassPhrase,
newPassPhrase, this);
Apg.setCachedPassPhrase(masterKeyId, newPassPhrase);
// Output
sendMessageToHandler(ApgHandler.MESSAGE_OKAY);
} catch (Exception e) {
sendErrorToHandler(e);
} }
if (!extras.containsKey(EXTRA_MESSENGER)) { break;
Log.e(Constants.TAG, "Extra bundle must contain a messenger!");
return;
}
mMessenger = (Messenger) extras.get(EXTRA_MESSENGER);
Bundle data = null; case ACTION_GENERATE_KEY:
if (extras.containsKey(EXTRA_DATA)) {
data = extras.getBundle(EXTRA_DATA);
}
int action = extras.getInt(EXTRA_ACTION); try {
// Input
// will be filled if error occurs int algorithm = data.getInt(ALGORITHM);
String error = ""; String passphrase = data.getString(PASSPHRASE);
int keysize = data.getInt(KEY_SIZE);
// execute action from extra bundle PGPSecretKey masterKey = null;
switch (action) { if (data.containsKey(MASTER_KEY)) {
case ACTION_SAVE_KEYRING: masterKey = Utils.BytesToPGPSecretKey(data.getByteArray(MASTER_KEY));
try {
String oldPassPhrase = data.getString(DATA_CURRENT_PASSPHRASE);
String newPassPhrase = data.getString(DATA_NEW_PASSPHRASE);
if (newPassPhrase == null) {
newPassPhrase = oldPassPhrase;
}
ArrayList<String> userIds = (ArrayList<String>) data
.getSerializable(DATA_USER_IDS);
byte[] keysBytes = data.getByteArray(DATA_KEYS);
// convert back from byte[] to ArrayList<PGPSecretKey>
PGPObjectFactory factory = new PGPObjectFactory(keysBytes);
PGPSecretKeyRing keyRing = null;
if ((keyRing = (PGPSecretKeyRing) factory.nextObject()) == null) {
Log.e(Constants.TAG, "No keys given!");
}
ArrayList<PGPSecretKey> keys = new ArrayList<PGPSecretKey>();
Iterator<PGPSecretKey> itr = keyRing.getSecretKeys();
while (itr.hasNext()) {
keys.add(itr.next());
Log.d(Constants.TAG, "added...");
}
ArrayList<Integer> keysUsages = (ArrayList<Integer>) data
.getSerializable(DATA_KEYS_USAGES);
long masterKeyId = data.getLong(DATA_MASTER_KEY_ID);
Apg.buildSecretKey(this, userIds, keys, keysUsages, masterKeyId, oldPassPhrase,
newPassPhrase, this);
Apg.setCachedPassPhrase(masterKeyId, newPassPhrase);
} catch (Exception e) {
error = e.getMessage();
Log.e(Constants.TAG, "Exception: " + error);
e.printStackTrace();
sendErrorToUi(error);
} }
sendMessageToUi(MESSAGE_OKAY, null, null); // Operation
break; PGPSecretKey newKey = Apg
.createKey(this, algorithm, keysize, passphrase, masterKey);
default: // Output
break; Bundle resultData = new Bundle();
resultData.putByteArray(ApgHandler.NEW_KEY, Utils.PGPSecretKeyToBytes(newKey));
sendMessageToHandler(ApgHandler.MESSAGE_OKAY, null, resultData);
} catch (Exception e) {
sendErrorToHandler(e);
} }
break;
default:
break;
} }
} }
private void sendErrorToUi(String error) { private void sendErrorToHandler(Exception e) {
Log.e(Constants.TAG, "ApgService Exception: ", e);
e.printStackTrace();
Bundle data = new Bundle(); Bundle data = new Bundle();
data.putString(MESSAGE_DATA_ERROR, error); data.putString(ApgHandler.ERROR, e.getMessage());
sendMessageToUi(MESSAGE_EXCEPTION, null, data); sendMessageToHandler(ApgHandler.MESSAGE_EXCEPTION, null, data);
} }
private void sendMessageToUi(Integer arg1, Integer arg2, Bundle data) { private void sendMessageToHandler(Integer arg1, Integer arg2, Bundle data) {
Message msg = Message.obtain(); Message msg = Message.obtain();
msg.arg1 = arg1; msg.arg1 = arg1;
if (arg2 != null) { if (arg2 != null) {
@ -164,43 +188,37 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
try { try {
mMessenger.send(msg); mMessenger.send(msg);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.w(Constants.TAG, "Exception sending message", e); Log.w(Constants.TAG, "Exception sending message, Is handler present?", e);
} catch (NullPointerException e) { } catch (NullPointerException e) {
Log.w(Constants.TAG, "Messenger is null!", e); Log.w(Constants.TAG, "Messenger is null!", e);
} }
} }
private void sendMessageToHandler(Integer arg1) {
sendMessageToHandler(arg1, null, null);
}
/**
* Set progress of ProgressDialog by sending message to handler on UI thread
*/
public void setProgress(String message, int progress, int max) {
Log.d(Constants.TAG, "Send message by setProgress");
Bundle data = new Bundle();
if (message != null) {
data.putString(ApgHandler.MESSAGE, message);
}
data.putInt(ApgHandler.PROGRESS, progress);
data.putInt(ApgHandler.PROGRESS_MAX, max);
sendMessageToHandler(ApgHandler.MESSAGE_UPDATE_PROGRESS, null, data);
}
public void setProgress(int resourceId, int progress, int max) { public void setProgress(int resourceId, int progress, int max) {
setProgress(getString(resourceId), progress, max); setProgress(getString(resourceId), progress, max);
} }
public void setProgress(int progress, int max) { public void setProgress(int progress, int max) {
Message msg = new Message(); setProgress(null, progress, max);
Bundle data = new Bundle();
data.putInt(Constants.extras.STATUS, Id.message.progress_update);
data.putInt(Constants.extras.PROGRESS, progress);
data.putInt(Constants.extras.PROGRESS_MAX, max);
msg.setData(data);
try {
mMessenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
public void setProgress(String message, int progress, int max) {
Message msg = new Message();
Bundle data = new Bundle();
data.putInt(Constants.extras.STATUS, Id.message.progress_update);
data.putString(Constants.extras.MESSAGE, message);
data.putInt(Constants.extras.PROGRESS, progress);
data.putInt(Constants.extras.PROGRESS_MAX, max);
msg.setData(data);
try {
mMessenger.send(msg);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
} }

View File

@ -32,6 +32,7 @@ import org.thialfihar.android.apg.Service;
import com.actionbarsherlock.app.ActionBar; import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockActivity; import com.actionbarsherlock.app.SherlockActivity;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.MenuItem; import com.actionbarsherlock.view.MenuItem;
import android.app.Activity; import android.app.Activity;
@ -44,10 +45,12 @@ import android.os.Bundle;
import android.os.Environment; import android.os.Environment;
import android.os.Handler; import android.os.Handler;
import android.os.Message; import android.os.Message;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.widget.Toast; import android.widget.Toast;
public class BaseActivity extends SherlockActivity implements Runnable, ProgressDialogUpdater, public class BaseActivity extends SherlockFragmentActivity implements Runnable,
AskForSecretKeyPassPhrase.PassPhraseCallbackInterface { ProgressDialogUpdater, AskForSecretKeyPassPhrase.PassPhraseCallbackInterface {
private ProgressDialog mProgressDialog = null; private ProgressDialog mProgressDialog = null;
private PausableThread mRunningThread = null; private PausableThread mRunningThread = null;

View File

@ -22,28 +22,29 @@ import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.thialfihar.android.apg.Apg; import org.thialfihar.android.apg.Apg;
import org.thialfihar.android.apg.Constants; import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.Id; import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.service.ApgHandler;
import org.thialfihar.android.apg.service.ApgService; import org.thialfihar.android.apg.service.ApgService;
import org.thialfihar.android.apg.ui.widget.KeyEditor; import org.thialfihar.android.apg.ui.widget.KeyEditor;
import org.thialfihar.android.apg.ui.widget.SectionView; import org.thialfihar.android.apg.ui.widget.SectionView;
import org.thialfihar.android.apg.ui.widget.UserIdEditor; import org.thialfihar.android.apg.ui.widget.UserIdEditor;
import org.thialfihar.android.apg.util.IterableIterator; import org.thialfihar.android.apg.util.IterableIterator;
import org.thialfihar.android.apg.util.Utils;
import org.thialfihar.android.apg.R; import org.thialfihar.android.apg.R;
import com.actionbarsherlock.app.ActionBar; import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockActivity; import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.Menu; import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem; import com.actionbarsherlock.view.MenuItem;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.Dialog; import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.os.Message; import android.os.Message;
import android.os.Messenger; import android.os.Messenger;
import android.support.v4.app.DialogFragment;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@ -57,11 +58,9 @@ import android.widget.LinearLayout;
import android.widget.Toast; import android.widget.Toast;
import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.CompoundButton.OnCheckedChangeListener;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Vector; import java.util.Vector;
public class EditKeyActivity extends SherlockActivity { // extends BaseActivity { public class EditKeyActivity extends SherlockFragmentActivity { // extends BaseActivity {
private Intent mIntent = null; private Intent mIntent = null;
private ActionBar mActionBar; private ActionBar mActionBar;
@ -77,6 +76,8 @@ public class EditKeyActivity extends SherlockActivity { // extends BaseActivity
private CheckBox mNoPassphrase; private CheckBox mNoPassphrase;
private ProgressDialogFragment mSavingDialog;
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
menu.add(1, Id.menu.option.cancel, 0, R.string.btn_doNotSave).setShowAsAction( menu.add(1, Id.menu.option.cancel, 0, R.string.btn_doNotSave).setShowAsAction(
@ -115,6 +116,16 @@ public class EditKeyActivity extends SherlockActivity { // extends BaseActivity
setContentView(R.layout.edit_key); setContentView(R.layout.edit_key);
mActionBar = getSupportActionBar(); mActionBar = getSupportActionBar();
mActionBar.setDisplayShowTitleEnabled(true);
// set actionbar without home button if called from another app
if (getCallingPackage() != null && getCallingPackage().equals(Apg.PACKAGE_NAME)) {
mActionBar.setDisplayHomeAsUpEnabled(true);
mActionBar.setHomeButtonEnabled(true);
} else {
mActionBar.setDisplayHomeAsUpEnabled(false);
mActionBar.setHomeButtonEnabled(false);
}
// find views // find views
mChangePassPhrase = (Button) findViewById(R.id.edit_key_btn_change_pass_phrase); mChangePassPhrase = (Button) findViewById(R.id.edit_key_btn_change_pass_phrase);
@ -126,6 +137,8 @@ public class EditKeyActivity extends SherlockActivity { // extends BaseActivity
// Catch Intents opened from other apps // Catch Intents opened from other apps
mIntent = getIntent(); mIntent = getIntent();
// Handle intents
Bundle extras = mIntent.getExtras(); Bundle extras = mIntent.getExtras();
if (Apg.Intent.CREATE_KEY.equals(mIntent.getAction())) { if (Apg.Intent.CREATE_KEY.equals(mIntent.getAction())) {
@ -134,12 +147,6 @@ public class EditKeyActivity extends SherlockActivity { // extends BaseActivity
mCurrentPassPhrase = ""; mCurrentPassPhrase = "";
if (extras != null) { if (extras != null) {
// disable home button on actionbar because this activity is run from another app
mActionBar.setDisplayShowTitleEnabled(true);
mActionBar.setDisplayHomeAsUpEnabled(false);
mActionBar.setHomeButtonEnabled(false);
// if userId is given, prefill the fields // if userId is given, prefill the fields
if (extras.containsKey(Apg.EXTRA_USER_IDS)) { if (extras.containsKey(Apg.EXTRA_USER_IDS)) {
Log.d(Constants.TAG, "UserIds are given!"); Log.d(Constants.TAG, "UserIds are given!");
@ -339,72 +346,71 @@ public class EditKeyActivity extends SherlockActivity { // extends BaseActivity
} }
private void saveClicked() { private void saveClicked() {
if (!isPassphraseSet()) {
Toast.makeText(this, R.string.setAPassPhrase, Toast.LENGTH_SHORT).show();
return;
}
// showDialog(Id.dialog.saving);
ProgressDialogFragment newFragment = ProgressDialogFragment.newInstance(
ProgressDialogFragment.ID_SAVING);
newFragment.show(getSupportFragmentManager(), "saving");
// ((ProgressDialog) newFragment.getDialog()).setProgress(value)
// startThread(); try {
if (!isPassphraseSet()) {
// Send all information needed to service to edit key in other thread throw new Apg.GeneralException(this.getString(R.string.setAPassPhrase));
Intent intent = new Intent(this, ApgService.class);
// Create a new Messenger for the communication back
Messenger messenger = new Messenger(handler);
intent.putExtra(ApgService.EXTRA_MESSENGER, messenger);
intent.putExtra(ApgService.EXTRA_ACTION, ApgService.ACTION_SAVE_KEYRING);
// fill values for this action
Bundle data = new Bundle();
data.putString(ApgService.DATA_CURRENT_PASSPHRASE, mCurrentPassPhrase);
data.putString(ApgService.DATA_NEW_PASSPHRASE, mNewPassPhrase);
data.putSerializable(ApgService.DATA_USER_IDS, getUserIds(mUserIds));
Vector<PGPSecretKey> keys = getKeys(mKeys);
// convert to byte[]
ByteArrayOutputStream os = new ByteArrayOutputStream();
for (PGPSecretKey key : keys) {
try {
key.encode(os);
} catch (IOException e) {
Log.e(Constants.TAG,
"Error while converting PGPSecretKey to byte[]: " + e.getMessage());
e.printStackTrace();
} }
// Send all information needed to service to edit key in other thread
Intent intent = new Intent(this, ApgService.class);
intent.putExtra(ApgService.EXTRA_ACTION, ApgService.ACTION_SAVE_KEYRING);
// fill values for this action
Bundle data = new Bundle();
data.putString(ApgService.CURRENT_PASSPHRASE, mCurrentPassPhrase);
data.putString(ApgService.NEW_PASSPHRASE, mNewPassPhrase);
data.putSerializable(ApgService.USER_IDS, getUserIds(mUserIds));
Vector<PGPSecretKey> keys = getKeys(mKeys);
byte[] keysBytes = Utils.PGPSecretKeyListToBytes(keys);
data.putByteArray(ApgService.KEYS, keysBytes);
data.putSerializable(ApgService.KEYS_USAGES, getKeysUsages(mKeys));
data.putLong(ApgService.MASTER_KEY_ID, getMasterKeyId());
intent.putExtra(ApgService.EXTRA_DATA, data);
// show progress dialog
mSavingDialog = ProgressDialogFragment.newInstance(R.string.progress_saving,
ProgressDialog.STYLE_HORIZONTAL);
// Message is received after saving is done in ApgService
ApgHandler saveHandler = new ApgHandler(this, mSavingDialog) {
public void handleMessage(Message message) {
// handle messages by standard ApgHandler first
super.handleMessage(message);
if (message.arg1 == ApgHandler.MESSAGE_OKAY) {
finish();
}
};
};
// Create a new Messenger for the communication back
Messenger messenger = new Messenger(saveHandler);
intent.putExtra(ApgService.EXTRA_MESSENGER, messenger);
mSavingDialog.show(getSupportFragmentManager(), "dialog");
// start service with intent
startService(intent);
} catch (Apg.GeneralException e) {
Toast.makeText(this, getString(R.string.errorMessage, e.getMessage()),
Toast.LENGTH_SHORT).show();
} }
byte[] keysBytes = os.toByteArray();
data.putByteArray(ApgService.DATA_KEYS, keysBytes);
data.putSerializable(ApgService.DATA_KEYS_USAGES, getKeysUsages(mKeys).toArray());
data.putLong(ApgService.DATA_MASTER_KEY_ID, getMasterKeyId());
intent.putExtra(ApgService.EXTRA_DATA, data);
startService(intent);
} }
private Handler handler = new Handler() { /**
public void handleMessage(Message message) { * Returns user ids from the SectionView
Object path = message.obj; *
if (message.arg1 == ApgService.MESSAGE_OKAY) { * @param userIdsView
Toast.makeText(EditKeyActivity.this, "okay", Toast.LENGTH_LONG).show(); * @return
} else { */
Toast.makeText(EditKeyActivity.this, "nope", Toast.LENGTH_LONG).show(); private Vector<String> getUserIds(SectionView userIdsView) throws Apg.GeneralException {
}
};
};
// TODO: put in other class
private Vector<String> getUserIds(SectionView userIdsView) {
Vector<String> userIds = new Vector<String>(); Vector<String> userIds = new Vector<String>();
ViewGroup userIdEditors = userIdsView.getEditors(); ViewGroup userIdEditors = userIdsView.getEditors();
@ -416,12 +422,12 @@ public class EditKeyActivity extends SherlockActivity { // extends BaseActivity
try { try {
userId = editor.getValue(); userId = editor.getValue();
} catch (UserIdEditor.NoNameException e) { } catch (UserIdEditor.NoNameException e) {
// throw new Apg.GeneralException(this.getString(R.string.error_userIdNeedsAName)); throw new Apg.GeneralException(this.getString(R.string.error_userIdNeedsAName));
} catch (UserIdEditor.NoEmailException e) { } catch (UserIdEditor.NoEmailException e) {
// throw new Apg.GeneralException( throw new Apg.GeneralException(
// this.getString(R.string.error_userIdNeedsAnEmailAddress)); this.getString(R.string.error_userIdNeedsAnEmailAddress));
} catch (UserIdEditor.InvalidEmailException e) { } catch (UserIdEditor.InvalidEmailException e) {
// throw new Apg.GeneralException("" + e); throw new Apg.GeneralException(e.getMessage());
} }
if (userId.equals("")) { if (userId.equals("")) {
@ -437,24 +443,29 @@ public class EditKeyActivity extends SherlockActivity { // extends BaseActivity
} }
if (userIds.size() == 0) { if (userIds.size() == 0) {
// throw new Apg.GeneralException(context.getString(R.string.error_keyNeedsAUserId)); throw new Apg.GeneralException(getString(R.string.error_keyNeedsAUserId));
} }
if (!gotMainUserId) { if (!gotMainUserId) {
// throw new Apg.GeneralException( throw new Apg.GeneralException(getString(R.string.error_mainUserIdMustNotBeEmpty));
// context.getString(R.string.error_mainUserIdMustNotBeEmpty));
} }
return userIds; return userIds;
} }
private Vector<PGPSecretKey> getKeys(SectionView keysView) { /**
* Returns keys from the SectionView
*
* @param keysView
* @return
*/
private Vector<PGPSecretKey> getKeys(SectionView keysView) throws Apg.GeneralException {
Vector<PGPSecretKey> keys = new Vector<PGPSecretKey>(); Vector<PGPSecretKey> keys = new Vector<PGPSecretKey>();
ViewGroup keyEditors = keysView.getEditors(); ViewGroup keyEditors = keysView.getEditors();
if (keyEditors.getChildCount() == 0) { if (keyEditors.getChildCount() == 0) {
// throw new Apg.GeneralException(getString(R.string.error_keyNeedsMasterKey)); throw new Apg.GeneralException(getString(R.string.error_keyNeedsMasterKey));
} }
for (int i = 0; i < keyEditors.getChildCount(); ++i) { for (int i = 0; i < keyEditors.getChildCount(); ++i) {
@ -465,13 +476,19 @@ public class EditKeyActivity extends SherlockActivity { // extends BaseActivity
return keys; return keys;
} }
private Vector<Integer> getKeysUsages(SectionView keysView) { /**
* Returns usage selections of keys from the SectionView
*
* @param keysView
* @return
*/
private Vector<Integer> getKeysUsages(SectionView keysView) throws Apg.GeneralException {
Vector<Integer> getKeysUsages = new Vector<Integer>(); Vector<Integer> getKeysUsages = new Vector<Integer>();
ViewGroup keyEditors = keysView.getEditors(); ViewGroup keyEditors = keysView.getEditors();
if (keyEditors.getChildCount() == 0) { if (keyEditors.getChildCount() == 0) {
// throw new Apg.GeneralException(getString(R.string.error_keyNeedsMasterKey)); throw new Apg.GeneralException(getString(R.string.error_keyNeedsMasterKey));
} }
for (int i = 0; i < keyEditors.getChildCount(); ++i) { for (int i = 0; i < keyEditors.getChildCount(); ++i) {
@ -482,66 +499,6 @@ public class EditKeyActivity extends SherlockActivity { // extends BaseActivity
return getKeysUsages; return getKeysUsages;
} }
// @Override
// public void run() {
// String error = null;
// Bundle data = new Bundle();
// Message msg = new Message();
//
// data.putParcelable("ts", (Parcelable) mUserIds);
//
// try {
// String oldPassPhrase = mCurrentPassPhrase;
// String newPassPhrase = mNewPassPhrase;
// if (newPassPhrase == null) {
// newPassPhrase = oldPassPhrase;
// }
// Apg.buildSecretKey(this, mUserIds, mKeys, oldPassPhrase, newPassPhrase, this);
// Apg.setCachedPassPhrase(getMasterKeyId(), newPassPhrase);
// } catch (NoSuchProviderException e) {
// error = "" + e;
// } catch (NoSuchAlgorithmException e) {
// error = "" + e;
// } catch (PGPException e) {
// error = "" + e;
// } catch (SignatureException e) {
// error = "" + e;
// } catch (Apg.GeneralException e) {
// error = "" + e;
// } catch (Database.GeneralException e) {
// error = "" + e;
// } catch (IOException e) {
// error = "" + e;
// }
//
// data.putInt(Constants.extras.STATUS, Id.message.done);
//
// if (error != null) {
// data.putString(Apg.EXTRA_ERROR, error);
// }
//
// msg.setData(data);
// sendMessage(msg);
// }
// @Override
// public void doneCallback(Message msg) {
// super.doneCallback(msg);
//
// Bundle data = msg.getData();
// removeDialog(Id.dialog.saving);
//
// String error = data.getString(Apg.EXTRA_ERROR);
// if (error != null) {
// Toast.makeText(EditKeyActivity.this, getString(R.string.errorMessage, error),
// Toast.LENGTH_SHORT).show();
// } else {
// Toast.makeText(EditKeyActivity.this, R.string.keySaved, Toast.LENGTH_SHORT).show();
// setResult(RESULT_OK);
// finish();
// }
// }
private void updatePassPhraseButtonText() { private void updatePassPhraseButtonText() {
mChangePassPhrase.setText(isPassphraseSet() ? R.string.btn_changePassPhrase mChangePassPhrase.setText(isPassphraseSet() ? R.string.btn_changePassPhrase
: R.string.btn_setPassPhrase); : R.string.btn_setPassPhrase);

View File

@ -1,42 +0,0 @@
package org.thialfihar.android.apg.ui;
import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.Id;
import android.content.Context;
import android.os.Bundle;
import android.os.Message;
/**
* Extends the standard ProgressDialog by new methods for setting progress
*
*/
public class ProgressDialog extends android.app.ProgressDialog{
Context mContext;
public ProgressDialog(Context context) {
super(context);
mContext = context;
}
public void setProgress(int resourceId, int progress, int max) {
setProgress(mContext.getString(resourceId), progress, max);
}
public void setProgress(int progress, int max) {
this.setP
}
public void setProgress(String message, int progress, int max) {
Message msg = new Message();
Bundle data = new Bundle();
data.putInt(Constants.extras.STATUS, Id.message.progress_update);
data.putString(Constants.extras.MESSAGE, message);
data.putInt(Constants.extras.PROGRESS, progress);
data.putInt(Constants.extras.PROGRESS_MAX, max);
msg.setData(data);
mHandler.sendMessage(msg);
}
}

View File

@ -1,6 +1,20 @@
package org.thialfihar.android.apg.ui; /*
* Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de>
*
* 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.
*/
import org.thialfihar.android.apg.R; package org.thialfihar.android.apg.ui;
import android.app.Activity; import android.app.Activity;
import android.app.Dialog; import android.app.Dialog;
@ -13,27 +27,68 @@ import android.view.KeyEvent;
public class ProgressDialogFragment extends DialogFragment { public class ProgressDialogFragment extends DialogFragment {
public static final int ID_ENCRYPTING = 1; private static final String ARG_MESSAGE_ID = "message_id";
public static final int ID_DECRYPTING = 2; private static final String ARG_STYLE = "style";
public static final int ID_SAVING = 3;
public static final int ID_IMPORTING = 4;
public static final int ID_EXPORTING = 5;
public static final int ID_DELETING = 6;
public static final int ID_QUERYING = 7;
public static final int ID_SIGNING = 8;
public static ProgressDialogFragment newInstance(int id) { /**
* Instantiates new instance of this fragment
*
* @param id
* @return
*/
public static ProgressDialogFragment newInstance(int messageId, int style) {
ProgressDialogFragment frag = new ProgressDialogFragment(); ProgressDialogFragment frag = new ProgressDialogFragment();
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putInt("id", id); args.putInt(ARG_MESSAGE_ID, messageId);
args.putInt(ARG_STYLE, style);
frag.setArguments(args); frag.setArguments(args);
return frag; return frag;
} }
public static void test() { /**
* Updates progress of dialog
*
* @param messageId
* @param progress
* @param max
*/
public void setProgress(int messageId, int progress, int max) {
setProgress(getString(messageId), progress, max);
} }
/**
* Updates progress of dialog
*
* @param messageId
* @param progress
* @param max
*/
public void setProgress(int progress, int max) {
ProgressDialog dialog = (ProgressDialog) getDialog();
dialog.setProgress(progress);
dialog.setMax(max);
}
/**
* Updates progress of dialog
*
* @param messageId
* @param progress
* @param max
*/
public void setProgress(String message, int progress, int max) {
ProgressDialog dialog = (ProgressDialog) getDialog();
dialog.setMessage(message);
dialog.setProgress(progress);
dialog.setMax(max);
}
/**
* Creates dialog based on arguments (messageId, style)
*/
@Override @Override
public Dialog onCreateDialog(Bundle savedInstanceState) { public Dialog onCreateDialog(Bundle savedInstanceState) {
Activity activity = getActivity(); Activity activity = getActivity();
@ -41,57 +96,28 @@ public class ProgressDialogFragment extends DialogFragment {
ProgressDialog dialog = new ProgressDialog(activity); ProgressDialog dialog = new ProgressDialog(activity);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setCancelable(false); dialog.setCancelable(false);
dialog.setCanceledOnTouchOutside(false);
int id = getArguments().getInt("id"); int messageId = getArguments().getInt(ARG_MESSAGE_ID);
int style = getArguments().getInt(ARG_STYLE);
switch (id) { dialog.setMessage(getString(messageId));
case ID_ENCRYPTING: dialog.setProgressStyle(style);
dialog.setMessage(this.getString(R.string.progress_initializing));
case ID_DECRYPTING:
dialog.setMessage(this.getString(R.string.progress_initializing));
case ID_SAVING:
dialog.setMessage(this.getString(R.string.progress_saving));
case ID_IMPORTING:
dialog.setMessage(this.getString(R.string.progress_importing));
case ID_EXPORTING:
dialog.setMessage(this.getString(R.string.progress_exporting));
case ID_DELETING:
dialog.setMessage(this.getString(R.string.progress_initializing));
case ID_QUERYING:
dialog.setMessage(this.getString(R.string.progress_querying));
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.setCancelable(false);
case ID_SIGNING:
dialog.setMessage(this.getString(R.string.progress_signing));
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.setCancelable(false);
default:
break;
}
// Disable the back button // Disable the back button
// OnKeyListener keyListener = new OnKeyListener() { OnKeyListener keyListener = new OnKeyListener() {
//
// @Override @Override
// public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
//
// if (keyCode == KeyEvent.KEYCODE_BACK) { if (keyCode == KeyEvent.KEYCODE_BACK) {
// return true; return true;
// } }
// return false; return false;
// } }
//
// }; };
// dialog.setOnKeyListener(keyListener); dialog.setOnKeyListener(keyListener);
return dialog; return dialog;
} }

View File

@ -16,44 +16,41 @@
package org.thialfihar.android.apg.ui.widget; package org.thialfihar.android.apg.ui.widget;
import org.spongycastle.openpgp.PGPException;
import org.spongycastle.openpgp.PGPSecretKey; import org.spongycastle.openpgp.PGPSecretKey;
import org.thialfihar.android.apg.Apg; import org.thialfihar.android.apg.Apg;
import org.thialfihar.android.apg.Id; import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.service.ApgHandler;
import org.thialfihar.android.apg.service.ApgService;
import org.thialfihar.android.apg.ui.ProgressDialogFragment;
import org.thialfihar.android.apg.ui.widget.Editor.EditorListener; import org.thialfihar.android.apg.ui.widget.Editor.EditorListener;
import org.thialfihar.android.apg.util.Choice; import org.thialfihar.android.apg.util.Choice;
import org.thialfihar.android.apg.util.Utils;
import org.thialfihar.android.apg.R; import org.thialfihar.android.apg.R;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.os.Message; import android.os.Message;
import android.os.Messenger;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText; import android.widget.EditText;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.Spinner; import android.widget.Spinner;
import android.widget.TableRow;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.Vector; import java.util.Vector;
public class SectionView extends LinearLayout implements OnClickListener, EditorListener, Runnable { public class SectionView extends LinearLayout implements OnClickListener, EditorListener {
private LayoutInflater mInflater; private LayoutInflater mInflater;
private View mAdd; private View mAdd;
private ViewGroup mEditors; private ViewGroup mEditors;
@ -63,50 +60,18 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
private Choice mNewKeyAlgorithmChoice; private Choice mNewKeyAlgorithmChoice;
private int mNewKeySize; private int mNewKeySize;
volatile private PGPSecretKey mNewKey; private SherlockFragmentActivity mActivity;
private ProgressDialog mProgressDialog;
private Thread mRunningThread = null;
private Handler mHandler = new Handler() { private ProgressDialogFragment mGeneratingDialog;
@Override
public void handleMessage(Message msg) {
Bundle data = msg.getData();
if (data != null) {
boolean closeProgressDialog = data.getBoolean("closeProgressDialog");
if (closeProgressDialog) {
if (mProgressDialog != null) {
mProgressDialog.dismiss();
mProgressDialog = null;
}
}
String error = data.getString(Apg.EXTRA_ERROR);
if (error != null) {
Toast.makeText(getContext(),
getContext().getString(R.string.errorMessage, error),
Toast.LENGTH_SHORT).show();
}
boolean gotNewKey = data.getBoolean("gotNewKey");
if (gotNewKey) {
KeyEditor view = (KeyEditor) mInflater.inflate(R.layout.edit_key_key_item,
mEditors, false);
view.setEditorListener(SectionView.this);
boolean isMasterKey = (mEditors.getChildCount() == 0);
view.setValue(mNewKey, isMasterKey, -1);
mEditors.addView(view);
SectionView.this.updateEditorsVisible();
}
}
}
};
public SectionView(Context context) { public SectionView(Context context) {
super(context); super(context);
mActivity = (SherlockFragmentActivity) context;
} }
public SectionView(Context context, AttributeSet attrs) { public SectionView(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs);
mActivity = (SherlockFragmentActivity) context;
} }
public ViewGroup getEditors() { public ViewGroup getEditors() {
@ -281,51 +246,64 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
} }
private void createKey() { private void createKey() {
mProgressDialog = new ProgressDialog(getContext()); // Send all information needed to service to edit key in other thread
mProgressDialog.setMessage(getContext().getString(R.string.progress_generating)); Intent intent = new Intent(mActivity, ApgService.class);
mProgressDialog.setCancelable(false);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
mProgressDialog.show();
mRunningThread = new Thread(this);
mRunningThread.start();
}
public void run() { intent.putExtra(ApgService.EXTRA_ACTION, ApgService.ACTION_GENERATE_KEY);
String error = null;
try {
PGPSecretKey masterKey = null;
String passPhrase;
if (mEditors.getChildCount() > 0) {
masterKey = ((KeyEditor) mEditors.getChildAt(0)).getValue();
passPhrase = Apg.getCachedPassPhrase(masterKey.getKeyID());
} else {
passPhrase = "";
}
mNewKey = Apg.createKey(getContext(), mNewKeyAlgorithmChoice.getId(), mNewKeySize,
passPhrase, masterKey);
} catch (NoSuchProviderException e) {
error = "" + e;
} catch (NoSuchAlgorithmException e) {
error = "" + e;
} catch (PGPException e) {
error = "" + e;
} catch (InvalidParameterException e) {
error = "" + e;
} catch (InvalidAlgorithmParameterException e) {
error = "" + e;
} catch (Apg.GeneralException e) {
error = "" + e;
}
Message message = new Message(); // fill values for this action
Bundle data = new Bundle(); Bundle data = new Bundle();
data.putBoolean("closeProgressDialog", true);
if (error != null) { String passPhrase;
data.putString(Apg.EXTRA_ERROR, error); if (mEditors.getChildCount() > 0) {
PGPSecretKey masterKey = ((KeyEditor) mEditors.getChildAt(0)).getValue();
passPhrase = Apg.getCachedPassPhrase(masterKey.getKeyID());
data.putByteArray(ApgService.MASTER_KEY, Utils.PGPSecretKeyToBytes(masterKey));
} else { } else {
data.putBoolean("gotNewKey", true); passPhrase = "";
} }
message.setData(data); data.putString(ApgService.PASSPHRASE, passPhrase);
mHandler.sendMessage(message); data.putInt(ApgService.ALGORITHM, mNewKeyAlgorithmChoice.getId());
data.putInt(ApgService.KEY_SIZE, mNewKeySize);
intent.putExtra(ApgService.EXTRA_DATA, data);
// show progress dialog
mGeneratingDialog = ProgressDialogFragment.newInstance(R.string.progress_generating,
ProgressDialog.STYLE_SPINNER);
// Message is received after generating is done in ApgService
ApgHandler saveHandler = new ApgHandler(mActivity, mGeneratingDialog) {
public void handleMessage(Message message) {
// handle messages by standard ApgHandler first
super.handleMessage(message);
if (message.arg1 == ApgHandler.MESSAGE_OKAY) {
// get new key from data bundle returned from service
Bundle data = message.getData();
PGPSecretKey newKey = Utils.BytesToPGPSecretKey(data
.getByteArray(ApgHandler.NEW_KEY));
// add view with new key
KeyEditor view = (KeyEditor) mInflater.inflate(R.layout.edit_key_key_item,
mEditors, false);
view.setEditorListener(SectionView.this);
boolean isMasterKey = (mEditors.getChildCount() == 0);
view.setValue(newKey, isMasterKey, -1);
mEditors.addView(view);
SectionView.this.updateEditorsVisible();
}
};
};
// Create a new Messenger for the communication back
Messenger messenger = new Messenger(saveHandler);
intent.putExtra(ApgService.EXTRA_MESSENGER, messenger);
mGeneratingDialog.show(mActivity.getSupportFragmentManager(), "dialog");
// start service with intent
mActivity.startService(intent);
} }
} }

View File

@ -19,10 +19,19 @@ package org.thialfihar.android.apg.util;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.Vector;
import org.spongycastle.openpgp.PGPObjectFactory;
import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.thialfihar.android.apg.Constants;
import android.content.Context; import android.content.Context;
import android.util.Log;
public class Utils { public class Utils {
@ -72,4 +81,69 @@ public class Utils {
return numDays; return numDays;
} }
/**
* Converts Vector<PGPSecretKey> to a byte[] array to send it by intent to service
*
* @param keys
* @return
*/
public static byte[] PGPSecretKeyListToBytes(Vector<PGPSecretKey> keys) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
for (PGPSecretKey key : keys) {
try {
key.encode(os);
} catch (IOException e) {
Log.e(Constants.TAG,
"Error while converting PGPSecretKey to byte[]: " + e.getMessage());
e.printStackTrace();
}
}
byte[] keysBytes = os.toByteArray();
return keysBytes;
}
/**
* Convert from byte[] to ArrayList<PGPSecretKey>
*
* @param keysBytes
* @return
*/
public static ArrayList<PGPSecretKey> BytesToPGPSecretKeyList(byte[] keysBytes) {
PGPObjectFactory factory = new PGPObjectFactory(keysBytes);
PGPSecretKeyRing keyRing = null;
try {
if ((keyRing = (PGPSecretKeyRing) factory.nextObject()) == null) {
Log.e(Constants.TAG, "No keys given!");
}
} catch (IOException e) {
e.printStackTrace();
}
ArrayList<PGPSecretKey> keys = new ArrayList<PGPSecretKey>();
Iterator<PGPSecretKey> itr = keyRing.getSecretKeys();
while (itr.hasNext()) {
keys.add(itr.next());
}
return keys;
}
public static PGPSecretKey BytesToPGPSecretKey(byte[] keyBytes) {
PGPSecretKey key = BytesToPGPSecretKeyList(keyBytes).get(0);
return key;
}
public static byte[] PGPSecretKeyToBytes(PGPSecretKey key) {
try {
return key.getEncoded();
} catch (IOException e) {
Log.e(Constants.TAG, "Encoding failed: ", e);
return null;
}
}
} }