query key externalized into service

This commit is contained in:
Dominik 2012-09-10 17:55:54 +02:00
parent 6096f7e8ca
commit 23ce0e37fd
5 changed files with 188 additions and 94 deletions

View File

@ -44,6 +44,7 @@ import org.thialfihar.android.apg.helper.PGPConversionHelper;
import org.thialfihar.android.apg.provider.DataProvider;
import org.thialfihar.android.apg.util.HkpKeyServer;
import org.thialfihar.android.apg.util.InputData;
import org.thialfihar.android.apg.util.KeyServer.KeyInfo;
import org.thialfihar.android.apg.util.ProgressDialogUpdater;
import android.app.IntentService;
@ -131,6 +132,12 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
public static final String UPLOAD_KEY_SERVER = "uploadKeyServer";
public static final String UPLOAD_KEY_KEYRING_ID = "uploadKeyRingId";
// query key
public static final String QUERY_KEY_SERVER = "queryKeyServer";
public static final String QUERY_KEY_TYPE = "queryKeyType";
public static final String QUERY_KEY_STRING = "queryKeyString";
public static final String QUERY_KEY_ID = "queryKeyId";
/* possible EXTRA_ACTIONs */
public static final int ACTION_ENCRYPT_SIGN = 10;
@ -146,6 +153,7 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
public static final int ACTION_EXPORT_KEY = 51;
public static final int ACTION_UPLOAD_KEY = 60;
public static final int ACTION_QUERY_KEY = 61;
/* possible data keys as result send over messenger */
// keys
@ -175,6 +183,10 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
public static final String RESULT_IMPORT_UPDATED = "updated";
public static final String RESULT_IMPORT_BAD = "bad";
// query
public static final String RESULT_QUERY_KEY_KEY_DATA = "queryKeyKeyData";
public static final String RESULT_QUERY_KEY_SEARCH_RESULT = "queryKeySearchResult";
Messenger mMessenger;
public ApgService() {
@ -713,7 +725,7 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
try {
/* Input */
int keyRingId = data.getInt(UPLOAD_KEY_KEYRING_ID);
String keyServer = data.getString(UPLOAD_KEY_SERVER);
@ -739,6 +751,39 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
break;
case ACTION_QUERY_KEY:
try {
/* Input */
int queryType = data.getInt(QUERY_KEY_TYPE);
String keyServer = data.getString(QUERY_KEY_SERVER);
String queryString = data.getString(QUERY_KEY_STRING);
long queryId = data.getLong(QUERY_KEY_ID);
/* Operation */
Bundle resultData = new Bundle();
HkpKeyServer server = new HkpKeyServer(keyServer);
if (queryType == Id.keyserver.search) {
ArrayList<KeyInfo> searchResult = server.search(queryString);
resultData.putParcelableArrayList(RESULT_QUERY_KEY_SEARCH_RESULT, searchResult);
} else if (queryType == Id.keyserver.get) {
String keyData = server.get(queryId);
resultData.putString(RESULT_QUERY_KEY_KEY_DATA, keyData);
}
sendMessageToHandler(ApgHandler.MESSAGE_OKAY, resultData);
} catch (Exception e) {
sendErrorToHandler(e);
}
break;
default:
break;
}

View File

@ -14,28 +14,30 @@
package org.thialfihar.android.apg.ui;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import org.thialfihar.android.apg.R;
import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.helper.PGPHelper;
import org.thialfihar.android.apg.util.HkpKeyServer;
import org.thialfihar.android.apg.util.KeyServer.InsufficientQuery;
import org.thialfihar.android.apg.helper.Preferences;
import org.thialfihar.android.apg.service.ApgHandler;
import org.thialfihar.android.apg.service.ApgService;
import org.thialfihar.android.apg.ui.dialog.ProgressDialogFragment;
import org.thialfihar.android.apg.util.Log;
import org.thialfihar.android.apg.util.KeyServer.KeyInfo;
import org.thialfihar.android.apg.util.KeyServer.QueryException;
import org.thialfihar.android.apg.util.KeyServer.TooManyResponses;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.MenuItem;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Message;
import android.os.Messenger;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
@ -53,7 +55,7 @@ import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
public class KeyServerQueryActivity extends BaseActivity {
public class KeyServerQueryActivity extends SherlockFragmentActivity {
// possible intent actions for this activity
public static final String ACTION_LOOK_UP_KEY_ID = Constants.INTENT_PREFIX + "LOOK_UP_KEY_ID";
@ -62,8 +64,7 @@ public class KeyServerQueryActivity extends BaseActivity {
public static final String EXTRA_KEY_ID = "keyId";
// TODO: remove when using new intentservice:
public static final String EXTRA_ERROR = "error";
// TODO: Change?
public static final String EXTRA_TEXT = "text";
private ListView mList;
@ -110,7 +111,8 @@ public class KeyServerQueryActivity extends BaseActivity {
mKeyServer = (Spinner) findViewById(R.id.keyServer);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, mPreferences.getKeyServers());
android.R.layout.simple_spinner_item, Preferences.getPreferences(this)
.getKeyServers());
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mKeyServer.setAdapter(adapter);
if (adapter.getCount() > 0) {
@ -145,99 +147,108 @@ public class KeyServerQueryActivity extends BaseActivity {
}
private void search(String query) {
showDialog(Id.dialog.querying);
mQueryType = Id.keyserver.search;
mQueryString = query;
mAdapter.setKeys(new Vector<KeyInfo>());
startThread();
mAdapter.setKeys(new ArrayList<KeyInfo>());
start();
}
private void get(long keyId) {
showDialog(Id.dialog.querying);
mQueryType = Id.keyserver.get;
mQueryId = keyId;
startThread();
start();
}
@Override
protected Dialog onCreateDialog(int id) {
ProgressDialog progress = (ProgressDialog) super.onCreateDialog(id);
progress.setMessage(this.getString(R.string.progress_queryingServer,
(String) mKeyServer.getSelectedItem()));
return progress;
}
private void start() {
Log.d(Constants.TAG, "start search with service");
@Override
public void run() {
String error = null;
// Send all information needed to service to query keys in other thread
Intent intent = new Intent(this, ApgService.class);
intent.putExtra(ApgService.EXTRA_ACTION, ApgService.ACTION_QUERY_KEY);
// fill values for this action
Bundle data = new Bundle();
Message msg = new Message();
try {
HkpKeyServer server = new HkpKeyServer((String) mKeyServer.getSelectedItem());
if (mQueryType == Id.keyserver.search) {
mSearchResult = server.search(mQueryString);
} else if (mQueryType == Id.keyserver.get) {
mKeyData = server.get(mQueryId);
}
} catch (QueryException e) {
error = "" + e;
} catch (InsufficientQuery e) {
error = "Insufficient query.";
} catch (TooManyResponses e) {
error = "Too many responses.";
}
String server = (String) mKeyServer.getSelectedItem();
data.putString(ApgService.QUERY_KEY_SERVER, server);
data.putInt(Constants.extras.STATUS, Id.message.done);
if (error != null) {
data.putString(EXTRA_ERROR, error);
}
msg.setData(data);
sendMessage(msg);
}
@Override
public void doneCallback(Message msg) {
super.doneCallback(msg);
removeDialog(Id.dialog.querying);
Bundle data = msg.getData();
String error = data.getString(EXTRA_ERROR);
if (error != null) {
Toast.makeText(this, getString(R.string.errorMessage, error), Toast.LENGTH_SHORT)
.show();
return;
}
data.putInt(ApgService.QUERY_KEY_TYPE, mQueryType);
if (mQueryType == Id.keyserver.search) {
if (mSearchResult != null) {
Toast.makeText(this, getString(R.string.keysFound, mSearchResult.size()),
Toast.LENGTH_SHORT).show();
mAdapter.setKeys(mSearchResult);
}
data.putString(ApgService.QUERY_KEY_STRING, mQueryString);
} else if (mQueryType == Id.keyserver.get) {
Intent orgIntent = getIntent();
if (ACTION_LOOK_UP_KEY_ID_AND_RETURN.equals(orgIntent.getAction())) {
if (mKeyData != null) {
Intent intent = new Intent();
intent.putExtra(EXTRA_TEXT, mKeyData);
setResult(RESULT_OK, intent);
} else {
setResult(RESULT_CANCELED);
}
finish();
} else {
if (mKeyData != null) {
Intent intent = new Intent(this, PublicKeyListActivity.class);
intent.setAction(KeyListActivity.ACTION_IMPORT);
intent.putExtra(KeyListActivity.EXTRA_TEXT, mKeyData);
startActivity(intent);
}
}
data.putLong(ApgService.QUERY_KEY_ID, mQueryId);
}
intent.putExtra(ApgService.EXTRA_DATA, data);
// create progress dialog
ProgressDialogFragment queryingDialog = ProgressDialogFragment.newInstance(
R.string.progress_querying, ProgressDialog.STYLE_SPINNER);
// Message is received after querying is done in ApgService
ApgHandler saveHandler = new ApgHandler(this, queryingDialog) {
public void handleMessage(Message message) {
// handle messages by standard ApgHandler first
super.handleMessage(message);
if (message.arg1 == ApgHandler.MESSAGE_OKAY) {
// get returned data bundle
Bundle returnData = message.getData();
if (mQueryType == Id.keyserver.search) {
mSearchResult = returnData
.getParcelableArrayList(ApgService.RESULT_QUERY_KEY_SEARCH_RESULT);
} else if (mQueryType == Id.keyserver.get) {
mKeyData = returnData.getString(ApgService.RESULT_QUERY_KEY_KEY_DATA);
}
// TODO: IMPROVE CODE!!! some global variables can be avoided!!!
if (mQueryType == Id.keyserver.search) {
if (mSearchResult != null) {
Toast.makeText(KeyServerQueryActivity.this,
getString(R.string.keysFound, mSearchResult.size()),
Toast.LENGTH_SHORT).show();
mAdapter.setKeys(mSearchResult);
}
} else if (mQueryType == Id.keyserver.get) {
Intent orgIntent = getIntent();
if (ACTION_LOOK_UP_KEY_ID_AND_RETURN.equals(orgIntent.getAction())) {
if (mKeyData != null) {
Intent intent = new Intent();
intent.putExtra(EXTRA_TEXT, mKeyData);
setResult(RESULT_OK, intent);
} else {
setResult(RESULT_CANCELED);
}
finish();
} else {
if (mKeyData != null) {
Intent intent = new Intent(KeyServerQueryActivity.this,
PublicKeyListActivity.class);
intent.setAction(KeyListActivity.ACTION_IMPORT);
intent.putExtra(KeyListActivity.EXTRA_TEXT, mKeyData);
startActivity(intent);
}
}
}
}
};
};
// Create a new Messenger for the communication back
Messenger messenger = new Messenger(saveHandler);
intent.putExtra(ApgService.EXTRA_MESSENGER, messenger);
// show progress dialog
queryingDialog.show(getSupportFragmentManager(), "queryingDialog");
// start service with intent
startService(intent);
}
public class KeyInfoListAdapter extends BaseAdapter {
@ -248,7 +259,7 @@ public class KeyServerQueryActivity extends BaseActivity {
public KeyInfoListAdapter(Activity activity) {
mActivity = activity;
mInflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mKeys = new Vector<KeyInfo>();
mKeys = new ArrayList<KeyInfo>();
}
public void setKeys(List<KeyInfo> keys) {

View File

@ -29,7 +29,6 @@ import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -141,9 +140,9 @@ public class HkpKeyServer extends KeyServer {
}
@Override
public List<KeyInfo> search(String query) throws QueryException, TooManyResponses,
public ArrayList<KeyInfo> search(String query) throws QueryException, TooManyResponses,
InsufficientQuery {
Vector<KeyInfo> results = new Vector<KeyInfo>();
ArrayList<KeyInfo> results = new ArrayList<KeyInfo>();
if (query.length() < 3) {
throw new InsufficientQuery();
@ -185,7 +184,7 @@ public class HkpKeyServer extends KeyServer {
String chunks[] = matcher.group(4).split("-");
info.date = new GregorianCalendar(Integer.parseInt(chunks[0]),
Integer.parseInt(chunks[1]), Integer.parseInt(chunks[2])).getTime();
info.userIds = new Vector<String>();
info.userIds = new ArrayList<String>();
if (matcher.group(5).startsWith("*** KEY")) {
info.revoked = matcher.group(5);
} else {

View File

@ -17,10 +17,14 @@
package org.thialfihar.android.apg.util;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Vector;
import android.os.Parcel;
import android.os.Parcelable;
public abstract class KeyServer {
static public class QueryException extends Exception {
private static final long serialVersionUID = 2703768928624654512L;
@ -42,15 +46,47 @@ public abstract class KeyServer {
private static final long serialVersionUID = -507574859137295530L;
}
static public class KeyInfo implements Serializable {
static public class KeyInfo implements Serializable, Parcelable {
private static final long serialVersionUID = -7797972113284992662L;
public Vector<String> userIds;
public ArrayList<String> userIds;
public String revoked;
public Date date;
public String fingerPrint;
public long keyId;
public int size;
public String algorithm;
public KeyInfo() {
userIds = new ArrayList<String>();
}
public KeyInfo(Parcel in) {
this();
in.readStringList(this.userIds);
this.revoked = in.readString();
this.date = (Date) in.readSerializable();
this.fingerPrint = in.readString();
this.keyId = in.readLong();
this.size = in.readInt();
this.algorithm = in.readString();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeStringList(userIds);
dest.writeString(revoked);
dest.writeSerializable(date);
dest.writeString(fingerPrint);
dest.writeLong(keyId);
dest.writeInt(size);
dest.writeString(algorithm);
}
}
abstract List<KeyInfo> search(String query) throws QueryException, TooManyResponses,

View File

@ -18,6 +18,9 @@ package org.thialfihar.android.apg.util;
import java.math.BigInteger;
/**
* Primes for ElGamal
*/
public final class Primes {
// taken from http://www.ietf.org/rfc/rfc3526.txt
public static final String P1536 =