started working on dialogs

This commit is contained in:
Dominik 2012-04-20 12:12:07 +02:00
parent e95ec50b46
commit 784c3156df
10 changed files with 649 additions and 169 deletions

View File

@ -224,20 +224,22 @@
android:label="@string/title_help" /> android:label="@string/title_help" />
<service android:name=".Service" /> <service android:name=".Service" />
<service
android:name="org.thialfihar.android.apg.ApgService" <service android:name=".service.ApgService" />
android:enabled="true" <!-- <service -->
android:exported="true" <!-- android:name=".ApgService2" -->
android:permission="org.thialfihar.android.apg.permission.READ_KEY_DETAILS" <!-- android:enabled="true" -->
android:process=":remote" > <!-- android:exported="true" -->
<intent-filter> <!-- android:permission="org.thialfihar.android.apg.permission.READ_KEY_DETAILS" -->
<action android:name="org.thialfihar.android.apg.IApgService" /> <!-- android:process=":remote" > -->
</intent-filter> <!-- <intent-filter> -->
<!-- <action android:name="org.thialfihar.android.apg.IApgService" /> -->
<!-- </intent-filter> -->
<meta-data <!-- <meta-data -->
android:name="api_version" <!-- android:name="api_version" -->
android:value="2" /> <!-- android:value="2" /> -->
</service> <!-- </service> -->
<provider <provider
android:name=".provider.DataProvider" android:name=".provider.DataProvider"

View File

@ -99,6 +99,7 @@ import java.security.NoSuchProviderException;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.security.Security; import java.security.Security;
import java.security.SignatureException; import java.security.SignatureException;
import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
@ -380,8 +381,8 @@ public class Apg {
return secretKey; return secretKey;
} }
public static void buildSecretKey(Activity context, SectionView userIdsView, public static void buildSecretKey(Context context, ArrayList<String> userIds,
SectionView keysView, String oldPassPhrase, String newPassPhrase, ArrayList<PGPSecretKey> keys, ArrayList<Integer> keysUsages, long masterKeyId, String oldPassPhrase, String newPassPhrase,
ProgressDialogUpdater progress) throws Apg.GeneralException, NoSuchProviderException, ProgressDialogUpdater progress) throws Apg.GeneralException, NoSuchProviderException,
PGPException, NoSuchAlgorithmException, SignatureException, IOException, PGPException, NoSuchAlgorithmException, SignatureException, IOException,
Database.GeneralException { Database.GeneralException {
@ -399,61 +400,65 @@ 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;
// for (int i = 0; i < userIdEditors.getChildCount(); ++i) {
// UserIdEditor editor = (UserIdEditor) userIdEditors.getChildAt(i);
// String userId = null;
// try {
// userId = editor.getValue();
// } catch (UserIdEditor.NoNameException e) {
// throw new Apg.GeneralException(context.getString(R.string.error_userIdNeedsAName));
// } catch (UserIdEditor.NoEmailException e) {
// throw new Apg.GeneralException(
// context.getString(R.string.error_userIdNeedsAnEmailAddress));
// } catch (UserIdEditor.InvalidEmailException e) {
// throw new Apg.GeneralException("" + e);
// }
//
// if (userId.equals("")) {
// continue;
// }
//
// if (editor.isMainUserId()) {
// userIds.insertElementAt(userId, 0);
// gotMainUserId = true;
// } else {
// userIds.add(userId);
// }
// }
boolean gotMainUserId = false; // if (userIds.size() == 0) {
for (int i = 0; i < userIdEditors.getChildCount(); ++i) { // throw new Apg.GeneralException(context.getString(R.string.error_keyNeedsAUserId));
UserIdEditor editor = (UserIdEditor) userIdEditors.getChildAt(i); // }
String userId = null; //
try { // if (!gotMainUserId) {
userId = editor.getValue(); // throw new Apg.GeneralException(
} catch (UserIdEditor.NoNameException e) { // context.getString(R.string.error_mainUserIdMustNotBeEmpty));
throw new Apg.GeneralException(context.getString(R.string.error_userIdNeedsAName)); // }
} catch (UserIdEditor.NoEmailException e) {
throw new Apg.GeneralException(
context.getString(R.string.error_userIdNeedsAnEmailAddress));
} catch (UserIdEditor.InvalidEmailException e) {
throw new Apg.GeneralException("" + e);
}
if (userId.equals("")) { // if (keyEditors.getChildCount() == 0) {
continue; // throw new Apg.GeneralException(context.getString(R.string.error_keyNeedsMasterKey));
} // }
//
if (editor.isMainUserId()) { // for (int i = 0; i < keyEditors.getChildCount(); ++i) {
userIds.insertElementAt(userId, 0); // KeyEditor editor = (KeyEditor) keyEditors.getChildAt(i);
gotMainUserId = true; // keys.add(editor.getValue());
} else { // }
userIds.add(userId);
}
}
if (userIds.size() == 0) {
throw new Apg.GeneralException(context.getString(R.string.error_keyNeedsAUserId));
}
if (!gotMainUserId) {
throw new Apg.GeneralException(
context.getString(R.string.error_mainUserIdMustNotBeEmpty));
}
if (keyEditors.getChildCount() == 0) {
throw new Apg.GeneralException(context.getString(R.string.error_keyNeedsMasterKey));
}
for (int i = 0; i < keyEditors.getChildCount(); ++i) {
KeyEditor editor = (KeyEditor) keyEditors.getChildAt(i);
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);
int usageId = keyEditor.getUsage();
// KeyEditor keyEditor = (KeyEditor) keyEditors.getChildAt(0);
// int usageId = keyEditor.getUsage();
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);
@ -499,17 +504,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);
@ -526,7 +531,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());
@ -538,7 +543,9 @@ public class Apg {
unhashedPacketsGen = new PGPSignatureSubpacketGenerator(); unhashedPacketsGen = new PGPSignatureSubpacketGenerator();
keyFlags = 0; keyFlags = 0;
usageId = keyEditor.getUsage(); // usageId = keyEditor.getUsage();
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);
if (canSign) { if (canSign) {
@ -550,17 +557,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

@ -40,7 +40,7 @@ import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
import android.util.Log; import android.util.Log;
public class ApgService extends Service { public class ApgService2 extends Service {
private final static String TAG = "ApgService"; private final static String TAG = "ApgService";
public static final boolean LOCAL_LOGV = true; public static final boolean LOCAL_LOGV = true;
public static final boolean LOCAL_LOGD = true; public static final boolean LOCAL_LOGD = true;

View File

@ -14,7 +14,7 @@
package org.thialfihar.android.apg.provider; package org.thialfihar.android.apg.provider;
import org.thialfihar.android.apg.ApgService; import org.thialfihar.android.apg.ApgService2;
import android.content.ContentUris; import android.content.ContentUris;
import android.content.ContentValues; import android.content.ContentValues;
@ -35,31 +35,31 @@ public class ApgServiceBlobDatabase extends SQLiteOpenHelper {
public ApgServiceBlobDatabase(Context context) { public ApgServiceBlobDatabase(Context context) {
super(context, NAME, null, VERSION); super(context, NAME, null, VERSION);
if(ApgService.LOCAL_LOGD) Log.d(TAG, "constructor called"); if(ApgService2.LOCAL_LOGD) Log.d(TAG, "constructor called");
} }
@Override @Override
public void onCreate(SQLiteDatabase db) { public void onCreate(SQLiteDatabase db) {
if(ApgService.LOCAL_LOGD) Log.d(TAG, "onCreate() called"); if(ApgService2.LOCAL_LOGD) Log.d(TAG, "onCreate() called");
db.execSQL("create table " + TABLE + " ( _id integer primary key autoincrement," + db.execSQL("create table " + TABLE + " ( _id integer primary key autoincrement," +
"key text not null)"); "key text not null)");
} }
@Override @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if(ApgService.LOCAL_LOGD) Log.d(TAG, "onUpgrade() called"); if(ApgService2.LOCAL_LOGD) Log.d(TAG, "onUpgrade() called");
// no upgrade necessary yet // no upgrade necessary yet
} }
public Uri insert(ContentValues vals) { public Uri insert(ContentValues vals) {
if(ApgService.LOCAL_LOGD) Log.d(TAG, "insert() called"); if(ApgService2.LOCAL_LOGD) Log.d(TAG, "insert() called");
SQLiteDatabase db = this.getWritableDatabase(); SQLiteDatabase db = this.getWritableDatabase();
long newId = db.insert(TABLE, null, vals); long newId = db.insert(TABLE, null, vals);
return ContentUris.withAppendedId(ApgServiceBlobProvider.CONTENT_URI, newId); return ContentUris.withAppendedId(ApgServiceBlobProvider.CONTENT_URI, newId);
} }
public Cursor query(String id, String key) { public Cursor query(String id, String key) {
if(ApgService.LOCAL_LOGD) Log.d(TAG, "query() called"); if(ApgService2.LOCAL_LOGD) Log.d(TAG, "query() called");
SQLiteDatabase db = this.getReadableDatabase(); SQLiteDatabase db = this.getReadableDatabase();
return db.query(TABLE, new String[] {"_id"}, return db.query(TABLE, new String[] {"_id"},
"_id = ? and key = ?", new String[] {id, key}, "_id = ? and key = ?", new String[] {id, key},

View File

@ -14,7 +14,7 @@
package org.thialfihar.android.apg.provider; package org.thialfihar.android.apg.provider;
import org.thialfihar.android.apg.ApgService; import org.thialfihar.android.apg.ApgService2;
import org.thialfihar.android.apg.Constants; import org.thialfihar.android.apg.Constants;
import android.content.ContentProvider; import android.content.ContentProvider;
@ -43,29 +43,29 @@ public class ApgServiceBlobProvider extends ContentProvider {
private ApgServiceBlobDatabase mDb = null; private ApgServiceBlobDatabase mDb = null;
public ApgServiceBlobProvider() { public ApgServiceBlobProvider() {
if(ApgService.LOCAL_LOGD) Log.d(TAG, "Constructor called"); if(ApgService2.LOCAL_LOGD) Log.d(TAG, "Constructor called");
File dir = new File(STORE_PATH); File dir = new File(STORE_PATH);
dir.mkdirs(); dir.mkdirs();
if(ApgService.LOCAL_LOGD) Log.d(TAG, "Constructor finished"); if(ApgService2.LOCAL_LOGD) Log.d(TAG, "Constructor finished");
} }
@Override @Override
public int delete(Uri arg0, String arg1, String[] arg2) { public int delete(Uri arg0, String arg1, String[] arg2) {
if(ApgService.LOCAL_LOGD) Log.d(TAG, "delete() called"); if(ApgService2.LOCAL_LOGD) Log.d(TAG, "delete() called");
// TODO Auto-generated method stub // TODO Auto-generated method stub
return 0; return 0;
} }
@Override @Override
public String getType(Uri arg0) { public String getType(Uri arg0) {
if(ApgService.LOCAL_LOGD) Log.d(TAG, "getType() called"); if(ApgService2.LOCAL_LOGD) Log.d(TAG, "getType() called");
// not needed for now // not needed for now
return null; return null;
} }
@Override @Override
public Uri insert(Uri uri, ContentValues ignored) { public Uri insert(Uri uri, ContentValues ignored) {
if(ApgService.LOCAL_LOGD) Log.d(TAG, "insert() called"); if(ApgService2.LOCAL_LOGD) Log.d(TAG, "insert() called");
// ContentValues are actually ignored, because we want to store a blob with no more information // ContentValues are actually ignored, because we want to store a blob with no more information
// but have to create an record with the password generated here first // but have to create an record with the password generated here first
@ -82,7 +82,7 @@ public class ApgServiceBlobProvider extends ContentProvider {
@Override @Override
public boolean onCreate() { public boolean onCreate() {
if(ApgService.LOCAL_LOGD) Log.d(TAG, "onCreate() called"); if(ApgService2.LOCAL_LOGD) Log.d(TAG, "onCreate() called");
mDb = new ApgServiceBlobDatabase(getContext()); mDb = new ApgServiceBlobDatabase(getContext());
// TODO Auto-generated method stub // TODO Auto-generated method stub
return true; return true;
@ -90,23 +90,23 @@ public class ApgServiceBlobProvider extends ContentProvider {
@Override @Override
public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3, String arg4) { public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3, String arg4) {
if(ApgService.LOCAL_LOGD) Log.d(TAG, "query() called"); if(ApgService2.LOCAL_LOGD) Log.d(TAG, "query() called");
// TODO Auto-generated method stub // TODO Auto-generated method stub
return null; return null;
} }
@Override @Override
public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) { public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) {
if(ApgService.LOCAL_LOGD) Log.d(TAG, "update() called"); if(ApgService2.LOCAL_LOGD) Log.d(TAG, "update() called");
// TODO Auto-generated method stub // TODO Auto-generated method stub
return 0; return 0;
} }
@Override @Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws SecurityException, FileNotFoundException { public ParcelFileDescriptor openFile(Uri uri, String mode) throws SecurityException, FileNotFoundException {
if(ApgService.LOCAL_LOGD) Log.d(TAG, "openFile() called"); if(ApgService2.LOCAL_LOGD) Log.d(TAG, "openFile() called");
if(ApgService.LOCAL_LOGD) Log.d(TAG, "... with uri: "+uri.toString()); if(ApgService2.LOCAL_LOGD) Log.d(TAG, "... with uri: "+uri.toString());
if(ApgService.LOCAL_LOGD) Log.d(TAG, "... with mode: "+mode); if(ApgService2.LOCAL_LOGD) Log.d(TAG, "... with mode: "+mode);
List<String> segments = uri.getPathSegments(); List<String> segments = uri.getPathSegments();
if(segments.size() < 2) { if(segments.size() < 2) {
@ -115,8 +115,8 @@ public class ApgServiceBlobProvider extends ContentProvider {
String id = segments.get(0); String id = segments.get(0);
String key = segments.get(1); String key = segments.get(1);
if(ApgService.LOCAL_LOGD) Log.d(TAG, "... got id: "+id); if(ApgService2.LOCAL_LOGD) Log.d(TAG, "... got id: "+id);
if(ApgService.LOCAL_LOGD) Log.d(TAG, "... and key: "+key); if(ApgService2.LOCAL_LOGD) Log.d(TAG, "... and key: "+key);
// get the data // get the data
Cursor result = mDb.query(id, key); Cursor result = mDb.query(id, key);
@ -128,7 +128,7 @@ public class ApgServiceBlobProvider extends ContentProvider {
File targetFile = new File(STORE_PATH, id); File targetFile = new File(STORE_PATH, id);
if(mode.equals("w")) { if(mode.equals("w")) {
if(ApgService.LOCAL_LOGD) Log.d(TAG, "... will try to open file w"); if(ApgService2.LOCAL_LOGD) Log.d(TAG, "... will try to open file w");
if( !targetFile.exists() ) { if( !targetFile.exists() ) {
try { try {
targetFile.createNewFile(); targetFile.createNewFile();
@ -139,7 +139,7 @@ public class ApgServiceBlobProvider extends ContentProvider {
} }
return ParcelFileDescriptor.open(targetFile, ParcelFileDescriptor.MODE_WRITE_ONLY | ParcelFileDescriptor.MODE_TRUNCATE ); return ParcelFileDescriptor.open(targetFile, ParcelFileDescriptor.MODE_WRITE_ONLY | ParcelFileDescriptor.MODE_TRUNCATE );
} else if(mode.equals("r")) { } else if(mode.equals("r")) {
if(ApgService.LOCAL_LOGD) Log.d(TAG, "... will try to open file r"); if(ApgService2.LOCAL_LOGD) Log.d(TAG, "... will try to open file r");
if( !targetFile.exists() ) { if( !targetFile.exists() ) {
throw new FileNotFoundException("Error: Could not find the file requested"); throw new FileNotFoundException("Error: Could not find the file requested");
} }

View File

@ -1,4 +1,3 @@
/** /**
* TODO: * TODO:
* - Reimplement all the threads in the activitys as intents in this intentService * - Reimplement all the threads in the activitys as intents in this intentService
@ -7,6 +6,201 @@
package org.thialfihar.android.apg.service; package org.thialfihar.android.apg.service;
public class ApgService { 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.PGPSecretKeyRing;
import org.thialfihar.android.apg.Apg;
import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.ProgressDialogUpdater;
import org.thialfihar.android.apg.ui.widget.KeyEditor;
import org.thialfihar.android.apg.ui.widget.SectionView;
import android.app.IntentService;
import android.content.Intent;
import android.os.Bundle;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
//TODO: ProgressDialogUpdater rework???
public class ApgService extends IntentService implements ProgressDialogUpdater {
// extras that can be given by intent
public static final String EXTRA_MESSENGER = "messenger";
public static final String EXTRA_ACTION = "action";
public static final String EXTRA_DATA = "data";
// keys for data bundle
// edit keys
public static final String DATA_NEW_PASSPHRASE = "new_passphrase";
public static final String DATA_CURRENT_PASSPHRASE = "current_passphrase";
public static final String DATA_USER_IDS = "user_ids";
public static final String DATA_KEYS = "keys";
public static final String DATA_KEYS_USAGES = "keys_usages";
public static final String DATA_MASTER_KEY_ID = "master_key_id";
// possible ints for EXTRA_ACTION
public static final int ACTION_SAVE_KEYRING = 1;
// 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;
public ApgService() {
super("ApgService");
}
/**
* The IntentService calls this method from the default worker thread with the intent that
* started the service. When this method returns, IntentService stops the service, as
* appropriate.
*/
@Override
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
if (extras != null) {
if (!extras.containsKey(EXTRA_ACTION)) {
Log.e(Constants.TAG, "Extra bundle must contain a action!");
return;
}
if (!extras.containsKey(EXTRA_MESSENGER)) {
Log.e(Constants.TAG, "Extra bundle must contain a messenger!");
return;
}
mMessenger = (Messenger) extras.get(EXTRA_MESSENGER);
Bundle data = null;
if (extras.containsKey(EXTRA_DATA)) {
data = extras.getBundle(EXTRA_DATA);
}
int action = extras.getInt(EXTRA_ACTION);
// will be filled if error occurs
String error = "";
// execute action from extra bundle
switch (action) {
case ACTION_SAVE_KEYRING:
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);
break;
default:
break;
}
}
}
private void sendErrorToUi(String error) {
Bundle data = new Bundle();
data.putString(MESSAGE_DATA_ERROR, error);
sendMessageToUi(MESSAGE_EXCEPTION, null, data);
}
private void sendMessageToUi(Integer arg1, Integer arg2, Bundle data) {
Message msg = Message.obtain();
msg.arg1 = arg1;
if (arg2 != null) {
msg.arg2 = arg2;
}
if (data != null) {
msg.setData(data);
}
try {
mMessenger.send(msg);
} catch (RemoteException e) {
Log.w(Constants.TAG, "Exception sending message", e);
} catch (NullPointerException e) {
Log.w(Constants.TAG, "Messenger is null!", e);
}
}
public void setProgress(int resourceId, int progress, int max) {
setProgress(getString(resourceId), progress, max);
}
public void setProgress(int progress, int max) {
Message msg = new Message();
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

@ -17,19 +17,20 @@
package org.thialfihar.android.apg.ui; package org.thialfihar.android.apg.ui;
import org.spongycastle.openpgp.PGPException;
import org.spongycastle.openpgp.PGPSecretKey; import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing; 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.provider.Database; 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.util.IterableIterator; import org.thialfihar.android.apg.util.IterableIterator;
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.view.Menu; import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem; import com.actionbarsherlock.view.MenuItem;
@ -39,7 +40,10 @@ 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.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;
@ -53,15 +57,11 @@ 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.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SignatureException;
import java.util.Vector; import java.util.Vector;
public class EditKeyActivity extends BaseActivity { public class EditKeyActivity extends SherlockActivity { // extends BaseActivity {
private Intent mIntent = null; private Intent mIntent = null;
private ActionBar mActionBar; private ActionBar mActionBar;
@ -343,68 +343,205 @@ public class EditKeyActivity extends BaseActivity {
Toast.makeText(this, R.string.setAPassPhrase, Toast.LENGTH_SHORT).show(); Toast.makeText(this, R.string.setAPassPhrase, Toast.LENGTH_SHORT).show();
return; return;
} }
showDialog(Id.dialog.saving); // showDialog(Id.dialog.saving);
startThread();
} ProgressDialogFragment newFragment = ProgressDialogFragment.newInstance(
ProgressDialogFragment.ID_SAVING);
newFragment.show(getSupportFragmentManager(), "saving");
// ((ProgressDialog) newFragment.getDialog()).setProgress(value)
@Override // startThread();
public void run() {
String error = null; // Send all information needed to service to edit key in other thread
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(); Bundle data = new Bundle();
Message msg = new Message(); data.putString(ApgService.DATA_CURRENT_PASSPHRASE, mCurrentPassPhrase);
data.putString(ApgService.DATA_NEW_PASSPHRASE, mNewPassPhrase);
data.putSerializable(ApgService.DATA_USER_IDS, getUserIds(mUserIds));
try { Vector<PGPSecretKey> keys = getKeys(mKeys);
String oldPassPhrase = mCurrentPassPhrase;
String newPassPhrase = mNewPassPhrase; // convert to byte[]
if (newPassPhrase == null) { ByteArrayOutputStream os = new ByteArrayOutputStream();
newPassPhrase = oldPassPhrase; 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();
} }
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); byte[] keysBytes = os.toByteArray();
if (error != null) { data.putByteArray(ApgService.DATA_KEYS, keysBytes);
data.putString(Apg.EXTRA_ERROR, error);
}
msg.setData(data); data.putSerializable(ApgService.DATA_KEYS_USAGES, getKeysUsages(mKeys).toArray());
sendMessage(msg); data.putLong(ApgService.DATA_MASTER_KEY_ID, getMasterKeyId());
intent.putExtra(ApgService.EXTRA_DATA, data);
startService(intent);
} }
@Override private Handler handler = new Handler() {
public void doneCallback(Message msg) { public void handleMessage(Message message) {
super.doneCallback(msg); Object path = message.obj;
if (message.arg1 == ApgService.MESSAGE_OKAY) {
Toast.makeText(EditKeyActivity.this, "okay", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(EditKeyActivity.this, "nope", Toast.LENGTH_LONG).show();
}
Bundle data = msg.getData(); };
removeDialog(Id.dialog.saving); };
String error = data.getString(Apg.EXTRA_ERROR); // TODO: put in other class
if (error != null) { private Vector<String> getUserIds(SectionView userIdsView) {
Toast.makeText(EditKeyActivity.this, getString(R.string.errorMessage, error), Vector<String> userIds = new Vector<String>();
Toast.LENGTH_SHORT).show();
} else { ViewGroup userIdEditors = userIdsView.getEditors();
Toast.makeText(EditKeyActivity.this, R.string.keySaved, Toast.LENGTH_SHORT).show();
setResult(RESULT_OK); boolean gotMainUserId = false;
finish(); for (int i = 0; i < userIdEditors.getChildCount(); ++i) {
UserIdEditor editor = (UserIdEditor) userIdEditors.getChildAt(i);
String userId = null;
try {
userId = editor.getValue();
} catch (UserIdEditor.NoNameException e) {
// throw new Apg.GeneralException(this.getString(R.string.error_userIdNeedsAName));
} catch (UserIdEditor.NoEmailException e) {
// throw new Apg.GeneralException(
// this.getString(R.string.error_userIdNeedsAnEmailAddress));
} catch (UserIdEditor.InvalidEmailException e) {
// throw new Apg.GeneralException("" + e);
}
if (userId.equals("")) {
continue;
}
if (editor.isMainUserId()) {
userIds.insertElementAt(userId, 0);
gotMainUserId = true;
} else {
userIds.add(userId);
}
} }
if (userIds.size() == 0) {
// throw new Apg.GeneralException(context.getString(R.string.error_keyNeedsAUserId));
}
if (!gotMainUserId) {
// throw new Apg.GeneralException(
// context.getString(R.string.error_mainUserIdMustNotBeEmpty));
}
return userIds;
} }
private Vector<PGPSecretKey> getKeys(SectionView keysView) {
Vector<PGPSecretKey> keys = new Vector<PGPSecretKey>();
ViewGroup keyEditors = keysView.getEditors();
if (keyEditors.getChildCount() == 0) {
// throw new Apg.GeneralException(getString(R.string.error_keyNeedsMasterKey));
}
for (int i = 0; i < keyEditors.getChildCount(); ++i) {
KeyEditor editor = (KeyEditor) keyEditors.getChildAt(i);
keys.add(editor.getValue());
}
return keys;
}
private Vector<Integer> getKeysUsages(SectionView keysView) {
Vector<Integer> getKeysUsages = new Vector<Integer>();
ViewGroup keyEditors = keysView.getEditors();
if (keyEditors.getChildCount() == 0) {
// throw new Apg.GeneralException(getString(R.string.error_keyNeedsMasterKey));
}
for (int i = 0; i < keyEditors.getChildCount(); ++i) {
KeyEditor editor = (KeyEditor) keyEditors.getChildAt(i);
getKeysUsages.add(editor.getUsage());
}
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

@ -0,0 +1,42 @@
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

@ -0,0 +1,98 @@
package org.thialfihar.android.apg.ui;
import org.thialfihar.android.apg.R;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnKeyListener;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.KeyEvent;
public class ProgressDialogFragment extends DialogFragment {
public static final int ID_ENCRYPTING = 1;
public static final int ID_DECRYPTING = 2;
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) {
ProgressDialogFragment frag = new ProgressDialogFragment();
Bundle args = new Bundle();
args.putInt("id", id);
frag.setArguments(args);
return frag;
}
public static void test() {
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Activity activity = getActivity();
ProgressDialog dialog = new ProgressDialog(activity);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setCancelable(false);
int id = getArguments().getInt("id");
switch (id) {
case ID_ENCRYPTING:
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
// OnKeyListener keyListener = new OnKeyListener() {
//
// @Override
// public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
//
// if (keyCode == KeyEvent.KEYCODE_BACK) {
// return true;
// }
// return false;
// }
//
// };
// dialog.setOnKeyListener(keyListener);
return dialog;
}
}

View File

@ -56,7 +56,7 @@ public class IntentDemoActivity extends Activity {
public void intentDemoCreateNewKeyOnClick(View view) { public void intentDemoCreateNewKeyOnClick(View view) {
// mApgIntentHelper.createNewKey(); // mApgIntentHelper.createNewKey();
mApgIntentHelper.createNewKey("test <+491716581452@cryptocall.org>", true, true); mApgIntentHelper.createNewKey("test <+491711111111@cryptocall.org>", true, true);
} }
public void intentDemoSelectSecretKeyOnClick(View view) { public void intentDemoSelectSecretKeyOnClick(View view) {