From fc08f14ef180d492f34d4fadeee321b5aabecf13 Mon Sep 17 00:00:00 2001
From: Markus Doits After an async execution is finished, obj.meth() will be called. You can
+ * use this in order to get notified, when encrypting/decrypting of long
+ * data finishes and do not have to poll {@link #is_running()} in your
+ * thread. Note, that if the call of the method fails for whatever reason,
+ * you won't get notified in any way - so you still should check
+ * {@link #is_running()} from time to time. It produces a warning fetchable with {@link #get_next_warning()} when the callback fails.
+ * Creates a new ApgCon object and searches for the right APG version on
+ * initialization. If not found, errors are printed to the error log.
+ *
+ * This should be called whenever all work with APG is done (e.g. everything
+ * you wanted to encrypt is encrypted), since connections with AIDL should
+ * not be upheld indefinitely.
+ *
+ *
+ *
+ * Also, if you destroy you end using your ApgCon-instance, this must be
+ * called or else the connection to APG is leaked
+ *
+ * After you have set up everything with {@link #set_arg(String, String)}
+ * (and variants), you can call a function from the AIDL-interface. This
+ * will
+ *
+ *
+ *
+ * @param obj
+ * The object, which has the public method meth
+ * @param meth
+ * Method to call on the object obj
+ */
+ public void set_callback(Object obj, String meth) {
+ set_callback_object(obj);
+ set_callback_method(meth);
+ }
+
+ /**
+ * Set a callback object
+ *
+ * @param obj
+ * a object to call back after async execution
+ * @see #set_callback(Object, String)
+ */
+ public void set_callback_object(Object obj) {
+ callback_object = obj;
+ }
+
+ /**
+ * Set a callback method
+ *
+ * @param meth
+ * a method to call on a callback object after async execution
+ * @see #set_callback(Object, String)
+ */
+ public void set_callback_method(String meth) {
+ callback_method = meth;
+ }
+
+ public void clear_callback_object() {
+ callback_object = null;
+ }
+
+ public void clear_callback_method() {
+ callback_method = null;
+ }
+
+ public boolean is_running() {
+ return async_running;
+ }
+
public void reset() {
clear_errors();
clear_warnings();
clear_args();
clear_result();
- }
-
- public void disconnect() {
- Log.v(TAG, "disconnecting apgService");
- if (apgService != null) {
- mContext.unbindService(apgConnection);
- apgService = null;
- }
+ clear_callback_object();
+ clear_callback_method();
}
}
From e73794a5cc1f1c78485cce4282f5b2ecef549fe2 Mon Sep 17 00:00:00 2001
From: Markus Doits
+ * .... your class ...
+ * public void callback() {
+ * // do something after encryption finished
+ * }
+ *
+ * public void encrypt() {
+ * ApgCon mEnc = new ApgCon(context);
+ * // set parameters
+ * mEnc.set_arg(key, value);
+ * ...
+ *
+ * // set callback object and method
+ * mEnc.set_callback( this, "callback" );
+ *
+ * // start asynchronous call
+ * mEnc.call_async( call );
+ *
+ * // when the call_async finishes, the method "callback()" will be called automatically
+ * }
+ *
+ *
+ *
+ *
+ * Note your thread will be blocked during execution - if you want to call + * the function asynchronously, see {@link #call_async(String)}. + *
+ * + * @param function + * a remote function to call + * @return true, if call successful (= no errors), else false + * + * @see #call_async(String) + * @see #set_arg(String, String) + */ public boolean call(String function) { return this.call(function, args, result); } + /** + * Calls a function from remote interface asynchronously + * + *+ * This does exactly the same as {@link #call(String)}, but asynchronously. + * While connection to APG and work are done in background, your thread can + * go on executing. + *
+ * + *
+ * To see whether the task is finished, you have to possibilities: + *
+ * This defines a string argument for APG's AIDL-interface. + *
+ * + *+ * To know what key-value-pairs are possible (or required), take a look into + * the IApgService.aidl + *
+ * + *+ * Note, that the parameters are not deleted after a call, so you have to + * reset ({@link #clear_args()}) them manually if you want to. + *
+ * + * + * @param key + * the key + * @param val + * the value + * + * @see #clear_args() + */ public void set_arg(String key, String val) { args.putString(key, val); } + /** + * Set a string-array argument for APG + * + *
+ * If the AIDL-parameter is an {@literal ArrayList
+ *
+ * set_arg("a key", new String[]{ "entry 1", "entry 2" });
+ *
+ *
+ *
+ * @param key
+ * the key
+ * @param vals
+ * the value
+ *
+ * @see #set_arg(String, String)
+ */
public void set_arg(String key, String vals[]) {
ArrayList
+ * If the AIDL-parameter is an {@literal ArrayList
+ * Anything the has been set up with the various + * {@link #set_arg(String, String)} functions, is cleared. + *
+ *+ * Note, that any warning, error, callback, result etc. is not cleared with + * this. + *
+ * + * @see #reset() + */ public void clear_args() { args.clear(); } + /** + * Return the object associated with the key + * + * @param key + * the object's key you want to return + * @return an object at position key, or null if not set + */ public Object get_arg(String key) { return args.get(key); } + /** + * Iterates through the errors + * + *+ * With this method, you can iterate through all errors. The errors are only + * returned once and deleted immediately afterwards, so you can only return + * each error once. + *
+ * + * @return a human readable description of a error that happened, or null if + * no more errors + * + * @see #has_next_error() + * @see #clear_errors() + */ public String get_next_error() { if (error_list.size() != 0) return error_list.remove(0); @@ -267,10 +451,32 @@ public class ApgCon { return null; } + /** + * Check, if there are any new errors + * + * @return true, if there are unreturned errors, false otherwise + * + * @see #get_next_error() + */ public boolean has_next_error() { return error_list.size() != 0; } + /** + * Iterates through the warnings + * + *+ * With this method, you can iterate through all warnings. The warnings are + * only returned once and deleted immediately afterwards, so you can only + * return each warning once. + *
+ * + * @return a human readable description of a warning that happened, or null + * if no more warnings + * + * @see #has_next_warning() + * @see #clear_warnings() + */ public String get_next_warning() { if (warning_list.size() != 0) return warning_list.remove(0); @@ -278,22 +484,68 @@ public class ApgCon { return null; } + /** + * Check, if there are any new warnings + * + * @return true, if there are unreturned warnings, false otherwise + * + * @see #get_next_warning() + */ public boolean has_next_warning() { return warning_list.size() != 0; } + /** + * Get the result + * + *+ * This gets your result. After doing anything with APG, you get the output + * with this function + *
+ *+ * Note, that when your last remote call is unsuccessful, the result will + * still have the same value like the last successful call (or null, if no + * call was successful). To ensure you do not work with old call's results, + * either be sure to {@link #reset()} (or at least {@link #clear_result()}) + * your instance before each new call or always check that + * {@link #has_next_error()} is false. + *
+ * + * @return the result of the last {@link #call(String)} or + * {@link #call_asinc(String)}. + * + * @see #reset() + * @see #clear_result() + */ public String get_result() { return result.getString("RESULT"); } + /** + * Clears all unfetched errors + * + * @see #get_next_error() + * @see #has_next_error() + */ public void clear_errors() { error_list.clear(); } + /** + * Clears all unfetched warnings + * + * @see #get_next_warning() + * @see #has_next_warning() + */ public void clear_warnings() { warning_list.clear(); } + /** + * Clears the last result + * + * @see #get_result() + */ public void clear_result() { result.clear(); } @@ -301,14 +553,19 @@ public class ApgCon { /** * Set a callback object and method * - *After an async execution is finished, obj.meth() will be called. You can + *
+ * After an async execution is finished, obj.meth() will be called. You can * use this in order to get notified, when encrypting/decrypting of long * data finishes and do not have to poll {@link #is_running()} in your * thread. Note, that if the call of the method fails for whatever reason, * you won't get notified in any way - so you still should check - * {@link #is_running()} from time to time.
+ * {@link #is_running()} from time to time. + * * - *It produces a warning fetchable with {@link #get_next_warning()} when the callback fails.
+ *+ * It produces a warning fetchable with {@link #get_next_warning()} when the + * callback fails. + *
* *
*
@@ -366,18 +623,67 @@ public class ApgCon {
callback_method = meth;
}
+ /**
+ * Clears any callback object
+ *
+ * @see #set_callback(Object, String)
+ */
public void clear_callback_object() {
callback_object = null;
}
+ /**
+ * Clears any callback method
+ *
+ * @see #set_callback(Object, String)
+ */
public void clear_callback_method() {
callback_method = null;
}
+ /**
+ * Clears any callback method and object
+ *
+ * @see #set_callback(Object, String)
+ */
+ public void clear_callback() {
+ clear_callback_object();
+ clear_callback_method();
+ }
+
+ /**
+ * Checks, whether an async execution is running
+ *
+ *
+ * If you started something with {@link #call_async(String)}, this will
+ * return true if the task is still running
+ *
+ *
+ * @return true, if an async task is still running, false otherwise
+ *
+ * @see #call_async(String)
+ */
public boolean is_running() {
return async_running;
}
+ /**
+ * Completely resets your instance
+ *
+ *
+ * This currently resets everything in this instance. Errors, warnings,
+ * results, callbacks, ... are removed. Any connection to the remote
+ * interface is upheld, though.
+ *
+ *
+ *
+ * Note, that when an async execution ({@link #call_async(String)}) is
+ * running, it's result, warnings etc. will still be evaluated (which might
+ * be not what you want). Also mind, that any callback you set is also
+ * reseted, so on finishing the async execution any defined callback will
+ * NOT BE TRIGGERED.
+ *
+ */
public void reset() {
clear_errors();
clear_warnings();
From 15bf93de348410fe3bad0aae9d869f04676ffb06 Mon Sep 17 00:00:00 2001
From: Markus Doits
Date: Thu, 20 Jan 2011 12:49:49 +0000
Subject: [PATCH 41/69] Fix wrong param in doc
---
src/org/thialfihar/android/apg/IApgService.aidl | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/org/thialfihar/android/apg/IApgService.aidl b/src/org/thialfihar/android/apg/IApgService.aidl
index 89ea62827..896314635 100644
--- a/src/org/thialfihar/android/apg/IApgService.aidl
+++ b/src/org/thialfihar/android/apg/IApgService.aidl
@@ -42,7 +42,7 @@ interface IApgService {
* String "SIGNATURE_KEY" = Key to sign with
*
* (optional)
- * String "SIGNATURE_KEY_PASSPHRASE" = Passphrase for signing key
+ * String "PRIVATE_KEY_PASSPHRASE" = Passphrase for signing key
*
* Bundle return_vals (in addition to the ERRORS/WARNINGS above):
* String "RESULT" = Encrypted message
From 3e158d0afc585e9fddd202c0fb7ddbe3f215fc30 Mon Sep 17 00:00:00 2001
From: Markus Doits
Date: Thu, 20 Jan 2011 16:36:03 +0000
Subject: [PATCH 42/69] Some better errors (hopefully more information)
Some smaller fixes and some new functions/doc, too
---
.../thialfihar/android/apg/utils/ApgCon.java | 108 +++++++++++++++---
1 file changed, 89 insertions(+), 19 deletions(-)
diff --git a/src/org/thialfihar/android/apg/utils/ApgCon.java b/src/org/thialfihar/android/apg/utils/ApgCon.java
index 296c966a5..9c47f111e 100644
--- a/src/org/thialfihar/android/apg/utils/ApgCon.java
+++ b/src/org/thialfihar/android/apg/utils/ApgCon.java
@@ -37,14 +37,15 @@ public class ApgCon {
async_running = false;
if (callback_object != null && callback_method != null) {
try {
+ Log.d(TAG, "About to execute callback");
callback_object.getClass().getMethod(callback_method).invoke(callback_object);
Log.d(TAG, "Callback executed");
} catch (NoSuchMethodException e) {
Log.w(TAG, "Exception in callback: Method '" + callback_method + "' not found");
- warning_list.add("LOCAL: Could not execute callback, method '" + callback_method + "' not found");
+ warning_list.add("(LOCAL) Could not execute callback, method '" + callback_method + "' not found");
} catch (Exception e) {
- Log.w(TAG, "Exception on callback: " + e.getMessage());
- warning_list.add("LOCAL: Could not execute callback");
+ Log.w(TAG, "Exception on callback: (" + e.getClass() + ") " + e.getMessage());
+ warning_list.add("(LOCAL) Could not execute callback");
}
}
}
@@ -63,6 +64,7 @@ public class ApgCon {
private final Bundle args = new Bundle();
private final ArrayList error_list = new ArrayList();
private final ArrayList warning_list = new ArrayList();
+ private error local_error;
/** Remote service for decrypting and encrypting data */
private IApgService apgService = null;
@@ -85,6 +87,16 @@ public class ApgCon {
CANNOT_BIND_TO_APG, // connection to apg service not possible
CALL_MISSING, // function to call not provided
CALL_NOT_KNOWN, // apg service does not know what to do
+ APG_NOT_FOUND, // could not find APG installed
+ APG_AIDL_MISSING, // found APG but without AIDL interface
+ }
+
+ public static enum ret {
+ ERROR, // returned from AIDL
+ RESULT, // returned from AIDL
+ WARNINGS, // mixed AIDL and LOCAL
+ ERRORS, // mixed AIDL and LOCAL
+ LOCAL_ERROR, // LOCAL error
}
/**
@@ -117,9 +129,11 @@ public class ApgCon {
if (inf.metaData == null) {
Log.w(TAG, "Could not determine ApgService API");
Log.w(TAG, "This probably won't work!");
+ warning_list.add("(LOCAL) Could not determine ApgService API");
} else if (inf.metaData.getInt("api_version") != api_version) {
Log.w(TAG, "Found ApgService API version" + inf.metaData.getInt("api_version") + " but exspected " + api_version);
Log.w(TAG, "This probably won't work!");
+ warning_list.add("(LOCAL) Found ApgService API version" + inf.metaData.getInt("api_version") + " but exspected " + api_version);
} else {
Log.v(TAG, "Found api_version " + api_version + ", everything should work");
}
@@ -128,10 +142,14 @@ public class ApgCon {
if (!apg_service_found) {
Log.e(TAG, "Could not find APG with AIDL interface, this probably won't work");
+ error_list.add("(LOCAL) Could not find APG with AIDL interface, this probably won't work");
+ local_error = error.APG_AIDL_MISSING;
}
}
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Could not find APG, is it installed?");
+ error_list.add("(LOCAL) Could not find APG, is it installed?");
+ local_error = error.APG_NOT_FOUND;
}
}
@@ -262,31 +280,33 @@ public class ApgCon {
warning_list.clear();
if (!initialize()) {
- error_list.add("LOCAL: Cannot bind to ApgService");
- pReturn.putInt("LOCAL_ERROR", error.CANNOT_BIND_TO_APG.ordinal());
+ error_list.add("(LOCAL) Cannot bind to ApgService");
+ local_error = error.CANNOT_BIND_TO_APG;
return false;
}
if (function == null || function.length() == 0) {
- error_list.add("LOCAL: Function to call missing");
- pReturn.putInt("LOCAL_ERROR", error.CALL_MISSING.ordinal());
+ error_list.add("(LOCAL) Function to call missing");
+ local_error = error.CALL_MISSING;
return false;
}
try {
- Boolean ret = (Boolean) IApgService.class.getMethod(function, Bundle.class, Bundle.class).invoke(apgService, pArgs, pReturn);
- error_list.addAll(pReturn.getStringArrayList("ERRORS"));
- warning_list.addAll(pReturn.getStringArrayList("WARNINGS"));
- return ret;
+ Boolean success = (Boolean) IApgService.class.getMethod(function, Bundle.class, Bundle.class).invoke(apgService, pArgs, pReturn);
+ error_list.addAll(pReturn.getStringArrayList(ret.ERRORS.name()));
+ warning_list.addAll(pReturn.getStringArrayList(ret.WARNINGS.name()));
+ pReturn.remove(ret.ERRORS.name());
+ pReturn.remove(ret.WARNINGS.name());
+ return success;
} catch (NoSuchMethodException e) {
- Log.e(TAG, e.getMessage());
- error_list.add("LOCAL: " + e.getMessage());
- pReturn.putInt("LOCAL_ERROR", error.CALL_NOT_KNOWN.ordinal());
+ Log.e(TAG, "Remote call not known (" + function + "): " + e.getMessage());
+ error_list.add("(LOCAL) Remote call not known (" + function + "): " + e.getMessage());
+ local_error = error.CALL_NOT_KNOWN;
return false;
} catch (Exception e) {
Log.e(TAG, "" + e.getMessage());
- error_list.add("LOCAL: " + e.getMessage());
- pReturn.putInt("LOCAL_ERROR", error.GENERIC.ordinal());
+ error_list.add("(LOCAL) Generic error (" + e.getClass() + "): " + e.getMessage());
+ local_error = error.GENERIC;
return false;
}
@@ -462,6 +482,54 @@ public class ApgCon {
return error_list.size() != 0;
}
+ /**
+ * Returns the type of error happened
+ *
+ *
+ * Currently, two error types are possible:
+ *
+ * - ret.LOCAL_ERROR: An error that happened on the caller site. This
+ * might be something like connection to AIDL not possible or the funciton
+ * call not know by AIDL. This means, the instance is not set up correctly
+ * or prerequisites to use APG with AIDL are not met.
+ * - ret.ERROR: Connection to APG was successful, and the call started but
+ * failed. Mostly this is because of wrong or missing parameters for APG.
+ *
+ *
+ *
+ * @return the type of error that happend: ret.LOCAL_ERROR or ret.ERROR, or
+ * null if none happend
+ */
+ public ret get_error_type() {
+ if (local_error != null) {
+ return ret.LOCAL_ERROR;
+ } else if (result.containsKey(ret.ERROR.name())) {
+ return ret.ERROR;
+ } else {
+ return null;
+ }
+ }
+
+ public error get_local_error() {
+ return local_error;
+ }
+
+ public void clear_local_error() {
+ local_error = null;
+ }
+
+ public int get_remote_error() {
+ if (result.containsKey(ret.ERROR.name())) {
+ return result.getInt(ret.ERROR.name());
+ } else {
+ return -1;
+ }
+ }
+
+ public void clear_remote_error() {
+ result.remove(ret.ERROR.name());
+ }
+
/**
* Iterates through the warnings
*
@@ -518,7 +586,7 @@ public class ApgCon {
* @see #clear_result()
*/
public String get_result() {
- return result.getString("RESULT");
+ return result.getString(ret.RESULT.name());
}
/**
@@ -529,6 +597,8 @@ public class ApgCon {
*/
public void clear_errors() {
error_list.clear();
+ result.remove(ret.ERROR.name());
+ clear_local_error();
}
/**
@@ -547,7 +617,7 @@ public class ApgCon {
* @see #get_result()
*/
public void clear_result() {
- result.clear();
+ result.remove(ret.RESULT.name());
}
/**
@@ -688,9 +758,9 @@ public class ApgCon {
clear_errors();
clear_warnings();
clear_args();
- clear_result();
clear_callback_object();
clear_callback_method();
+ result.clear();
}
}
From 72ab7fb25ffe193aa418ba0ba31fc292d8235e62 Mon Sep 17 00:00:00 2001
From: Markus Doits
Date: Thu, 20 Jan 2011 16:40:45 +0000
Subject: [PATCH 43/69] Some more error output
---
src/org/thialfihar/android/apg/utils/ApgCon.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/org/thialfihar/android/apg/utils/ApgCon.java b/src/org/thialfihar/android/apg/utils/ApgCon.java
index 9c47f111e..16ba94a1f 100644
--- a/src/org/thialfihar/android/apg/utils/ApgCon.java
+++ b/src/org/thialfihar/android/apg/utils/ApgCon.java
@@ -45,7 +45,7 @@ public class ApgCon {
warning_list.add("(LOCAL) Could not execute callback, method '" + callback_method + "' not found");
} catch (Exception e) {
Log.w(TAG, "Exception on callback: (" + e.getClass() + ") " + e.getMessage());
- warning_list.add("(LOCAL) Could not execute callback");
+ warning_list.add("(LOCAL) Could not execute callback (" + e.getClass() + "): " + e.getMessage());
}
}
}
@@ -304,7 +304,7 @@ public class ApgCon {
local_error = error.CALL_NOT_KNOWN;
return false;
} catch (Exception e) {
- Log.e(TAG, "" + e.getMessage());
+ Log.e(TAG, "Generic error (" + e.getClass() + "): " + e.getMessage());
error_list.add("(LOCAL) Generic error (" + e.getClass() + "): " + e.getMessage());
local_error = error.GENERIC;
return false;
@@ -525,7 +525,7 @@ public class ApgCon {
return -1;
}
}
-
+
public void clear_remote_error() {
result.remove(ret.ERROR.name());
}
From d4901f5999b51398b3a2ff43ba82f356225f4fef Mon Sep 17 00:00:00 2001
From: Markus Doits
Date: Thu, 20 Jan 2011 16:53:51 +0000
Subject: [PATCH 44/69] Catch callback's and apg-call's (are there any?)
exceptions
---
src/org/thialfihar/android/apg/utils/ApgCon.java | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/src/org/thialfihar/android/apg/utils/ApgCon.java b/src/org/thialfihar/android/apg/utils/ApgCon.java
index 16ba94a1f..4852ad548 100644
--- a/src/org/thialfihar/android/apg/utils/ApgCon.java
+++ b/src/org/thialfihar/android/apg/utils/ApgCon.java
@@ -1,5 +1,6 @@
package org.thialfihar.android.apg.utils;
+import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import android.content.Context;
@@ -42,7 +43,12 @@ public class ApgCon {
Log.d(TAG, "Callback executed");
} catch (NoSuchMethodException e) {
Log.w(TAG, "Exception in callback: Method '" + callback_method + "' not found");
- warning_list.add("(LOCAL) Could not execute callback, method '" + callback_method + "' not found");
+ warning_list.add("(LOCAL) Could not execute callback, method '" + callback_method + "()' not found");
+ } catch (InvocationTargetException e) {
+ Throwable orig = e.getTargetException();
+ Log.w(TAG, "Exception of type '" + orig.getClass() + "' in callback's method '" + callback_method + "()':" + orig.getMessage());
+ warning_list.add("(LOCAL) Exception of type '" + orig.getClass() + "' in callback's method '" + callback_method + "()':"
+ + orig.getMessage());
} catch (Exception e) {
Log.w(TAG, "Exception on callback: (" + e.getClass() + ") " + e.getMessage());
warning_list.add("(LOCAL) Could not execute callback (" + e.getClass() + "): " + e.getMessage());
@@ -303,8 +309,13 @@ public class ApgCon {
error_list.add("(LOCAL) Remote call not known (" + function + "): " + e.getMessage());
local_error = error.CALL_NOT_KNOWN;
return false;
+ } catch (InvocationTargetException e) {
+ Throwable orig = e.getTargetException();
+ Log.w(TAG, "Exception of type '" + orig.getClass() + "' on AIDL call '" + function + "':" + orig.getMessage());
+ error_list.add("(LOCAL) Exception of type '" + orig.getClass() + "' on AIDL call '" + function + "':" + orig.getMessage());
+ return false;
} catch (Exception e) {
- Log.e(TAG, "Generic error (" + e.getClass() + "): " + e.getMessage());
+ Log.e(TAG, "Generic error (" + e.getClass() + "): " + e.getMessage());
error_list.add("(LOCAL) Generic error (" + e.getClass() + "): " + e.getMessage());
local_error = error.GENERIC;
return false;
From dfb4f4e03050757c9226f0a3b089cb18ab29c6f5 Mon Sep 17 00:00:00 2001
From: Markus Doits
Date: Thu, 20 Jan 2011 17:38:25 +0000
Subject: [PATCH 45/69] Allow at compile time to enable stacktraces on
exceptions
---
.../thialfihar/android/apg/utils/ApgCon.java | 25 +++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/src/org/thialfihar/android/apg/utils/ApgCon.java b/src/org/thialfihar/android/apg/utils/ApgCon.java
index 4852ad548..5277222eb 100644
--- a/src/org/thialfihar/android/apg/utils/ApgCon.java
+++ b/src/org/thialfihar/android/apg/utils/ApgCon.java
@@ -24,6 +24,11 @@ import org.thialfihar.android.apg.IApgService;
*/
public class ApgCon {
+ /**
+ * Put stacktraces into the log?
+ */
+ private final boolean stacktraces = true;
+
private class call_async extends AsyncTask {
@Override
@@ -42,14 +47,20 @@ public class ApgCon {
callback_object.getClass().getMethod(callback_method).invoke(callback_object);
Log.d(TAG, "Callback executed");
} catch (NoSuchMethodException e) {
+ if (stacktraces)
+ e.printStackTrace();
Log.w(TAG, "Exception in callback: Method '" + callback_method + "' not found");
warning_list.add("(LOCAL) Could not execute callback, method '" + callback_method + "()' not found");
} catch (InvocationTargetException e) {
+ if (stacktraces)
+ e.printStackTrace();
Throwable orig = e.getTargetException();
Log.w(TAG, "Exception of type '" + orig.getClass() + "' in callback's method '" + callback_method + "()':" + orig.getMessage());
warning_list.add("(LOCAL) Exception of type '" + orig.getClass() + "' in callback's method '" + callback_method + "()':"
+ orig.getMessage());
} catch (Exception e) {
+ if (stacktraces)
+ e.printStackTrace();
Log.w(TAG, "Exception on callback: (" + e.getClass() + ") " + e.getMessage());
warning_list.add("(LOCAL) Could not execute callback (" + e.getClass() + "): " + e.getMessage());
}
@@ -153,6 +164,8 @@ public class ApgCon {
}
}
} catch (PackageManager.NameNotFoundException e) {
+ if (stacktraces)
+ e.printStackTrace();
Log.e(TAG, "Could not find APG, is it installed?");
error_list.add("(LOCAL) Could not find APG, is it installed?");
local_error = error.APG_NOT_FOUND;
@@ -171,6 +184,8 @@ public class ApgCon {
try {
mContext.bindService(new Intent(IApgService.class.getName()), apgConnection, Context.BIND_AUTO_CREATE);
} catch (Exception e) {
+ if (stacktraces)
+ e.printStackTrace();
Log.v(TAG, "could not bind APG service");
return false;
}
@@ -305,16 +320,22 @@ public class ApgCon {
pReturn.remove(ret.WARNINGS.name());
return success;
} catch (NoSuchMethodException e) {
+ if (stacktraces)
+ e.printStackTrace();
Log.e(TAG, "Remote call not known (" + function + "): " + e.getMessage());
error_list.add("(LOCAL) Remote call not known (" + function + "): " + e.getMessage());
local_error = error.CALL_NOT_KNOWN;
return false;
} catch (InvocationTargetException e) {
+ if (stacktraces)
+ e.printStackTrace();
Throwable orig = e.getTargetException();
- Log.w(TAG, "Exception of type '" + orig.getClass() + "' on AIDL call '" + function + "':" + orig.getMessage());
- error_list.add("(LOCAL) Exception of type '" + orig.getClass() + "' on AIDL call '" + function + "':" + orig.getMessage());
+ Log.w(TAG, "Exception of type '" + orig.getClass() + "' on AIDL call '" + function + "': " + orig.getMessage());
+ error_list.add("(LOCAL) Exception of type '" + orig.getClass() + "' on AIDL call '" + function + "': " + orig.getMessage());
return false;
} catch (Exception e) {
+ if (stacktraces)
+ e.printStackTrace();
Log.e(TAG, "Generic error (" + e.getClass() + "): " + e.getMessage());
error_list.add("(LOCAL) Generic error (" + e.getClass() + "): " + e.getMessage());
local_error = error.GENERIC;
From 730b44bc73ca25cf0a5747f401bda18d0d010ee7 Mon Sep 17 00:00:00 2001
From: Markus Doits
Date: Thu, 20 Jan 2011 18:19:34 +0000
Subject: [PATCH 46/69] Make the stacktrace enabler static
---
src/org/thialfihar/android/apg/utils/ApgCon.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/org/thialfihar/android/apg/utils/ApgCon.java b/src/org/thialfihar/android/apg/utils/ApgCon.java
index 5277222eb..e05c7e8da 100644
--- a/src/org/thialfihar/android/apg/utils/ApgCon.java
+++ b/src/org/thialfihar/android/apg/utils/ApgCon.java
@@ -27,7 +27,7 @@ public class ApgCon {
/**
* Put stacktraces into the log?
*/
- private final boolean stacktraces = true;
+ private final static boolean stacktraces = true;
private class call_async extends AsyncTask {
From 05627fbd623411e0c138d5e182b207c222e46e31 Mon Sep 17 00:00:00 2001
From: Markus Doits
Date: Thu, 20 Jan 2011 18:19:42 +0000
Subject: [PATCH 47/69] Print some info about keys on asymmetric encryption
---
src/org/thialfihar/android/apg/ApgService.java | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java
index fe9e84d4b..4e55f80d7 100644
--- a/src/org/thialfihar/android/apg/ApgService.java
+++ b/src/org/thialfihar/android/apg/ApgService.java
@@ -199,10 +199,15 @@ public class ApgService extends Service {
while (mCursor.moveToNext()) {
long _cur_mkey = mCursor.getLong(1);
String _cur_user = mCursor.getString(2);
+
+ String _cur_fprint = Apg.getSmallFingerPrint(_cur_mkey);
Log.d(TAG, "current master key: " + _cur_mkey + " from " + _cur_user);
- if (search_keys.contains(Apg.getSmallFingerPrint(_cur_mkey)) || search_keys.contains(_cur_user)) {
- Log.d(TAG, "master key found for: " + Apg.getSmallFingerPrint(_cur_mkey));
+ if (search_keys.contains(_cur_fprint) || search_keys.contains(_cur_user)) {
+ Log.v(TAG, "master key found for: " + _cur_fprint);
_master_keys.add(_cur_mkey);
+ search_keys.remove(_cur_fprint);
+ } else {
+ Log.v(TAG, "Installed key "+_cur_fprint+" is not in the list of public keys to encrypt with");
}
}
mCursor.close();
@@ -212,6 +217,15 @@ public class ApgService extends Service {
for (Long _key : _master_keys) {
_master_longs[i++] = _key;
}
+
+ if( i == 0) {
+ Log.e(TAG, "Found no public key to encrypt with, APG will error out");
+ }
+
+ for( String _key : search_keys) {
+ Log.w(TAG, "Cannot encrypt with key "+_key+": cannot find it in APG");
+ }
+
return _master_longs;
}
From 1af5a985b5db356860a622dacda767c85ef444e6 Mon Sep 17 00:00:00 2001
From: Markus Doits
Date: Thu, 20 Jan 2011 18:25:38 +0000
Subject: [PATCH 48/69] Redefine some log-msges
---
src/org/thialfihar/android/apg/ApgService.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java
index 4e55f80d7..b7c4f0d4a 100644
--- a/src/org/thialfihar/android/apg/ApgService.java
+++ b/src/org/thialfihar/android/apg/ApgService.java
@@ -195,13 +195,14 @@ public class ApgService extends Service {
"" + Id.database.type_public
}, null, null, orderBy);
+ Log.v(TAG, "going through installed user keys");
ArrayList _master_keys = new ArrayList();
while (mCursor.moveToNext()) {
long _cur_mkey = mCursor.getLong(1);
String _cur_user = mCursor.getString(2);
String _cur_fprint = Apg.getSmallFingerPrint(_cur_mkey);
- Log.d(TAG, "current master key: " + _cur_mkey + " from " + _cur_user);
+ Log.v(TAG, "current user: "+_cur_user+" ("+_cur_fprint+")");
if (search_keys.contains(_cur_fprint) || search_keys.contains(_cur_user)) {
Log.v(TAG, "master key found for: " + _cur_fprint);
_master_keys.add(_cur_mkey);
From 392969629c9fb4953a0a257e866d8538515faa50 Mon Sep 17 00:00:00 2001
From: Markus Doits
Date: Thu, 20 Jan 2011 18:38:15 +0000
Subject: [PATCH 49/69] Some better (non-misleading) error msgs
Also some reindentation
---
.../thialfihar/android/apg/ApgService.java | 32 ++++++++++---------
1 file changed, 17 insertions(+), 15 deletions(-)
diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java
index b7c4f0d4a..fc6742445 100644
--- a/src/org/thialfihar/android/apg/ApgService.java
+++ b/src/org/thialfihar/android/apg/ApgService.java
@@ -150,13 +150,13 @@ public class ApgService extends Service {
* fingerprint or user id to search for
* @return master key if found, or 0
*/
- private static long get_master_key(String search_key) {
+ private static long get_master_key(String search_key, Bundle pReturn) {
if (search_key == null || search_key.length() != 8) {
return 0;
}
ArrayList tmp = new ArrayList();
tmp.add(search_key);
- long[] _keys = get_master_key(tmp);
+ long[] _keys = get_master_key(tmp, pReturn);
if (_keys.length > 0)
return _keys[0];
else
@@ -171,7 +171,7 @@ public class ApgService extends Service {
* database
* @return an array of master keys
*/
- private static long[] get_master_key(ArrayList search_keys) {
+ private static long[] get_master_key(ArrayList search_keys, Bundle pReturn) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(KeyRings.TABLE_NAME + " INNER JOIN " + Keys.TABLE_NAME + " ON " + "(" + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + Keys.TABLE_NAME
@@ -200,15 +200,15 @@ public class ApgService extends Service {
while (mCursor.moveToNext()) {
long _cur_mkey = mCursor.getLong(1);
String _cur_user = mCursor.getString(2);
-
+
String _cur_fprint = Apg.getSmallFingerPrint(_cur_mkey);
- Log.v(TAG, "current user: "+_cur_user+" ("+_cur_fprint+")");
+ Log.v(TAG, "current user: " + _cur_user + " (" + _cur_fprint + ")");
if (search_keys.contains(_cur_fprint) || search_keys.contains(_cur_user)) {
Log.v(TAG, "master key found for: " + _cur_fprint);
_master_keys.add(_cur_mkey);
search_keys.remove(_cur_fprint);
} else {
- Log.v(TAG, "Installed key "+_cur_fprint+" is not in the list of public keys to encrypt with");
+ Log.v(TAG, "Installed key " + _cur_fprint + " is not in the list of public keys to encrypt with");
}
}
mCursor.close();
@@ -218,15 +218,17 @@ public class ApgService extends Service {
for (Long _key : _master_keys) {
_master_longs[i++] = _key;
}
-
- if( i == 0) {
- Log.e(TAG, "Found no public key to encrypt with, APG will error out");
+
+ if (i == 0) {
+ Log.w(TAG, "Found not one public key");
+ pReturn.getStringArrayList(ret.WARNINGS.name()).add("Searched for public key(s) but found not one");
}
-
- for( String _key : search_keys) {
- Log.w(TAG, "Cannot encrypt with key "+_key+": cannot find it in APG");
+
+ for (String _key : search_keys) {
+ Log.w(TAG, "Searched for key " + _key + " but cannot find it in APG");
+ pReturn.getStringArrayList(ret.WARNINGS.name()).add("Searched for key " + _key + " but cannot find it in APG");
}
-
+
return _master_longs;
}
@@ -372,7 +374,7 @@ public class ApgService extends Service {
while (_iter.hasNext()) {
_pub_keys.add(_iter.next());
}
- _pub_master_keys = get_master_key(_pub_keys);
+ _pub_master_keys = get_master_key(_pub_keys, pReturn);
}
InputStream _inStream = new ByteArrayInputStream(pArgs.getString(arg.MESSAGE.name()).getBytes());
@@ -385,7 +387,7 @@ public class ApgService extends Service {
_out, // output stream
pArgs.getBoolean(arg.ARMORED_OUTPUT.name()), // ARMORED_OUTPUT
_pub_master_keys, // encryption keys
- get_master_key(pArgs.getString(arg.SIGNATURE_KEY.name())), // signature key
+ get_master_key(pArgs.getString(arg.SIGNATURE_KEY.name()), pReturn), // signature key
pArgs.getString(arg.PRIVATE_KEY_PASSPHRASE.name()), // signature passphrase
null, // progress
pArgs.getInt(arg.ENCRYPTION_ALGORYTHM.name()), // encryption
From c9f6f56827ce7b368a009c153d1f9995651f6522 Mon Sep 17 00:00:00 2001
From: Markus Doits
Date: Thu, 20 Jan 2011 20:00:28 +0000
Subject: [PATCH 50/69] Work on errors and documentation - once more
---
.../thialfihar/android/apg/ApgService.java | 20 +--
.../thialfihar/android/apg/IApgService.aidl | 9 +-
.../thialfihar/android/apg/utils/ApgCon.java | 117 +++++++++---------
3 files changed, 77 insertions(+), 69 deletions(-)
diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java
index fc6742445..c4a348cb4 100644
--- a/src/org/thialfihar/android/apg/ApgService.java
+++ b/src/org/thialfihar/android/apg/ApgService.java
@@ -38,7 +38,11 @@ public class ApgService extends Service {
APG_FAILURE,
NO_MATCHING_SECRET_KEY,
PRIVATE_KEY_PASSPHRASE_WRONG,
- PRIVATE_KEY_PASSPHRASE_MISSING
+ PRIVATE_KEY_PASSPHRASE_MISSING;
+
+ public int shifted_ordinal() {
+ return ordinal() + 100;
+ }
}
/** all arguments that can be passed by calling application */
@@ -355,7 +359,7 @@ public class ApgService extends Service {
/* return if errors happened */
if (pReturn.getStringArrayList(ret.ERRORS.name()).size() != 0) {
- pReturn.putInt(ret.ERROR.name(), error.ARGUMENTS_MISSING.ordinal());
+ pReturn.putInt(ret.ERROR.name(), error.ARGUMENTS_MISSING.shifted_ordinal());
return false;
}
Log.v(TAG, "error return");
@@ -401,13 +405,13 @@ public class ApgService extends Service {
String _msg = e.getMessage();
if (_msg.equals(getBaseContext().getString(R.string.error_noSignaturePassPhrase))) {
pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot encrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + " missing): " + _msg);
- pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_MISSING.ordinal());
+ pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_MISSING.shifted_ordinal());
} else if (_msg.equals(getBaseContext().getString(R.string.error_couldNotExtractPrivateKey))) {
pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot encrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + " probably wrong): " + _msg);
- pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_WRONG.ordinal());
+ pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_WRONG.shifted_ordinal());
} else {
pReturn.getStringArrayList(ret.ERRORS.name()).add("Internal failure (" + e.getClass() + ") in APG when encrypting: " + e.getMessage());
- pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.ordinal());
+ pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.shifted_ordinal());
}
return false;
}
@@ -455,13 +459,13 @@ public class ApgService extends Service {
String _msg = e.getMessage();
if (_msg.equals(getBaseContext().getString(R.string.error_noSecretKeyFound))) {
pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot decrypt: " + _msg);
- pReturn.putInt(ret.ERROR.name(), error.NO_MATCHING_SECRET_KEY.ordinal());
+ pReturn.putInt(ret.ERROR.name(), error.NO_MATCHING_SECRET_KEY.shifted_ordinal());
} else if (_msg.equals(getBaseContext().getString(R.string.error_wrongPassPhrase))) {
pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot decrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + " wrong/missing): " + _msg);
- pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_WRONG.ordinal());
+ pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_WRONG.shifted_ordinal());
} else {
pReturn.getStringArrayList(ret.ERRORS.name()).add("Internal failure (" + e.getClass() + ") in APG when decrypting: " + _msg);
- pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.ordinal());
+ pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.shifted_ordinal());
}
return false;
}
diff --git a/src/org/thialfihar/android/apg/IApgService.aidl b/src/org/thialfihar/android/apg/IApgService.aidl
index 896314635..c35e82df7 100644
--- a/src/org/thialfihar/android/apg/IApgService.aidl
+++ b/src/org/thialfihar/android/apg/IApgService.aidl
@@ -5,8 +5,13 @@ interface IApgService {
/* All functions fill the return_vals Bundle with the following keys:
*
* ArrayList "WARNINGS" = Warnings, if any
- * ArrayList "ERRORS" = Human readable error descriptions, why function call failed
- * int "ERROR" = Numeric representation of error
+ * ArrayList "ERRORS" = Human readable error descriptions, if any
+ * int "ERROR" = Numeric representation of error, if any, starting with 100
+ * 100: Required argument missing
+ * 101: Generic failure of APG
+ * 102: No matching private key found
+ * 103: Private key's passphrase wrong
+ * 104: Private key's passphrase missing
*/
/* Encryption function's arguments
diff --git a/src/org/thialfihar/android/apg/utils/ApgCon.java b/src/org/thialfihar/android/apg/utils/ApgCon.java
index e05c7e8da..b80b66daa 100644
--- a/src/org/thialfihar/android/apg/utils/ApgCon.java
+++ b/src/org/thialfihar/android/apg/utils/ApgCon.java
@@ -17,10 +17,20 @@ import android.util.Log;
import org.thialfihar.android.apg.IApgService;
/**
- * This class can be used by other projects to simplify connecting to the
- * APG-Service. Kind of wrapper of for AIDL.
+ * A APG-AIDL-Wrapper
*
+ *
+ * This class can be used by other projects to simplify connecting to the
+ * APG-AIDL-Service. Kind of wrapper of for AIDL.
+ *
+ *
+ *
* It is not used in this project.
+ *
+ *
+ * @author Markus Doits
+ * @version 0.9
+ *
*/
public class ApgCon {
@@ -81,7 +91,6 @@ public class ApgCon {
private final Bundle args = new Bundle();
private final ArrayList error_list = new ArrayList();
private final ArrayList warning_list = new ArrayList();
- private error local_error;
/** Remote service for decrypting and encrypting data */
private IApgService apgService = null;
@@ -99,21 +108,44 @@ public class ApgCon {
}
};
+ /**
+ * Different types of local errors
+ *
+ * @author markus
+ *
+ */
public static enum error {
- GENERIC, // no special type
- CANNOT_BIND_TO_APG, // connection to apg service not possible
- CALL_MISSING, // function to call not provided
- CALL_NOT_KNOWN, // apg service does not know what to do
- APG_NOT_FOUND, // could not find APG installed
- APG_AIDL_MISSING, // found APG but without AIDL interface
+ /**
+ * generic error
+ */
+ GENERIC,
+ /**
+ * connection to apg service not possible
+ */
+ CANNOT_BIND_TO_APG,
+ /**
+ * function to call not provided
+ */
+ CALL_MISSING,
+ /**
+ * apg service does not know what to do
+ */
+ CALL_NOT_KNOWN,
+ /**
+ * could not find APG being installed
+ */
+ APG_NOT_FOUND,
+ /**
+ * found APG but without AIDL interface
+ */
+ APG_AIDL_MISSING
}
- public static enum ret {
+ private static enum ret {
ERROR, // returned from AIDL
RESULT, // returned from AIDL
WARNINGS, // mixed AIDL and LOCAL
ERRORS, // mixed AIDL and LOCAL
- LOCAL_ERROR, // LOCAL error
}
/**
@@ -160,7 +192,7 @@ public class ApgCon {
if (!apg_service_found) {
Log.e(TAG, "Could not find APG with AIDL interface, this probably won't work");
error_list.add("(LOCAL) Could not find APG with AIDL interface, this probably won't work");
- local_error = error.APG_AIDL_MISSING;
+ result.putInt(ret.ERROR.name(), error.APG_AIDL_MISSING.ordinal());
}
}
} catch (PackageManager.NameNotFoundException e) {
@@ -168,7 +200,7 @@ public class ApgCon {
e.printStackTrace();
Log.e(TAG, "Could not find APG, is it installed?");
error_list.add("(LOCAL) Could not find APG, is it installed?");
- local_error = error.APG_NOT_FOUND;
+ result.putInt(ret.ERROR.name(), error.APG_NOT_FOUND.ordinal());
}
}
@@ -297,18 +329,15 @@ public class ApgCon {
private boolean call(String function, Bundle pArgs, Bundle pReturn) {
- error_list.clear();
- warning_list.clear();
-
if (!initialize()) {
error_list.add("(LOCAL) Cannot bind to ApgService");
- local_error = error.CANNOT_BIND_TO_APG;
+ result.putInt(ret.ERROR.name(), error.CANNOT_BIND_TO_APG.ordinal());
return false;
}
if (function == null || function.length() == 0) {
error_list.add("(LOCAL) Function to call missing");
- local_error = error.CALL_MISSING;
+ result.putInt(ret.ERROR.name(), error.CALL_MISSING.ordinal());
return false;
}
@@ -324,7 +353,7 @@ public class ApgCon {
e.printStackTrace();
Log.e(TAG, "Remote call not known (" + function + "): " + e.getMessage());
error_list.add("(LOCAL) Remote call not known (" + function + "): " + e.getMessage());
- local_error = error.CALL_NOT_KNOWN;
+ result.putInt(ret.ERROR.name(), error.CALL_NOT_KNOWN.ordinal());
return false;
} catch (InvocationTargetException e) {
if (stacktraces)
@@ -338,7 +367,7 @@ public class ApgCon {
e.printStackTrace();
Log.e(TAG, "Generic error (" + e.getClass() + "): " + e.getMessage());
error_list.add("(LOCAL) Generic error (" + e.getClass() + "): " + e.getMessage());
- local_error = error.GENERIC;
+ result.putInt(ret.ERROR.name(), error.GENERIC.ordinal());
return false;
}
@@ -515,51 +544,22 @@ public class ApgCon {
}
/**
- * Returns the type of error happened
+ * Get the numeric representation of the last error
*
*
- * Currently, two error types are possible:
- *
- * - ret.LOCAL_ERROR: An error that happened on the caller site. This
- * might be something like connection to AIDL not possible or the funciton
- * call not know by AIDL. This means, the instance is not set up correctly
- * or prerequisites to use APG with AIDL are not met.
- * - ret.ERROR: Connection to APG was successful, and the call started but
- * failed. Mostly this is because of wrong or missing parameters for APG.
- *
+ * Values <100 mean the error happened locally, values >=100 mean the error
+ * happened at the remote side (APG). See the IApgService.aidl (or get the
+ * human readable description with {@link #get_next_error()}) for what
+ * errors >=100 mean.
*
*
- * @return the type of error that happend: ret.LOCAL_ERROR or ret.ERROR, or
- * null if none happend
+ * @return the id of the error that happened
*/
- public ret get_error_type() {
- if (local_error != null) {
- return ret.LOCAL_ERROR;
- } else if (result.containsKey(ret.ERROR.name())) {
- return ret.ERROR;
- } else {
- return null;
- }
- }
-
- public error get_local_error() {
- return local_error;
- }
-
- public void clear_local_error() {
- local_error = null;
- }
-
- public int get_remote_error() {
- if (result.containsKey(ret.ERROR.name())) {
+ public int get_error() {
+ if (result.containsKey(ret.ERROR.name()))
return result.getInt(ret.ERROR.name());
- } else {
+ else
return -1;
- }
- }
-
- public void clear_remote_error() {
- result.remove(ret.ERROR.name());
}
/**
@@ -630,7 +630,6 @@ public class ApgCon {
public void clear_errors() {
error_list.clear();
result.remove(ret.ERROR.name());
- clear_local_error();
}
/**
From b5097b7a417b13c288adfbd1c0ea4f6d86715cf1 Mon Sep 17 00:00:00 2001
From: Markus Doits
Date: Thu, 20 Jan 2011 20:23:13 +0000
Subject: [PATCH 51/69] Some more verbose logs
---
src/org/thialfihar/android/apg/ApgService.java | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java
index c4a348cb4..b36b5cd0a 100644
--- a/src/org/thialfihar/android/apg/ApgService.java
+++ b/src/org/thialfihar/android/apg/ApgService.java
@@ -385,6 +385,7 @@ public class ApgService extends Service {
InputData _in = new InputData(_inStream, 0); // XXX Size second param?
OutputStream _out = new ByteArrayOutputStream();
+ Log.v(TAG, "About to encrypt");
try {
Apg.encrypt(getBaseContext(), // context
_in, // input stream
@@ -450,6 +451,7 @@ public class ApgService extends Service {
InputStream inStream = new ByteArrayInputStream(pArgs.getString(arg.MESSAGE.name()).getBytes());
InputData in = new InputData(inStream, 0); // XXX what size in second parameter?
OutputStream out = new ByteArrayOutputStream();
+ Log.v(TAG, "About to decrypt");
try {
Apg.decrypt(getBaseContext(), in, out, _passphrase, null, // progress
pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) != null // symmetric
@@ -469,6 +471,7 @@ public class ApgService extends Service {
}
return false;
}
+ Log.v(TAG, "Decrypted");
pReturn.putString(ret.RESULT.name(), out.toString());
return true;
From 4b882fa90bd59765d27f8462c505315233d4475c Mon Sep 17 00:00:00 2001
From: Markus Doits
Date: Sun, 23 Jan 2011 21:36:20 +0000
Subject: [PATCH 52/69] Other applications must user permission to read key
details to connect to AIDL interface
This is necessary, because upcoming version of the aidl-interface will
be able to return fingerprints and user ids to applications.
---
AndroidManifest.xml | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index a6580a57c..937eb488a 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -195,7 +195,12 @@
android:configChanges="keyboardHidden|orientation|keyboard"/>
-
+
From 6b7db8161a158e12344145815534f6552797cf6d Mon Sep 17 00:00:00 2001
From: Markus Doits
Date: Sun, 23 Jan 2011 21:36:27 +0000
Subject: [PATCH 53/69] Don't query things we don't need
---
src/org/thialfihar/android/apg/ApgService.java | 16 ++++------------
1 file changed, 4 insertions(+), 12 deletions(-)
diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java
index b36b5cd0a..3fa88673f 100644
--- a/src/org/thialfihar/android/apg/ApgService.java
+++ b/src/org/thialfihar/android/apg/ApgService.java
@@ -6,7 +6,6 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
-import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -185,16 +184,9 @@ public class ApgService extends Service {
String orderBy = UserIds.TABLE_NAME + "." + UserIds.USER_ID + " ASC";
- long now = new Date().getTime() / 1000;
Cursor mCursor = qb.query(Apg.getDatabase().db(), new String[] {
- KeyRings.TABLE_NAME + "." + KeyRings._ID, // 0
- KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID, // 1
- UserIds.TABLE_NAME + "." + UserIds.USER_ID, // 2
- "(SELECT COUNT(tmp." + Keys._ID + ") FROM " + Keys.TABLE_NAME + " AS tmp WHERE " + "tmp." + Keys.KEY_RING_ID + " = " + KeyRings.TABLE_NAME
- + "." + KeyRings._ID + " AND " + "tmp." + Keys.IS_REVOKED + " = '0' AND " + "tmp." + Keys.CAN_ENCRYPT + " = '1')", // 3
- "(SELECT COUNT(tmp." + Keys._ID + ") FROM " + Keys.TABLE_NAME + " AS tmp WHERE " + "tmp." + Keys.KEY_RING_ID + " = " + KeyRings.TABLE_NAME
- + "." + KeyRings._ID + " AND " + "tmp." + Keys.IS_REVOKED + " = '0' AND " + "tmp." + Keys.CAN_ENCRYPT + " = '1' AND " + "tmp."
- + Keys.CREATION + " <= '" + now + "' AND " + "(tmp." + Keys.EXPIRY + " IS NULL OR " + "tmp." + Keys.EXPIRY + " >= '" + now + "'))", // 4
+ KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID, // 0
+ UserIds.TABLE_NAME + "." + UserIds.USER_ID, // 1
}, KeyRings.TABLE_NAME + "." + KeyRings.TYPE + " = ?", new String[] {
"" + Id.database.type_public
}, null, null, orderBy);
@@ -202,8 +194,8 @@ public class ApgService extends Service {
Log.v(TAG, "going through installed user keys");
ArrayList _master_keys = new ArrayList();
while (mCursor.moveToNext()) {
- long _cur_mkey = mCursor.getLong(1);
- String _cur_user = mCursor.getString(2);
+ long _cur_mkey = mCursor.getLong(0);
+ String _cur_user = mCursor.getString(1);
String _cur_fprint = Apg.getSmallFingerPrint(_cur_mkey);
Log.v(TAG, "current user: " + _cur_user + " (" + _cur_fprint + ")");
From 1ec5fc05412c6d7019dd40497a81397752bee602 Mon Sep 17 00:00:00 2001
From: Markus Doits
Date: Sun, 23 Jan 2011 21:36:35 +0000
Subject: [PATCH 54/69] Allow to retrieve fingerprints and user ids through
AIDL
Update ApgCon and doc accordingly.
Not very tested.
---
.../thialfihar/android/apg/ApgService.java | 148 ++++++++++++------
.../thialfihar/android/apg/IApgService.aidl | 33 +++-
.../thialfihar/android/apg/utils/ApgCon.java | 4 +
3 files changed, 136 insertions(+), 49 deletions(-)
diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java
index 3fa88673f..20bd1b1e3 100644
--- a/src/org/thialfihar/android/apg/ApgService.java
+++ b/src/org/thialfihar/android/apg/ApgService.java
@@ -9,7 +9,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
-import java.util.Set;
import org.thialfihar.android.apg.provider.KeyRings;
import org.thialfihar.android.apg.provider.Keys;
@@ -38,7 +37,7 @@ public class ApgService extends Service {
NO_MATCHING_SECRET_KEY,
PRIVATE_KEY_PASSPHRASE_WRONG,
PRIVATE_KEY_PASSPHRASE_MISSING;
-
+
public int shifted_ordinal() {
return ordinal() + 100;
}
@@ -55,8 +54,8 @@ public class ApgService extends Service {
FORCE_V3_SIGNATURE, // whether to force v3 signature
COMPRESSION, // what compression to use for encrypted output
SIGNATURE_KEY, // key for signing
- PRIVATE_KEY_PASSPHRASE
- // passphrase for encrypted private key
+ PRIVATE_KEY_PASSPHRASE, // passphrase for encrypted private key
+ KEY_TYPE, // type of key (private or public)
}
/** all things that might be returned */
@@ -64,12 +63,13 @@ public class ApgService extends Service {
ERRORS, // string array list with errors
WARNINGS, // string array list with warnings
ERROR, // numeric error
- RESULT
- // en-/decrypted
+ RESULT, // en-/decrypted
+ FINGERPRINTS, // fingerprints of keys
+ USER_IDS, // user ids
}
/** required arguments for each AIDL function */
- private static final HashMap> FUNCTIONS_REQUIRED_ARGS = new HashMap>();
+ private static final HashMap> FUNCTIONS_REQUIRED_ARGS = new HashMap>();
static {
HashSet args = new HashSet();
args.add(arg.SYMMETRIC_PASSPHRASE);
@@ -85,10 +85,14 @@ public class ApgService extends Service {
args.add(arg.MESSAGE);
FUNCTIONS_REQUIRED_ARGS.put("decrypt", args);
+ args = new HashSet();
+ args.add(arg.KEY_TYPE);
+ FUNCTIONS_REQUIRED_ARGS.put("get_keys", args);
+
}
/** optional arguments for each AIDL function */
- private static final HashMap> FUNCTIONS_OPTIONAL_ARGS = new HashMap>();
+ private static final HashMap> FUNCTIONS_OPTIONAL_ARGS = new HashMap>();
static {
HashSet args = new HashSet();
args.add(arg.ENCRYPTION_ALGORYTHM);
@@ -166,6 +170,26 @@ public class ApgService extends Service {
return 0;
}
+ private static Cursor get_key_entries(HashMap params) {
+ SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+ qb.setTables(KeyRings.TABLE_NAME + " INNER JOIN " + Keys.TABLE_NAME + " ON " + "(" + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + Keys.TABLE_NAME
+ + "." + Keys.KEY_RING_ID + " AND " + Keys.TABLE_NAME + "." + Keys.IS_MASTER_KEY + " = '1'" + ") " + " INNER JOIN " + UserIds.TABLE_NAME
+ + " ON " + "(" + Keys.TABLE_NAME + "." + Keys._ID + " = " + UserIds.TABLE_NAME + "." + UserIds.KEY_ID + " AND " + UserIds.TABLE_NAME + "."
+ + UserIds.RANK + " = '0') ");
+
+ String orderBy = params.containsKey("order_by") ? (String) params.get("order_by") : UserIds.TABLE_NAME + "." + UserIds.USER_ID + " ASC";
+
+ String type_val[] = null;
+ String type_where = null;
+ if (params.containsKey("key_type")) {
+ type_where = KeyRings.TABLE_NAME + "." + KeyRings.TYPE + " = ?";
+ type_val = new String[] {
+ "" + params.get("key_type")
+ };
+ }
+ return qb.query(Apg.getDatabase().db(), (String[]) params.get("columns"), type_where, type_val, null, null, orderBy);
+ }
+
/**
* maps fingerprints or user ids of keys to master keys in database
*
@@ -176,20 +200,14 @@ public class ApgService extends Service {
*/
private static long[] get_master_key(ArrayList search_keys, Bundle pReturn) {
- SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
- qb.setTables(KeyRings.TABLE_NAME + " INNER JOIN " + Keys.TABLE_NAME + " ON " + "(" + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + Keys.TABLE_NAME
- + "." + Keys.KEY_RING_ID + " AND " + Keys.TABLE_NAME + "." + Keys.IS_MASTER_KEY + " = '1'" + ") " + " INNER JOIN " + UserIds.TABLE_NAME
- + " ON " + "(" + Keys.TABLE_NAME + "." + Keys._ID + " = " + UserIds.TABLE_NAME + "." + UserIds.KEY_ID + " AND " + UserIds.TABLE_NAME + "."
- + UserIds.RANK + " = '0') ");
-
- String orderBy = UserIds.TABLE_NAME + "." + UserIds.USER_ID + " ASC";
-
- Cursor mCursor = qb.query(Apg.getDatabase().db(), new String[] {
+ HashMap qParams = new HashMap();
+ qParams.put("columns", new String[] {
KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID, // 0
UserIds.TABLE_NAME + "." + UserIds.USER_ID, // 1
- }, KeyRings.TABLE_NAME + "." + KeyRings.TYPE + " = ?", new String[] {
- "" + Id.database.type_public
- }, null, null, orderBy);
+ });
+ qParams.put("key_type", Id.database.type_public);
+
+ Cursor mCursor = get_key_entries(qParams);
Log.v(TAG, "going through installed user keys");
ArrayList _master_keys = new ArrayList();
@@ -235,27 +253,30 @@ public class ApgService extends Service {
* the bundle to add default parameters to if missing
*/
private void add_default_arguments(String call, Bundle args) {
- Preferences _mPreferences = Preferences.getPreferences(getBaseContext(), true);
+ // check whether there are optional elements defined for that call
+ if (FUNCTIONS_OPTIONAL_ARGS.containsKey(call)) {
+ Preferences _mPreferences = Preferences.getPreferences(getBaseContext(), true);
- Iterator _iter = FUNCTIONS_DEFAULTS.keySet().iterator();
- while (_iter.hasNext()) {
- arg _current_arg = _iter.next();
- String _current_key = _current_arg.name();
- if (!args.containsKey(_current_key) && FUNCTIONS_OPTIONAL_ARGS.get(call).contains(_current_arg)) {
- String _current_function_name = FUNCTIONS_DEFAULTS.get(_current_arg);
- try {
- Class> _ret_type = FUNCTIONS_DEFAULTS_TYPES.get(_current_function_name);
- if (_ret_type == String.class) {
- args.putString(_current_key, (String) FUNCTIONS_DEFAULTS_METHODS.get(_current_function_name).invoke(_mPreferences));
- } else if (_ret_type == boolean.class) {
- args.putBoolean(_current_key, (Boolean) FUNCTIONS_DEFAULTS_METHODS.get(_current_function_name).invoke(_mPreferences));
- } else if (_ret_type == int.class) {
- args.putInt(_current_key, (Integer) FUNCTIONS_DEFAULTS_METHODS.get(_current_function_name).invoke(_mPreferences));
- } else {
- Log.e(TAG, "Unknown return type " + _ret_type.toString() + " for default option");
+ Iterator _iter = FUNCTIONS_DEFAULTS.keySet().iterator();
+ while (_iter.hasNext()) {
+ arg _current_arg = _iter.next();
+ String _current_key = _current_arg.name();
+ if (!args.containsKey(_current_key) && FUNCTIONS_OPTIONAL_ARGS.get(call).contains(_current_arg)) {
+ String _current_function_name = FUNCTIONS_DEFAULTS.get(_current_arg);
+ try {
+ Class> _ret_type = FUNCTIONS_DEFAULTS_TYPES.get(_current_function_name);
+ if (_ret_type == String.class) {
+ args.putString(_current_key, (String) FUNCTIONS_DEFAULTS_METHODS.get(_current_function_name).invoke(_mPreferences));
+ } else if (_ret_type == boolean.class) {
+ args.putBoolean(_current_key, (Boolean) FUNCTIONS_DEFAULTS_METHODS.get(_current_function_name).invoke(_mPreferences));
+ } else if (_ret_type == int.class) {
+ args.putInt(_current_key, (Integer) FUNCTIONS_DEFAULTS_METHODS.get(_current_function_name).invoke(_mPreferences));
+ } else {
+ Log.e(TAG, "Unknown return type " + _ret_type.toString() + " for default option");
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Exception in add_default_arguments " + e.getMessage());
}
- } catch (Exception e) {
- Log.e(TAG, "Exception in add_default_arguments " + e.getMessage());
}
}
}
@@ -286,11 +307,13 @@ public class ApgService extends Service {
* the bundle to write errors to
*/
private void check_required_args(String function, Bundle pArgs, Bundle pReturn) {
- Iterator _iter = FUNCTIONS_REQUIRED_ARGS.get(function).iterator();
- while (_iter.hasNext()) {
- String _cur_arg = _iter.next().name();
- if (!pArgs.containsKey(_cur_arg)) {
- pReturn.getStringArrayList(ret.ERRORS.name()).add("Argument missing: " + _cur_arg);
+ if (FUNCTIONS_REQUIRED_ARGS.containsKey(function)) {
+ Iterator _iter = FUNCTIONS_REQUIRED_ARGS.get(function).iterator();
+ while (_iter.hasNext()) {
+ String _cur_arg = _iter.next().name();
+ if (!pArgs.containsKey(_cur_arg)) {
+ pReturn.getStringArrayList(ret.ERRORS.name()).add("Argument missing: " + _cur_arg);
+ }
}
}
}
@@ -306,8 +329,14 @@ public class ApgService extends Service {
* the bundle to write warnings to
*/
private void check_unknown_args(String function, Bundle pArgs, Bundle pReturn) {
- HashSet all_args = new HashSet(FUNCTIONS_REQUIRED_ARGS.get(function));
- all_args.addAll(FUNCTIONS_OPTIONAL_ARGS.get(function));
+
+ HashSet all_args = new HashSet();
+ if (FUNCTIONS_REQUIRED_ARGS.containsKey(function)) {
+ all_args.addAll(FUNCTIONS_REQUIRED_ARGS.get(function));
+ }
+ if (FUNCTIONS_OPTIONAL_ARGS.containsKey(function)) {
+ all_args.addAll(FUNCTIONS_OPTIONAL_ARGS.get(function));
+ }
ArrayList _unknown_args = new ArrayList();
Iterator _iter = pArgs.keySet().iterator();
@@ -415,6 +444,32 @@ public class ApgService extends Service {
private final IApgService.Stub mBinder = new IApgService.Stub() {
+ public boolean get_keys(Bundle pArgs, Bundle pReturn) {
+
+ prepare_args("get_keys", pArgs, pReturn);
+
+ HashMap qParams = new HashMap();
+ qParams.put("columns", new String[] {
+ KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID, // 0
+ UserIds.TABLE_NAME + "." + UserIds.USER_ID, // 1
+ });
+
+ qParams.put("key_type", pArgs.getInt(arg.KEY_TYPE.name()));
+
+ Cursor mCursor = get_key_entries(qParams);
+ ArrayList fprints = new ArrayList();
+ ArrayList ids = new ArrayList();
+ while (mCursor.moveToNext()) {
+ fprints.add(Apg.getSmallFingerPrint(mCursor.getLong(0)));
+ ids.add(mCursor.getString(1));
+ }
+ mCursor.close();
+
+ pReturn.putStringArrayList(ret.FINGERPRINTS.name(), fprints);
+ pReturn.putStringArrayList(ret.USER_IDS.name(), ids);
+ return true;
+ }
+
public boolean encrypt_with_public_key(Bundle pArgs, Bundle pReturn) {
if (!prepare_args("encrypt_with_public_key", pArgs, pReturn)) {
return false;
@@ -468,5 +523,6 @@ public class ApgService extends Service {
pReturn.putString(ret.RESULT.name(), out.toString());
return true;
}
+
};
}
diff --git a/src/org/thialfihar/android/apg/IApgService.aidl b/src/org/thialfihar/android/apg/IApgService.aidl
index c35e82df7..0eb1307b8 100644
--- a/src/org/thialfihar/android/apg/IApgService.aidl
+++ b/src/org/thialfihar/android/apg/IApgService.aidl
@@ -1,7 +1,7 @@
package org.thialfihar.android.apg;
interface IApgService {
-
+
/* All functions fill the return_vals Bundle with the following keys:
*
* ArrayList "WARNINGS" = Warnings, if any
@@ -14,7 +14,12 @@ interface IApgService {
* 104: Private key's passphrase missing
*/
- /* Encryption function's arguments
+ /* *******************************************************
+ * Encrypting and decrypting
+ * ********************************************************/
+
+
+ /* All encryption function's arguments
*
* Bundle params' keys:
* (optional/required)
@@ -82,5 +87,27 @@ interface IApgService {
* Bundle return_vals:
* String "RESULT" = Decrypted message
*/
- boolean decrypt(in Bundle params, out Bundle return_vals);
+
+ boolean decrypt(in Bundle params, out Bundle return_vals);
+
+
+ /* *******************************************************
+ * Get key information
+ * ********************************************************/
+
+ /* Get info about all available keys
+ *
+ * Bundle params:
+ * (required)
+ * int "KEY_TYPE" = info about what type of keys to return
+ * 0: public keys
+ * 1: private keys
+ *
+ * Returns:
+ * StringArrayList "FINGERPRINTS" = Short fingerprints of keys
+ *
+ * StringArrayList "USER_IDS" = User ids of corrosponding fingerprints (order is the same)
+ */
+ boolean get_keys(in Bundle params, out Bundle return_vals);
+
}
\ No newline at end of file
diff --git a/src/org/thialfihar/android/apg/utils/ApgCon.java b/src/org/thialfihar/android/apg/utils/ApgCon.java
index b80b66daa..225320108 100644
--- a/src/org/thialfihar/android/apg/utils/ApgCon.java
+++ b/src/org/thialfihar/android/apg/utils/ApgCon.java
@@ -327,6 +327,10 @@ public class ApgCon {
new call_async().execute(function);
}
+ public boolean call(String function, Bundle pReturn) {
+ return call(function, args, pReturn);
+ }
+
private boolean call(String function, Bundle pArgs, Bundle pReturn) {
if (!initialize()) {
From efc5575d56e4888f8335a76a7a44472aa53965ea Mon Sep 17 00:00:00 2001
From: Markus Doits
Date: Sun, 23 Jan 2011 21:36:44 +0000
Subject: [PATCH 55/69] Change the way the complete result can be retrieved
---
.../thialfihar/android/apg/utils/ApgCon.java | 32 +++++++++++++++----
1 file changed, 26 insertions(+), 6 deletions(-)
diff --git a/src/org/thialfihar/android/apg/utils/ApgCon.java b/src/org/thialfihar/android/apg/utils/ApgCon.java
index 225320108..9a0ccb44b 100644
--- a/src/org/thialfihar/android/apg/utils/ApgCon.java
+++ b/src/org/thialfihar/android/apg/utils/ApgCon.java
@@ -327,10 +327,6 @@ public class ApgCon {
new call_async().execute(function);
}
- public boolean call(String function, Bundle pReturn) {
- return call(function, args, pReturn);
- }
-
private boolean call(String function, Bundle pArgs, Bundle pReturn) {
if (!initialize()) {
@@ -603,8 +599,8 @@ public class ApgCon {
* Get the result
*
*
- * This gets your result. After doing anything with APG, you get the output
- * with this function
+ * This gets your result. After doing an encryption or decryption with APG,
+ * you get the output with this function.
*
*
* Note, that when your last remote call is unsuccessful, the result will
@@ -620,11 +616,35 @@ public class ApgCon {
*
* @see #reset()
* @see #clear_result()
+ * @see #get_result_bundle()
*/
public String get_result() {
return result.getString(ret.RESULT.name());
}
+ /**
+ * Get the result bundle
+ *
+ *
+ * Unlike {@link #get_result()}, which only returns any en-/decrypted
+ * message, this function returns the complete information that was returned
+ * by Apg. This also includes the "RESULT", but additionally the warnings,
+ * errors and any other information.
+ *
+ *
+ * For warnings and errors it is suggested to use the functions that are
+ * provided here, namely {@link #get_error()}, {@link #get_next_error()},
+ * {@link #get_next_Warning()} etc.), but if any call returns something non
+ * standard, you have access to the complete result bundle to extract the
+ * information.
+ *
+ *
+ * @return the complete result-bundle of the last call to apg
+ */
+ public Bundle get_result_bundle() {
+ return result;
+ }
+
/**
* Clears all unfetched errors
*
From cb4f1933d55abeda08623115464e393a886b8032 Mon Sep 17 00:00:00 2001
From: Markus Doits
Date: Sun, 23 Jan 2011 21:36:51 +0000
Subject: [PATCH 56/69] Dont remove result and warnings from result
Some more debug output, too
---
src/org/thialfihar/android/apg/ApgService.java | 2 ++
src/org/thialfihar/android/apg/utils/ApgCon.java | 2 --
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java
index 20bd1b1e3..87437e629 100644
--- a/src/org/thialfihar/android/apg/ApgService.java
+++ b/src/org/thialfihar/android/apg/ApgService.java
@@ -380,6 +380,7 @@ public class ApgService extends Service {
/* return if errors happened */
if (pReturn.getStringArrayList(ret.ERRORS.name()).size() != 0) {
+ Log.v(TAG, "Errors after preparing, not executing "+call);
pReturn.putInt(ret.ERROR.name(), error.ARGUMENTS_MISSING.shifted_ordinal());
return false;
}
@@ -460,6 +461,7 @@ public class ApgService extends Service {
ArrayList fprints = new ArrayList();
ArrayList ids = new ArrayList();
while (mCursor.moveToNext()) {
+ Log.v(TAG, "adding key "+Apg.getSmallFingerPrint(mCursor.getLong(0)));
fprints.add(Apg.getSmallFingerPrint(mCursor.getLong(0)));
ids.add(mCursor.getString(1));
}
diff --git a/src/org/thialfihar/android/apg/utils/ApgCon.java b/src/org/thialfihar/android/apg/utils/ApgCon.java
index 9a0ccb44b..0388f4d18 100644
--- a/src/org/thialfihar/android/apg/utils/ApgCon.java
+++ b/src/org/thialfihar/android/apg/utils/ApgCon.java
@@ -345,8 +345,6 @@ public class ApgCon {
Boolean success = (Boolean) IApgService.class.getMethod(function, Bundle.class, Bundle.class).invoke(apgService, pArgs, pReturn);
error_list.addAll(pReturn.getStringArrayList(ret.ERRORS.name()));
warning_list.addAll(pReturn.getStringArrayList(ret.WARNINGS.name()));
- pReturn.remove(ret.ERRORS.name());
- pReturn.remove(ret.WARNINGS.name());
return success;
} catch (NoSuchMethodException e) {
if (stacktraces)
From 66263ab6e3d9ce3a67e5f10496c0b99a0dcd1752 Mon Sep 17 00:00:00 2001
From: Markus Doits
Date: Sun, 23 Jan 2011 21:36:59 +0000
Subject: [PATCH 57/69] Allow to return itself on callback
---
.../thialfihar/android/apg/utils/ApgCon.java | 68 +++++++++++++++++--
1 file changed, 64 insertions(+), 4 deletions(-)
diff --git a/src/org/thialfihar/android/apg/utils/ApgCon.java b/src/org/thialfihar/android/apg/utils/ApgCon.java
index 0388f4d18..09e183a96 100644
--- a/src/org/thialfihar/android/apg/utils/ApgCon.java
+++ b/src/org/thialfihar/android/apg/utils/ApgCon.java
@@ -54,7 +54,11 @@ public class ApgCon {
if (callback_object != null && callback_method != null) {
try {
Log.d(TAG, "About to execute callback");
- callback_object.getClass().getMethod(callback_method).invoke(callback_object);
+ if (callback_return_self) {
+ callback_object.getClass().getMethod(callback_method, ApgCon.class).invoke(callback_object, get_self());
+ } else {
+ callback_object.getClass().getMethod(callback_method).invoke(callback_object);
+ }
Log.d(TAG, "Callback executed");
} catch (NoSuchMethodException e) {
if (stacktraces)
@@ -86,6 +90,8 @@ public class ApgCon {
private boolean async_running = false;
private Object callback_object;
private String callback_method;
+ public static final boolean default_callback_return_self = false;
+ private boolean callback_return_self = default_callback_return_self;
private final Bundle result = new Bundle();
private final Bundle args = new Bundle();
@@ -718,10 +724,38 @@ public class ApgCon {
* The object, which has the public method meth
* @param meth
* Method to call on the object obj
+ *
+ * @see #set_callback(Object, String, boolean)
*/
public void set_callback(Object obj, String meth) {
+ set_callback(obj, meth, default_callback_return_self);
+ }
+
+ /**
+ * Set a callback and whether to return self as a additional parameter
+ *
+ *
+ * This does the same as {@link #set_callback(Object, String)} with one
+ * Additionally parameter return_self.
+ *
+ *
+ * The additional parameter controls, whether to return itself as a
+ * parameter to the callback method meth (in order to go on working after
+ * async execution has finished). This means, your callback method must have
+ * one parameter of the type ApgCon.
+ *
+ *
+ * @param obj
+ * The object, which has the public method meth
+ * @param meth
+ * Method to call on the object obj
+ * @param return_self
+ * Whether to return itself as an parameter to meth
+ */
+ public void set_callback(Object obj, String meth, boolean return_self) {
set_callback_object(obj);
set_callback_method(meth);
+ set_callback_return_self(return_self);
}
/**
@@ -746,6 +780,17 @@ public class ApgCon {
callback_method = meth;
}
+ /**
+ * Set whether to return self on callback
+ *
+ * @param arg
+ * set results as param for callback method
+ * @see #set_callback(Object, String)
+ */
+ public void set_callback_return_self(boolean arg) {
+ callback_return_self = arg;
+ }
+
/**
* Clears any callback object
*
@@ -765,13 +810,24 @@ public class ApgCon {
}
/**
- * Clears any callback method and object
+ * Sets to default value of whether to return self on callback
+ *
+ * @see #set_callback(Object, String, boolean)
+ * @see #default_callback_return_self
+ */
+ public void clear_callback_return_self() {
+ callback_return_self = default_callback_return_self;
+ }
+
+ /**
+ * Clears anything related to callback
*
* @see #set_callback(Object, String)
*/
public void clear_callback() {
clear_callback_object();
clear_callback_method();
+ clear_callback_return_self();
}
/**
@@ -785,6 +841,7 @@ public class ApgCon {
* @return true, if an async task is still running, false otherwise
*
* @see #call_async(String)
+ *
*/
public boolean is_running() {
return async_running;
@@ -811,9 +868,12 @@ public class ApgCon {
clear_errors();
clear_warnings();
clear_args();
- clear_callback_object();
- clear_callback_method();
+ clear_callback();
result.clear();
}
+ public ApgCon get_self() {
+ return this;
+ }
+
}
From 3372e571577481bfa62140a131f5c0dea35936fc Mon Sep 17 00:00:00 2001
From: Markus Doits
Date: Sun, 23 Jan 2011 21:37:06 +0000
Subject: [PATCH 58/69] Allow to retrieve connection status
This tells, if a connection to APG *might* be possible (right version of
APG found)
---
.../thialfihar/android/apg/utils/ApgCon.java | 20 +++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/src/org/thialfihar/android/apg/utils/ApgCon.java b/src/org/thialfihar/android/apg/utils/ApgCon.java
index 09e183a96..5572dcdb5 100644
--- a/src/org/thialfihar/android/apg/utils/ApgCon.java
+++ b/src/org/thialfihar/android/apg/utils/ApgCon.java
@@ -29,7 +29,7 @@ import org.thialfihar.android.apg.IApgService;
*
*
* @author Markus Doits
- * @version 0.9
+ * @version 0.9.1
*
*/
public class ApgCon {
@@ -87,6 +87,7 @@ public class ApgCon {
private final static int api_version = 1; // aidl api-version it expects
private final Context mContext;
+ private final error connection_status;
private boolean async_running = false;
private Object callback_object;
private String callback_method;
@@ -121,6 +122,7 @@ public class ApgCon {
*
*/
public static enum error {
+ NO_ERROR,
/**
* generic error
*/
@@ -144,7 +146,8 @@ public class ApgCon {
/**
* found APG but without AIDL interface
*/
- APG_AIDL_MISSING
+ APG_AIDL_MISSING,
+ APG_API_MISSMATCH
}
private static enum ret {
@@ -169,12 +172,14 @@ public class ApgCon {
Log.v(TAG, "EncryptionService created");
mContext = ctx;
+ error tmp_connection_status = null;
try {
Log.v(TAG, "Searching for the right APG version");
ServiceInfo apg_services[] = ctx.getPackageManager().getPackageInfo("org.thialfihar.android.apg",
PackageManager.GET_SERVICES | PackageManager.GET_META_DATA).services;
if (apg_services == null) {
Log.e(TAG, "Could not fetch services");
+ tmp_connection_status = error.GENERIC;
} else {
boolean apg_service_found = false;
for (ServiceInfo inf : apg_services) {
@@ -185,12 +190,15 @@ public class ApgCon {
Log.w(TAG, "Could not determine ApgService API");
Log.w(TAG, "This probably won't work!");
warning_list.add("(LOCAL) Could not determine ApgService API");
+ tmp_connection_status = error.APG_API_MISSMATCH;
} else if (inf.metaData.getInt("api_version") != api_version) {
Log.w(TAG, "Found ApgService API version" + inf.metaData.getInt("api_version") + " but exspected " + api_version);
Log.w(TAG, "This probably won't work!");
warning_list.add("(LOCAL) Found ApgService API version" + inf.metaData.getInt("api_version") + " but exspected " + api_version);
+ tmp_connection_status = error.APG_API_MISSMATCH;
} else {
Log.v(TAG, "Found api_version " + api_version + ", everything should work");
+ tmp_connection_status = error.NO_ERROR;
}
}
}
@@ -199,6 +207,7 @@ public class ApgCon {
Log.e(TAG, "Could not find APG with AIDL interface, this probably won't work");
error_list.add("(LOCAL) Could not find APG with AIDL interface, this probably won't work");
result.putInt(ret.ERROR.name(), error.APG_AIDL_MISSING.ordinal());
+ tmp_connection_status = error.APG_NOT_FOUND;
}
}
} catch (PackageManager.NameNotFoundException e) {
@@ -207,7 +216,10 @@ public class ApgCon {
Log.e(TAG, "Could not find APG, is it installed?");
error_list.add("(LOCAL) Could not find APG, is it installed?");
result.putInt(ret.ERROR.name(), error.APG_NOT_FOUND.ordinal());
+ tmp_connection_status = error.APG_NOT_FOUND;
}
+
+ connection_status = tmp_connection_status;
}
/** try to connect to the apg service */
@@ -648,6 +660,10 @@ public class ApgCon {
public Bundle get_result_bundle() {
return result;
}
+
+ public error get_connection_status() {
+ return connection_status;
+ }
/**
* Clears all unfetched errors
From 1036eb6bd5f89844cf71f171d89f48c342aee217 Mon Sep 17 00:00:00 2001
From: Markus Doits
Date: Tue, 25 Jan 2011 19:38:56 +0000
Subject: [PATCH 59/69] Log stacktraces the android way
---
.../thialfihar/android/apg/utils/ApgCon.java | 37 ++++---------------
1 file changed, 8 insertions(+), 29 deletions(-)
diff --git a/src/org/thialfihar/android/apg/utils/ApgCon.java b/src/org/thialfihar/android/apg/utils/ApgCon.java
index 5572dcdb5..3e0b75524 100644
--- a/src/org/thialfihar/android/apg/utils/ApgCon.java
+++ b/src/org/thialfihar/android/apg/utils/ApgCon.java
@@ -34,11 +34,6 @@ import org.thialfihar.android.apg.IApgService;
*/
public class ApgCon {
- /**
- * Put stacktraces into the log?
- */
- private final static boolean stacktraces = true;
-
private class call_async extends AsyncTask {
@Override
@@ -61,21 +56,15 @@ public class ApgCon {
}
Log.d(TAG, "Callback executed");
} catch (NoSuchMethodException e) {
- if (stacktraces)
- e.printStackTrace();
- Log.w(TAG, "Exception in callback: Method '" + callback_method + "' not found");
+ Log.w(TAG, "Exception in callback: Method '" + callback_method + "' not found", e);
warning_list.add("(LOCAL) Could not execute callback, method '" + callback_method + "()' not found");
} catch (InvocationTargetException e) {
- if (stacktraces)
- e.printStackTrace();
Throwable orig = e.getTargetException();
- Log.w(TAG, "Exception of type '" + orig.getClass() + "' in callback's method '" + callback_method + "()':" + orig.getMessage());
+ Log.w(TAG, "Exception of type '" + orig.getClass() + "' in callback's method '" + callback_method + "()':" + orig.getMessage(), orig);
warning_list.add("(LOCAL) Exception of type '" + orig.getClass() + "' in callback's method '" + callback_method + "()':"
+ orig.getMessage());
} catch (Exception e) {
- if (stacktraces)
- e.printStackTrace();
- Log.w(TAG, "Exception on callback: (" + e.getClass() + ") " + e.getMessage());
+ Log.w(TAG, "Exception on callback: (" + e.getClass() + ") " + e.getMessage(), e);
warning_list.add("(LOCAL) Could not execute callback (" + e.getClass() + "): " + e.getMessage());
}
}
@@ -211,9 +200,7 @@ public class ApgCon {
}
}
} catch (PackageManager.NameNotFoundException e) {
- if (stacktraces)
- e.printStackTrace();
- Log.e(TAG, "Could not find APG, is it installed?");
+ Log.e(TAG, "Could not find APG, is it installed?", e);
error_list.add("(LOCAL) Could not find APG, is it installed?");
result.putInt(ret.ERROR.name(), error.APG_NOT_FOUND.ordinal());
tmp_connection_status = error.APG_NOT_FOUND;
@@ -234,9 +221,7 @@ public class ApgCon {
try {
mContext.bindService(new Intent(IApgService.class.getName()), apgConnection, Context.BIND_AUTO_CREATE);
} catch (Exception e) {
- if (stacktraces)
- e.printStackTrace();
- Log.v(TAG, "could not bind APG service");
+ Log.e(TAG, "could not bind APG service", e);
return false;
}
@@ -365,23 +350,17 @@ public class ApgCon {
warning_list.addAll(pReturn.getStringArrayList(ret.WARNINGS.name()));
return success;
} catch (NoSuchMethodException e) {
- if (stacktraces)
- e.printStackTrace();
- Log.e(TAG, "Remote call not known (" + function + "): " + e.getMessage());
+ Log.e(TAG, "Remote call not known (" + function + "): " + e.getMessage(), e);
error_list.add("(LOCAL) Remote call not known (" + function + "): " + e.getMessage());
result.putInt(ret.ERROR.name(), error.CALL_NOT_KNOWN.ordinal());
return false;
} catch (InvocationTargetException e) {
- if (stacktraces)
- e.printStackTrace();
Throwable orig = e.getTargetException();
- Log.w(TAG, "Exception of type '" + orig.getClass() + "' on AIDL call '" + function + "': " + orig.getMessage());
+ Log.w(TAG, "Exception of type '" + orig.getClass() + "' on AIDL call '" + function + "': " + orig.getMessage(), orig);
error_list.add("(LOCAL) Exception of type '" + orig.getClass() + "' on AIDL call '" + function + "': " + orig.getMessage());
return false;
} catch (Exception e) {
- if (stacktraces)
- e.printStackTrace();
- Log.e(TAG, "Generic error (" + e.getClass() + "): " + e.getMessage());
+ Log.e(TAG, "Generic error (" + e.getClass() + "): " + e.getMessage(), e);
error_list.add("(LOCAL) Generic error (" + e.getClass() + "): " + e.getMessage());
result.putInt(ret.ERROR.name(), error.GENERIC.ordinal());
return false;
From 7278932990d1014bb635905de05ade429f826849 Mon Sep 17 00:00:00 2001
From: Markus Doits
Date: Tue, 25 Jan 2011 19:39:07 +0000
Subject: [PATCH 60/69] Make callback use an interface 'the java way'_tm
---
.../thialfihar/android/apg/utils/ApgCon.java | 211 +++---------------
.../android/apg/utils/ApgConInterface.java | 9 +
2 files changed, 42 insertions(+), 178 deletions(-)
create mode 100644 src/org/thialfihar/android/apg/utils/ApgConInterface.java
diff --git a/src/org/thialfihar/android/apg/utils/ApgCon.java b/src/org/thialfihar/android/apg/utils/ApgCon.java
index 3e0b75524..8a11b8cac 100644
--- a/src/org/thialfihar/android/apg/utils/ApgCon.java
+++ b/src/org/thialfihar/android/apg/utils/ApgCon.java
@@ -15,6 +15,7 @@ import android.os.IBinder;
import android.util.Log;
import org.thialfihar.android.apg.IApgService;
+import org.thialfihar.android.apg.utils.ApgConInterface.OnCallFinishListener;
/**
* A APG-AIDL-Wrapper
@@ -29,7 +30,7 @@ import org.thialfihar.android.apg.IApgService;
*
*
* @author Markus Doits
- * @version 0.9.1
+ * @version 0.9.9
*
*/
public class ApgCon {
@@ -43,31 +44,10 @@ public class ApgCon {
return null;
}
- protected void onPostExecute(Void result) {
+ protected void onPostExecute(Void res) {
Log.d(TAG, "Async execution finished");
async_running = false;
- if (callback_object != null && callback_method != null) {
- try {
- Log.d(TAG, "About to execute callback");
- if (callback_return_self) {
- callback_object.getClass().getMethod(callback_method, ApgCon.class).invoke(callback_object, get_self());
- } else {
- callback_object.getClass().getMethod(callback_method).invoke(callback_object);
- }
- Log.d(TAG, "Callback executed");
- } catch (NoSuchMethodException e) {
- Log.w(TAG, "Exception in callback: Method '" + callback_method + "' not found", e);
- warning_list.add("(LOCAL) Could not execute callback, method '" + callback_method + "()' not found");
- } catch (InvocationTargetException e) {
- Throwable orig = e.getTargetException();
- Log.w(TAG, "Exception of type '" + orig.getClass() + "' in callback's method '" + callback_method + "()':" + orig.getMessage(), orig);
- warning_list.add("(LOCAL) Exception of type '" + orig.getClass() + "' in callback's method '" + callback_method + "()':"
- + orig.getMessage());
- } catch (Exception e) {
- Log.w(TAG, "Exception on callback: (" + e.getClass() + ") " + e.getMessage(), e);
- warning_list.add("(LOCAL) Could not execute callback (" + e.getClass() + "): " + e.getMessage());
- }
- }
+
}
}
@@ -78,10 +58,7 @@ public class ApgCon {
private final Context mContext;
private final error connection_status;
private boolean async_running = false;
- private Object callback_object;
- private String callback_method;
- public static final boolean default_callback_return_self = false;
- private boolean callback_return_self = default_callback_return_self;
+ private OnCallFinishListener onCallFinishListener;
private final Bundle result = new Bundle();
private final Bundle args = new Bundle();
@@ -205,7 +182,7 @@ public class ApgCon {
result.putInt(ret.ERROR.name(), error.APG_NOT_FOUND.ordinal());
tmp_connection_status = error.APG_NOT_FOUND;
}
-
+
connection_status = tmp_connection_status;
}
@@ -282,6 +259,7 @@ public class ApgCon {
* start connection to the remote interface (if not already connected)
* call the passed function with all set up parameters synchronously
* set up everything to retrieve the result and/or warnings/errors
+ * call the callback if provided
*
*
*
@@ -296,9 +274,21 @@ public class ApgCon {
*
* @see #call_async(String)
* @see #set_arg(String, String)
+ * @see #set_onCallFinishListener(OnCallFinishListener)
*/
public boolean call(String function) {
- return this.call(function, args, result);
+ boolean success = this.call(function, args, result);
+ if (onCallFinishListener != null) {
+ try {
+ Log.d(TAG, "About to execute callback");
+ onCallFinishListener.onCallFinish(result);
+ Log.d(TAG, "Callback executed");
+ } catch (Exception e) {
+ Log.w(TAG, "Exception on callback: (" + e.getClass() + ") " + e.getMessage(), e);
+ warning_list.add("(LOCAL) Could not execute callback (" + e.getClass() + "): " + e.getMessage());
+ }
+ }
+ return success;
}
/**
@@ -314,7 +304,7 @@ public class ApgCon {
* To see whether the task is finished, you have to possibilities:
*
* - In your thread, poll {@link #is_running()}
- * - Supply a callback with {@link #set_callback(Object, String)}
+ * - Supply a callback with {@link #set_onCallFinishListener(OnCallFinishListener)}
*
*
*
@@ -323,7 +313,7 @@ public class ApgCon {
*
* @see #call(String)
* @see #is_running()
- * @see #set_callback(Object, String)
+ * @see #set_onCallFinishListener(OnCallFinishListener)
*/
public void call_async(String function) {
async_running = true;
@@ -484,7 +474,7 @@ public class ApgCon {
* {@link #set_arg(String, String)} functions, is cleared.
*
*
- * Note, that any warning, error, callback, result etc. is not cleared with
+ * Note, that any warning, error, callback, result, etc. is not cleared with
* this.
*
*
@@ -639,7 +629,7 @@ public class ApgCon {
public Bundle get_result_bundle() {
return result;
}
-
+
public error get_connection_status() {
return connection_status;
}
@@ -675,154 +665,23 @@ public class ApgCon {
}
/**
- * Set a callback object and method
- *
- *
- * After an async execution is finished, obj.meth() will be called. You can
- * use this in order to get notified, when encrypting/decrypting of long
- * data finishes and do not have to poll {@link #is_running()} in your
- * thread. Note, that if the call of the method fails for whatever reason,
- * you won't get notified in any way - so you still should check
- * {@link #is_running()} from time to time.
- *
- *
- *
- * It produces a warning fetchable with {@link #get_next_warning()} when the
- * callback fails.
- *
- *
- *
- *
- * .... your class ...
- * public void callback() {
- * // do something after encryption finished
- * }
- *
- * public void encrypt() {
- * ApgCon mEnc = new ApgCon(context);
- * // set parameters
- * mEnc.set_arg(key, value);
- * ...
- *
- * // set callback object and method
- * mEnc.set_callback( this, "callback" );
- *
- * // start asynchronous call
- * mEnc.call_async( call );
- *
- * // when the call_async finishes, the method "callback()" will be called automatically
- * }
- *
- *
- *
- * @param obj
- * The object, which has the public method meth
- * @param meth
- * Method to call on the object obj
- *
- * @see #set_callback(Object, String, boolean)
- */
- public void set_callback(Object obj, String meth) {
- set_callback(obj, meth, default_callback_return_self);
- }
-
- /**
- * Set a callback and whether to return self as a additional parameter
- *
- *
- * This does the same as {@link #set_callback(Object, String)} with one
- * Additionally parameter return_self.
- *
- *
- * The additional parameter controls, whether to return itself as a
- * parameter to the callback method meth (in order to go on working after
- * async execution has finished). This means, your callback method must have
- * one parameter of the type ApgCon.
- *
- *
- * @param obj
- * The object, which has the public method meth
- * @param meth
- * Method to call on the object obj
- * @param return_self
- * Whether to return itself as an parameter to meth
- */
- public void set_callback(Object obj, String meth, boolean return_self) {
- set_callback_object(obj);
- set_callback_method(meth);
- set_callback_return_self(return_self);
- }
-
- /**
- * Set a callback object
+ * Set a callback listener when call to AIDL finishes
*
* @param obj
* a object to call back after async execution
- * @see #set_callback(Object, String)
+ * @see ApgConInterface
*/
- public void set_callback_object(Object obj) {
- callback_object = obj;
- }
-
- /**
- * Set a callback method
- *
- * @param meth
- * a method to call on a callback object after async execution
- * @see #set_callback(Object, String)
- */
- public void set_callback_method(String meth) {
- callback_method = meth;
- }
-
- /**
- * Set whether to return self on callback
- *
- * @param arg
- * set results as param for callback method
- * @see #set_callback(Object, String)
- */
- public void set_callback_return_self(boolean arg) {
- callback_return_self = arg;
+ public void set_onCallFinishListener(OnCallFinishListener lis) {
+ onCallFinishListener = lis;
}
/**
* Clears any callback object
*
- * @see #set_callback(Object, String)
+ * @see #set_onCallFinishListener(OnCallFinishListener)
*/
- public void clear_callback_object() {
- callback_object = null;
- }
-
- /**
- * Clears any callback method
- *
- * @see #set_callback(Object, String)
- */
- public void clear_callback_method() {
- callback_method = null;
- }
-
- /**
- * Sets to default value of whether to return self on callback
- *
- * @see #set_callback(Object, String, boolean)
- * @see #default_callback_return_self
- */
- public void clear_callback_return_self() {
- callback_return_self = default_callback_return_self;
- }
-
- /**
- * Clears anything related to callback
- *
- * @see #set_callback(Object, String)
- */
- public void clear_callback() {
- clear_callback_object();
- clear_callback_method();
- clear_callback_return_self();
+ public void clear_onCallFinishListener() {
+ onCallFinishListener = null;
}
/**
@@ -855,7 +714,7 @@ public class ApgCon {
* Note, that when an async execution ({@link #call_async(String)}) is
* running, it's result, warnings etc. will still be evaluated (which might
* be not what you want). Also mind, that any callback you set is also
- * reseted, so on finishing the async execution any defined callback will
+ * reseted, so on finishing the execution any before defined callback will
* NOT BE TRIGGERED.
*
*/
@@ -863,12 +722,8 @@ public class ApgCon {
clear_errors();
clear_warnings();
clear_args();
- clear_callback();
+ clear_onCallFinishListener();
result.clear();
}
- public ApgCon get_self() {
- return this;
- }
-
}
diff --git a/src/org/thialfihar/android/apg/utils/ApgConInterface.java b/src/org/thialfihar/android/apg/utils/ApgConInterface.java
new file mode 100644
index 000000000..57ef0d9c4
--- /dev/null
+++ b/src/org/thialfihar/android/apg/utils/ApgConInterface.java
@@ -0,0 +1,9 @@
+package org.thialfihar.android.apg.utils;
+
+import android.os.Bundle;
+
+public interface ApgConInterface {
+ public static interface OnCallFinishListener {
+ public abstract void onCallFinish(Bundle result);
+ }
+}
From c497e48817141589624b933cffb6e9e714942818 Mon Sep 17 00:00:00 2001
From: Markus Doits
Date: Tue, 25 Jan 2011 19:51:35 +0000
Subject: [PATCH 61/69] Define interface without imports
---
src/org/thialfihar/android/apg/utils/ApgConInterface.java | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/src/org/thialfihar/android/apg/utils/ApgConInterface.java b/src/org/thialfihar/android/apg/utils/ApgConInterface.java
index 57ef0d9c4..27254fe95 100644
--- a/src/org/thialfihar/android/apg/utils/ApgConInterface.java
+++ b/src/org/thialfihar/android/apg/utils/ApgConInterface.java
@@ -1,9 +1,7 @@
package org.thialfihar.android.apg.utils;
-import android.os.Bundle;
-
public interface ApgConInterface {
public static interface OnCallFinishListener {
- public abstract void onCallFinish(Bundle result);
+ public abstract void onCallFinish(android.os.Bundle result);
}
}
From 3be076d0245ceddb483e9972ea0662a8de665e52 Mon Sep 17 00:00:00 2001
From: Markus Doits
Date: Wed, 18 May 2011 18:19:47 +0000
Subject: [PATCH 62/69] Little better log-managing for release-versions of
ApgCon
---
.../thialfihar/android/apg/utils/ApgCon.java | 50 +++++++++++++------
1 file changed, 34 insertions(+), 16 deletions(-)
diff --git a/src/org/thialfihar/android/apg/utils/ApgCon.java b/src/org/thialfihar/android/apg/utils/ApgCon.java
index 8a11b8cac..7ab2ea842 100644
--- a/src/org/thialfihar/android/apg/utils/ApgCon.java
+++ b/src/org/thialfihar/android/apg/utils/ApgCon.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2011 Markus Doits
+ *
+ * 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.utils;
import java.lang.reflect.InvocationTargetException;
@@ -34,18 +50,20 @@ import org.thialfihar.android.apg.utils.ApgConInterface.OnCallFinishListener;
*
*/
public class ApgCon {
+ private static final boolean LOCAL_LOGV = true;
+ private static final boolean LOCAL_LOGD = true;
private class call_async extends AsyncTask {
@Override
protected Void doInBackground(String... arg) {
- Log.d(TAG, "Async execution starting");
+ if( LOCAL_LOGD ) Log.d(TAG, "Async execution starting");
call(arg[0]);
return null;
}
protected void onPostExecute(Void res) {
- Log.d(TAG, "Async execution finished");
+ if( LOCAL_LOGD ) Log.d(TAG, "Async execution finished");
async_running = false;
}
@@ -71,12 +89,12 @@ public class ApgCon {
/** Set apgService accordingly to connection status */
private ServiceConnection apgConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
- Log.d(TAG, "IApgService bound to apgService");
+ if( LOCAL_LOGD ) Log.d(TAG, "IApgService bound to apgService");
apgService = IApgService.Stub.asInterface(service);
}
public void onServiceDisconnected(ComponentName className) {
- Log.d(TAG, "IApgService disconnected");
+ if( LOCAL_LOGD ) Log.d(TAG, "IApgService disconnected");
apgService = null;
}
};
@@ -135,12 +153,12 @@ public class ApgCon {
* the running context
*/
public ApgCon(Context ctx) {
- Log.v(TAG, "EncryptionService created");
+ if( LOCAL_LOGV ) Log.v(TAG, "EncryptionService created");
mContext = ctx;
error tmp_connection_status = null;
try {
- Log.v(TAG, "Searching for the right APG version");
+ if( LOCAL_LOGV ) Log.v(TAG, "Searching for the right APG version");
ServiceInfo apg_services[] = ctx.getPackageManager().getPackageInfo("org.thialfihar.android.apg",
PackageManager.GET_SERVICES | PackageManager.GET_META_DATA).services;
if (apg_services == null) {
@@ -149,7 +167,7 @@ public class ApgCon {
} else {
boolean apg_service_found = false;
for (ServiceInfo inf : apg_services) {
- Log.v(TAG, "Found service of APG: " + inf.name);
+ if( LOCAL_LOGV ) Log.v(TAG, "Found service of APG: " + inf.name);
if (inf.name.equals("org.thialfihar.android.apg.ApgService")) {
apg_service_found = true;
if (inf.metaData == null) {
@@ -163,7 +181,7 @@ public class ApgCon {
warning_list.add("(LOCAL) Found ApgService API version" + inf.metaData.getInt("api_version") + " but exspected " + api_version);
tmp_connection_status = error.APG_API_MISSMATCH;
} else {
- Log.v(TAG, "Found api_version " + api_version + ", everything should work");
+ if( LOCAL_LOGV ) Log.v(TAG, "Found api_version " + api_version + ", everything should work");
tmp_connection_status = error.NO_ERROR;
}
}
@@ -188,10 +206,10 @@ public class ApgCon {
/** try to connect to the apg service */
private boolean connect() {
- Log.v(TAG, "trying to bind the apgService to context");
+ if( LOCAL_LOGV ) Log.v(TAG, "trying to bind the apgService to context");
if (apgService != null) {
- Log.v(TAG, "allready connected");
+ if( LOCAL_LOGV ) Log.v(TAG, "allready connected");
return true;
}
@@ -204,12 +222,12 @@ public class ApgCon {
int wait_count = 0;
while (apgService == null && wait_count++ < 15) {
- Log.v(TAG, "sleeping 1 second to wait for apg");
+ if( LOCAL_LOGV ) Log.v(TAG, "sleeping 1 second to wait for apg");
android.os.SystemClock.sleep(1000);
}
if (wait_count >= 15) {
- Log.v(TAG, "slept waiting for nothing!");
+ if( LOCAL_LOGV ) Log.v(TAG, "slept waiting for nothing!");
return false;
}
@@ -231,7 +249,7 @@ public class ApgCon {
*
*/
public void disconnect() {
- Log.v(TAG, "disconnecting apgService");
+ if( LOCAL_LOGV ) Log.v(TAG, "disconnecting apgService");
if (apgService != null) {
mContext.unbindService(apgConnection);
apgService = null;
@@ -241,7 +259,7 @@ public class ApgCon {
private boolean initialize() {
if (apgService == null) {
if (!connect()) {
- Log.v(TAG, "connection to apg service failed");
+ if( LOCAL_LOGV ) Log.v(TAG, "connection to apg service failed");
return false;
}
}
@@ -280,9 +298,9 @@ public class ApgCon {
boolean success = this.call(function, args, result);
if (onCallFinishListener != null) {
try {
- Log.d(TAG, "About to execute callback");
+ if( LOCAL_LOGD ) Log.d(TAG, "About to execute callback");
onCallFinishListener.onCallFinish(result);
- Log.d(TAG, "Callback executed");
+ if( LOCAL_LOGD ) Log.d(TAG, "Callback executed");
} catch (Exception e) {
Log.w(TAG, "Exception on callback: (" + e.getClass() + ") " + e.getMessage(), e);
warning_list.add("(LOCAL) Could not execute callback (" + e.getClass() + "): " + e.getMessage());
From 6502e58c26cddc8472b6b46932250eb1fca88156 Mon Sep 17 00:00:00 2001
From: Markus Doits
Date: Sun, 5 Jun 2011 19:05:18 +0000
Subject: [PATCH 63/69] Possibility to not compile Log.d and Log.v in
---
.../thialfihar/android/apg/ApgService.java | 34 ++++++++++---------
1 file changed, 18 insertions(+), 16 deletions(-)
diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java
index 87437e629..34248c809 100644
--- a/src/org/thialfihar/android/apg/ApgService.java
+++ b/src/org/thialfihar/android/apg/ApgService.java
@@ -23,10 +23,12 @@ import android.util.Log;
public class ApgService extends Service {
private final static String TAG = "ApgService";
+ private static final boolean LOCAL_LOGV = true;
+ private static final boolean LOCAL_LOGD = true;
@Override
public IBinder onBind(Intent intent) {
- Log.d(TAG, "bound");
+ if( LOCAL_LOGD ) Log.d(TAG, "bound");
return mBinder;
}
@@ -209,20 +211,20 @@ public class ApgService extends Service {
Cursor mCursor = get_key_entries(qParams);
- Log.v(TAG, "going through installed user keys");
+ if( LOCAL_LOGV ) Log.v(TAG, "going through installed user keys");
ArrayList _master_keys = new ArrayList();
while (mCursor.moveToNext()) {
long _cur_mkey = mCursor.getLong(0);
String _cur_user = mCursor.getString(1);
String _cur_fprint = Apg.getSmallFingerPrint(_cur_mkey);
- Log.v(TAG, "current user: " + _cur_user + " (" + _cur_fprint + ")");
+ if( LOCAL_LOGV ) Log.v(TAG, "current user: " + _cur_user + " (" + _cur_fprint + ")");
if (search_keys.contains(_cur_fprint) || search_keys.contains(_cur_user)) {
- Log.v(TAG, "master key found for: " + _cur_fprint);
+ if( LOCAL_LOGV ) Log.v(TAG, "master key found for: " + _cur_fprint);
_master_keys.add(_cur_mkey);
search_keys.remove(_cur_fprint);
} else {
- Log.v(TAG, "Installed key " + _cur_fprint + " is not in the list of public keys to encrypt with");
+ if( LOCAL_LOGV ) Log.v(TAG, "Installed key " + _cur_fprint + " is not in the list of public keys to encrypt with");
}
}
mCursor.close();
@@ -368,23 +370,23 @@ public class ApgService extends Service {
/* add default arguments if missing */
add_default_arguments(call, pArgs);
- Log.v(TAG, "add_default_arguments");
+ if( LOCAL_LOGV ) Log.v(TAG, "add_default_arguments");
/* check for required arguments */
check_required_args(call, pArgs, pReturn);
- Log.v(TAG, "check_required_args");
+ if( LOCAL_LOGV ) Log.v(TAG, "check_required_args");
/* check for unknown arguments and add to warning if found */
check_unknown_args(call, pArgs, pReturn);
- Log.v(TAG, "check_unknown_args");
+ if( LOCAL_LOGV ) Log.v(TAG, "check_unknown_args");
/* return if errors happened */
if (pReturn.getStringArrayList(ret.ERRORS.name()).size() != 0) {
- Log.v(TAG, "Errors after preparing, not executing "+call);
+ if( LOCAL_LOGV ) Log.v(TAG, "Errors after preparing, not executing "+call);
pReturn.putInt(ret.ERROR.name(), error.ARGUMENTS_MISSING.shifted_ordinal());
return false;
}
- Log.v(TAG, "error return");
+ if( LOCAL_LOGV ) Log.v(TAG, "error return");
return true;
}
@@ -395,7 +397,7 @@ public class ApgService extends Service {
if (pArgs.containsKey(arg.PUBLIC_KEYS.name())) {
ArrayList _list = pArgs.getStringArrayList(arg.PUBLIC_KEYS.name());
ArrayList _pub_keys = new ArrayList();
- Log.v(TAG, "Long size: " + _list.size());
+ if( LOCAL_LOGV ) Log.v(TAG, "Long size: " + _list.size());
Iterator _iter = _list.iterator();
while (_iter.hasNext()) {
_pub_keys.add(_iter.next());
@@ -407,7 +409,7 @@ public class ApgService extends Service {
InputData _in = new InputData(_inStream, 0); // XXX Size second param?
OutputStream _out = new ByteArrayOutputStream();
- Log.v(TAG, "About to encrypt");
+ if( LOCAL_LOGV ) Log.v(TAG, "About to encrypt");
try {
Apg.encrypt(getBaseContext(), // context
_in, // input stream
@@ -438,7 +440,7 @@ public class ApgService extends Service {
}
return false;
}
- Log.v(TAG, "Encrypted");
+ if( LOCAL_LOGV ) Log.v(TAG, "Encrypted");
pReturn.putString(ret.RESULT.name(), _out.toString());
return true;
}
@@ -461,7 +463,7 @@ public class ApgService extends Service {
ArrayList fprints = new ArrayList();
ArrayList ids = new ArrayList();
while (mCursor.moveToNext()) {
- Log.v(TAG, "adding key "+Apg.getSmallFingerPrint(mCursor.getLong(0)));
+ if( LOCAL_LOGV ) Log.v(TAG, "adding key "+Apg.getSmallFingerPrint(mCursor.getLong(0)));
fprints.add(Apg.getSmallFingerPrint(mCursor.getLong(0)));
ids.add(mCursor.getString(1));
}
@@ -500,7 +502,7 @@ public class ApgService extends Service {
InputStream inStream = new ByteArrayInputStream(pArgs.getString(arg.MESSAGE.name()).getBytes());
InputData in = new InputData(inStream, 0); // XXX what size in second parameter?
OutputStream out = new ByteArrayOutputStream();
- Log.v(TAG, "About to decrypt");
+ if( LOCAL_LOGV ) Log.v(TAG, "About to decrypt");
try {
Apg.decrypt(getBaseContext(), in, out, _passphrase, null, // progress
pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) != null // symmetric
@@ -520,7 +522,7 @@ public class ApgService extends Service {
}
return false;
}
- Log.v(TAG, "Decrypted");
+ if( LOCAL_LOGV ) Log.v(TAG, "Decrypted");
pReturn.putString(ret.RESULT.name(), out.toString());
return true;
From 24205b8dbc6487ee066fec07c9c0840a3be30bb7 Mon Sep 17 00:00:00 2001
From: Markus Doits
Date: Sun, 5 Jun 2011 19:05:57 +0000
Subject: [PATCH 64/69] Cleanup of code, AIDL-calls renamed!
---
.../thialfihar/android/apg/ApgService.java | 316 ++++++++--------
.../thialfihar/android/apg/IApgService.aidl | 48 +--
.../thialfihar/android/apg/utils/ApgCon.java | 353 +++++++++---------
3 files changed, 355 insertions(+), 362 deletions(-)
diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/thialfihar/android/apg/ApgService.java
index 34248c809..0a25c6055 100644
--- a/src/org/thialfihar/android/apg/ApgService.java
+++ b/src/org/thialfihar/android/apg/ApgService.java
@@ -40,7 +40,7 @@ public class ApgService extends Service {
PRIVATE_KEY_PASSPHRASE_WRONG,
PRIVATE_KEY_PASSPHRASE_MISSING;
- public int shifted_ordinal() {
+ public int shiftedOrdinal() {
return ordinal() + 100;
}
}
@@ -90,7 +90,6 @@ public class ApgService extends Service {
args = new HashSet();
args.add(arg.KEY_TYPE);
FUNCTIONS_REQUIRED_ARGS.put("get_keys", args);
-
}
/** optional arguments for each AIDL function */
@@ -124,21 +123,7 @@ public class ApgService extends Service {
FUNCTIONS_DEFAULTS.put(arg.COMPRESSION, "getDefaultMessageCompression");
}
- /** a map the default functions to their return types */
- private static final HashMap> FUNCTIONS_DEFAULTS_TYPES = new HashMap>();
- static {
- try {
- FUNCTIONS_DEFAULTS_TYPES.put("getDefaultEncryptionAlgorithm", Preferences.class.getMethod("getDefaultEncryptionAlgorithm").getReturnType());
- FUNCTIONS_DEFAULTS_TYPES.put("getDefaultHashAlgorithm", Preferences.class.getMethod("getDefaultHashAlgorithm").getReturnType());
- FUNCTIONS_DEFAULTS_TYPES.put("getDefaultAsciiArmour", Preferences.class.getMethod("getDefaultAsciiArmour").getReturnType());
- FUNCTIONS_DEFAULTS_TYPES.put("getForceV3Signatures", Preferences.class.getMethod("getForceV3Signatures").getReturnType());
- FUNCTIONS_DEFAULTS_TYPES.put("getDefaultMessageCompression", Preferences.class.getMethod("getDefaultMessageCompression").getReturnType());
- } catch (Exception e) {
- Log.e(TAG, "Function default exception: " + e.getMessage());
- }
- }
-
- /** a map the default function names to their method */
+ /** a map of the default function names to their method */
private static final HashMap FUNCTIONS_DEFAULTS_METHODS = new HashMap();
static {
try {
@@ -152,46 +137,47 @@ public class ApgService extends Service {
}
}
- /**
- * maps a fingerprint or user id of a key to as master key in database
- *
- * @param search_key
- * fingerprint or user id to search for
- * @return master key if found, or 0
- */
- private static long get_master_key(String search_key, Bundle pReturn) {
- if (search_key == null || search_key.length() != 8) {
- return 0;
- }
- ArrayList tmp = new ArrayList();
- tmp.add(search_key);
- long[] _keys = get_master_key(tmp, pReturn);
- if (_keys.length > 0)
- return _keys[0];
- else
- return 0;
- }
-
- private static Cursor get_key_entries(HashMap params) {
+ private static Cursor getKeyEntries(HashMap pParams) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(KeyRings.TABLE_NAME + " INNER JOIN " + Keys.TABLE_NAME + " ON " + "(" + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + Keys.TABLE_NAME
+ "." + Keys.KEY_RING_ID + " AND " + Keys.TABLE_NAME + "." + Keys.IS_MASTER_KEY + " = '1'" + ") " + " INNER JOIN " + UserIds.TABLE_NAME
+ " ON " + "(" + Keys.TABLE_NAME + "." + Keys._ID + " = " + UserIds.TABLE_NAME + "." + UserIds.KEY_ID + " AND " + UserIds.TABLE_NAME + "."
+ UserIds.RANK + " = '0') ");
- String orderBy = params.containsKey("order_by") ? (String) params.get("order_by") : UserIds.TABLE_NAME + "." + UserIds.USER_ID + " ASC";
+ String orderBy = pParams.containsKey("order_by") ? (String) pParams.get("order_by") : UserIds.TABLE_NAME + "." + UserIds.USER_ID + " ASC";
- String type_val[] = null;
- String type_where = null;
- if (params.containsKey("key_type")) {
- type_where = KeyRings.TABLE_NAME + "." + KeyRings.TYPE + " = ?";
- type_val = new String[] {
- "" + params.get("key_type")
+ String typeVal[] = null;
+ String typeWhere = null;
+ if (pParams.containsKey("key_type")) {
+ typeWhere = KeyRings.TABLE_NAME + "." + KeyRings.TYPE + " = ?";
+ typeVal = new String[] {
+ "" + pParams.get("key_type")
};
}
- return qb.query(Apg.getDatabase().db(), (String[]) params.get("columns"), type_where, type_val, null, null, orderBy);
+ return qb.query(Apg.getDatabase().db(), (String[]) pParams.get("columns"), typeWhere, typeVal, null, null, orderBy);
}
+ /**
+ * maps a fingerprint or user id of a key to a master key in database
+ *
+ * @param search_key
+ * fingerprint or user id to search for
+ * @return master key if found, or 0
+ */
+ private static long getMasterKey(String pSearchKey, Bundle pReturn) {
+ if (pSearchKey == null || pSearchKey.length() != 8) {
+ return 0;
+ }
+ ArrayList keyList = new ArrayList();
+ keyList.add(pSearchKey);
+ long[] keys = getMasterKey(keyList, pReturn);
+ if (keys.length > 0) {
+ return keys[0];
+ } else {
+ return 0;
+ }
+ }
+
/**
* maps fingerprints or user ids of keys to master keys in database
*
@@ -200,7 +186,7 @@ public class ApgService extends Service {
* database
* @return an array of master keys
*/
- private static long[] get_master_key(ArrayList search_keys, Bundle pReturn) {
+ private static long[] getMasterKey(ArrayList pSearchKeys, Bundle pReturn) {
HashMap qParams = new HashMap();
qParams.put("columns", new String[] {
@@ -209,30 +195,30 @@ public class ApgService extends Service {
});
qParams.put("key_type", Id.database.type_public);
- Cursor mCursor = get_key_entries(qParams);
+ Cursor mCursor = getKeyEntries(qParams);
if( LOCAL_LOGV ) Log.v(TAG, "going through installed user keys");
- ArrayList _master_keys = new ArrayList();
+ ArrayList masterKeys = new ArrayList();
while (mCursor.moveToNext()) {
- long _cur_mkey = mCursor.getLong(0);
- String _cur_user = mCursor.getString(1);
+ long curMkey = mCursor.getLong(0);
+ String curUser = mCursor.getString(1);
- String _cur_fprint = Apg.getSmallFingerPrint(_cur_mkey);
- if( LOCAL_LOGV ) Log.v(TAG, "current user: " + _cur_user + " (" + _cur_fprint + ")");
- if (search_keys.contains(_cur_fprint) || search_keys.contains(_cur_user)) {
- if( LOCAL_LOGV ) Log.v(TAG, "master key found for: " + _cur_fprint);
- _master_keys.add(_cur_mkey);
- search_keys.remove(_cur_fprint);
+ String curFprint = Apg.getSmallFingerPrint(curMkey);
+ if( LOCAL_LOGV ) Log.v(TAG, "current user: " + curUser + " (" + curFprint + ")");
+ if (pSearchKeys.contains(curFprint) || pSearchKeys.contains(curUser)) {
+ if( LOCAL_LOGV ) Log.v(TAG, "master key found for: " + curFprint);
+ masterKeys.add(curMkey);
+ pSearchKeys.remove(curFprint);
} else {
- if( LOCAL_LOGV ) Log.v(TAG, "Installed key " + _cur_fprint + " is not in the list of public keys to encrypt with");
+ if( LOCAL_LOGV ) Log.v(TAG, "Installed key " + curFprint + " is not in the list of public keys to encrypt with");
}
}
mCursor.close();
- long[] _master_longs = new long[_master_keys.size()];
+ long[] masterKeyLongs = new long[masterKeys.size()];
int i = 0;
- for (Long _key : _master_keys) {
- _master_longs[i++] = _key;
+ for (Long key : masterKeys) {
+ masterKeyLongs[i++] = key;
}
if (i == 0) {
@@ -240,12 +226,12 @@ public class ApgService extends Service {
pReturn.getStringArrayList(ret.WARNINGS.name()).add("Searched for public key(s) but found not one");
}
- for (String _key : search_keys) {
- Log.w(TAG, "Searched for key " + _key + " but cannot find it in APG");
- pReturn.getStringArrayList(ret.WARNINGS.name()).add("Searched for key " + _key + " but cannot find it in APG");
+ for (String key : pSearchKeys) {
+ Log.w(TAG, "Searched for key " + key + " but cannot find it in APG");
+ pReturn.getStringArrayList(ret.WARNINGS.name()).add("Searched for key " + key + " but cannot find it in APG");
}
- return _master_longs;
+ return masterKeyLongs;
}
/**
@@ -254,27 +240,27 @@ public class ApgService extends Service {
* @param args
* the bundle to add default parameters to if missing
*/
- private void add_default_arguments(String call, Bundle args) {
+ private void addDefaultArguments(String pCall, Bundle pArgs) {
// check whether there are optional elements defined for that call
- if (FUNCTIONS_OPTIONAL_ARGS.containsKey(call)) {
- Preferences _mPreferences = Preferences.getPreferences(getBaseContext(), true);
+ if (FUNCTIONS_OPTIONAL_ARGS.containsKey(pCall)) {
+ Preferences preferences = Preferences.getPreferences(getBaseContext(), true);
- Iterator _iter = FUNCTIONS_DEFAULTS.keySet().iterator();
- while (_iter.hasNext()) {
- arg _current_arg = _iter.next();
- String _current_key = _current_arg.name();
- if (!args.containsKey(_current_key) && FUNCTIONS_OPTIONAL_ARGS.get(call).contains(_current_arg)) {
- String _current_function_name = FUNCTIONS_DEFAULTS.get(_current_arg);
+ Iterator iter = FUNCTIONS_DEFAULTS.keySet().iterator();
+ while (iter.hasNext()) {
+ arg currentArg = iter.next();
+ String currentKey = currentArg.name();
+ if (!pArgs.containsKey(currentKey) && FUNCTIONS_OPTIONAL_ARGS.get(pCall).contains(currentArg)) {
+ String currentFunctionName = FUNCTIONS_DEFAULTS.get(currentArg);
try {
- Class> _ret_type = FUNCTIONS_DEFAULTS_TYPES.get(_current_function_name);
- if (_ret_type == String.class) {
- args.putString(_current_key, (String) FUNCTIONS_DEFAULTS_METHODS.get(_current_function_name).invoke(_mPreferences));
- } else if (_ret_type == boolean.class) {
- args.putBoolean(_current_key, (Boolean) FUNCTIONS_DEFAULTS_METHODS.get(_current_function_name).invoke(_mPreferences));
- } else if (_ret_type == int.class) {
- args.putInt(_current_key, (Integer) FUNCTIONS_DEFAULTS_METHODS.get(_current_function_name).invoke(_mPreferences));
+ Class> returnType = FUNCTIONS_DEFAULTS_METHODS.get(currentFunctionName).getReturnType();
+ if (returnType == String.class) {
+ pArgs.putString(currentKey, (String) FUNCTIONS_DEFAULTS_METHODS.get(currentFunctionName).invoke(preferences));
+ } else if (returnType == boolean.class) {
+ pArgs.putBoolean(currentKey, (Boolean) FUNCTIONS_DEFAULTS_METHODS.get(currentFunctionName).invoke(preferences));
+ } else if (returnType == int.class) {
+ pArgs.putInt(currentKey, (Integer) FUNCTIONS_DEFAULTS_METHODS.get(currentFunctionName).invoke(preferences));
} else {
- Log.e(TAG, "Unknown return type " + _ret_type.toString() + " for default option");
+ Log.e(TAG, "Unknown return type " + returnType.toString() + " for default option");
}
} catch (Exception e) {
Log.e(TAG, "Exception in add_default_arguments " + e.getMessage());
@@ -290,7 +276,7 @@ public class ApgService extends Service {
* @param pReturn
* the Bundle to update
*/
- private void add_default_returns(Bundle pReturn) {
+ private void addDefaultReturns(Bundle pReturn) {
ArrayList errors = new ArrayList();
ArrayList warnings = new ArrayList();
@@ -308,13 +294,13 @@ public class ApgService extends Service {
* @param pReturn
* the bundle to write errors to
*/
- private void check_required_args(String function, Bundle pArgs, Bundle pReturn) {
- if (FUNCTIONS_REQUIRED_ARGS.containsKey(function)) {
- Iterator _iter = FUNCTIONS_REQUIRED_ARGS.get(function).iterator();
- while (_iter.hasNext()) {
- String _cur_arg = _iter.next().name();
- if (!pArgs.containsKey(_cur_arg)) {
- pReturn.getStringArrayList(ret.ERRORS.name()).add("Argument missing: " + _cur_arg);
+ private void checkForRequiredArgs(String pFunction, Bundle pArgs, Bundle pReturn) {
+ if (FUNCTIONS_REQUIRED_ARGS.containsKey(pFunction)) {
+ Iterator iter = FUNCTIONS_REQUIRED_ARGS.get(pFunction).iterator();
+ while (iter.hasNext()) {
+ String curArg = iter.next().name();
+ if (!pArgs.containsKey(curArg)) {
+ pReturn.getStringArrayList(ret.ERRORS.name()).add("Argument missing: " + curArg);
}
}
}
@@ -330,60 +316,60 @@ public class ApgService extends Service {
* @param pReturn
* the bundle to write warnings to
*/
- private void check_unknown_args(String function, Bundle pArgs, Bundle pReturn) {
+ private void checkForUnknownArgs(String pFunction, Bundle pArgs, Bundle pReturn) {
- HashSet all_args = new HashSet();
- if (FUNCTIONS_REQUIRED_ARGS.containsKey(function)) {
- all_args.addAll(FUNCTIONS_REQUIRED_ARGS.get(function));
+ HashSet allArgs = new HashSet();
+ if (FUNCTIONS_REQUIRED_ARGS.containsKey(pFunction)) {
+ allArgs.addAll(FUNCTIONS_REQUIRED_ARGS.get(pFunction));
}
- if (FUNCTIONS_OPTIONAL_ARGS.containsKey(function)) {
- all_args.addAll(FUNCTIONS_OPTIONAL_ARGS.get(function));
+ if (FUNCTIONS_OPTIONAL_ARGS.containsKey(pFunction)) {
+ allArgs.addAll(FUNCTIONS_OPTIONAL_ARGS.get(pFunction));
}
- ArrayList _unknown_args = new ArrayList();
- Iterator _iter = pArgs.keySet().iterator();
- while (_iter.hasNext()) {
- String _cur_key = _iter.next();
+ ArrayList unknownArgs = new ArrayList();
+ Iterator iter = pArgs.keySet().iterator();
+ while (iter.hasNext()) {
+ String curKey = iter.next();
try {
- arg _cur_arg = arg.valueOf(_cur_key);
- if (!all_args.contains(_cur_arg)) {
- pReturn.getStringArrayList(ret.WARNINGS.name()).add("Unknown argument: " + _cur_key);
- _unknown_args.add(_cur_key);
+ arg curArg = arg.valueOf(curKey);
+ if (!allArgs.contains(curArg)) {
+ pReturn.getStringArrayList(ret.WARNINGS.name()).add("Unknown argument: " + curKey);
+ unknownArgs.add(curKey);
}
} catch (Exception e) {
- pReturn.getStringArrayList(ret.WARNINGS.name()).add("Unknown argument: " + _cur_key);
- _unknown_args.add(_cur_key);
+ pReturn.getStringArrayList(ret.WARNINGS.name()).add("Unknown argument: " + curKey);
+ unknownArgs.add(curKey);
}
}
// remove unknown arguments so our bundle has just what we need
- for (String _arg : _unknown_args) {
- pArgs.remove(_arg);
+ for (String arg : unknownArgs) {
+ pArgs.remove(arg);
}
}
- private boolean prepare_args(String call, Bundle pArgs, Bundle pReturn) {
+ private boolean prepareArgs(String pCall, Bundle pArgs, Bundle pReturn) {
Apg.initialize(getBaseContext());
/* add default return values for all functions */
- add_default_returns(pReturn);
+ addDefaultReturns(pReturn);
/* add default arguments if missing */
- add_default_arguments(call, pArgs);
+ addDefaultArguments(pCall, pArgs);
if( LOCAL_LOGV ) Log.v(TAG, "add_default_arguments");
/* check for required arguments */
- check_required_args(call, pArgs, pReturn);
+ checkForRequiredArgs(pCall, pArgs, pReturn);
if( LOCAL_LOGV ) Log.v(TAG, "check_required_args");
/* check for unknown arguments and add to warning if found */
- check_unknown_args(call, pArgs, pReturn);
+ checkForUnknownArgs(pCall, pArgs, pReturn);
if( LOCAL_LOGV ) Log.v(TAG, "check_unknown_args");
/* return if errors happened */
if (pReturn.getStringArrayList(ret.ERRORS.name()).size() != 0) {
- if( LOCAL_LOGV ) Log.v(TAG, "Errors after preparing, not executing "+call);
- pReturn.putInt(ret.ERROR.name(), error.ARGUMENTS_MISSING.shifted_ordinal());
+ if( LOCAL_LOGV ) Log.v(TAG, "Errors after preparing, not executing "+pCall);
+ pReturn.putInt(ret.ERROR.name(), error.ARGUMENTS_MISSING.shiftedOrdinal());
return false;
}
if( LOCAL_LOGV ) Log.v(TAG, "error return");
@@ -393,30 +379,30 @@ public class ApgService extends Service {
private boolean encrypt(Bundle pArgs, Bundle pReturn) {
- long _pub_master_keys[] = {};
+ long pubMasterKeys[] = {};
if (pArgs.containsKey(arg.PUBLIC_KEYS.name())) {
- ArrayList _list = pArgs.getStringArrayList(arg.PUBLIC_KEYS.name());
- ArrayList _pub_keys = new ArrayList();
- if( LOCAL_LOGV ) Log.v(TAG, "Long size: " + _list.size());
- Iterator _iter = _list.iterator();
- while (_iter.hasNext()) {
- _pub_keys.add(_iter.next());
+ ArrayList list = pArgs.getStringArrayList(arg.PUBLIC_KEYS.name());
+ ArrayList pubKeys = new ArrayList();
+ if( LOCAL_LOGV ) Log.v(TAG, "Long size: " + list.size());
+ Iterator iter = list.iterator();
+ while (iter.hasNext()) {
+ pubKeys.add(iter.next());
}
- _pub_master_keys = get_master_key(_pub_keys, pReturn);
+ pubMasterKeys = getMasterKey(pubKeys, pReturn);
}
- InputStream _inStream = new ByteArrayInputStream(pArgs.getString(arg.MESSAGE.name()).getBytes());
- InputData _in = new InputData(_inStream, 0); // XXX Size second param?
+ InputStream inStream = new ByteArrayInputStream(pArgs.getString(arg.MESSAGE.name()).getBytes());
+ InputData in = new InputData(inStream, 0); // XXX Size second param?
- OutputStream _out = new ByteArrayOutputStream();
+ OutputStream out = new ByteArrayOutputStream();
if( LOCAL_LOGV ) Log.v(TAG, "About to encrypt");
try {
Apg.encrypt(getBaseContext(), // context
- _in, // input stream
- _out, // output stream
+ in, // input stream
+ out, // output stream
pArgs.getBoolean(arg.ARMORED_OUTPUT.name()), // ARMORED_OUTPUT
- _pub_master_keys, // encryption keys
- get_master_key(pArgs.getString(arg.SIGNATURE_KEY.name()), pReturn), // signature key
+ pubMasterKeys, // encryption keys
+ getMasterKey(pArgs.getString(arg.SIGNATURE_KEY.name()), pReturn), // signature key
pArgs.getString(arg.PRIVATE_KEY_PASSPHRASE.name()), // signature passphrase
null, // progress
pArgs.getInt(arg.ENCRYPTION_ALGORYTHM.name()), // encryption
@@ -427,29 +413,29 @@ public class ApgService extends Service {
);
} catch (Exception e) {
Log.e(TAG, "Exception in encrypt");
- String _msg = e.getMessage();
- if (_msg.equals(getBaseContext().getString(R.string.error_noSignaturePassPhrase))) {
- pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot encrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + " missing): " + _msg);
- pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_MISSING.shifted_ordinal());
- } else if (_msg.equals(getBaseContext().getString(R.string.error_couldNotExtractPrivateKey))) {
- pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot encrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + " probably wrong): " + _msg);
- pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_WRONG.shifted_ordinal());
+ String msg = e.getMessage();
+ if (msg.equals(getBaseContext().getString(R.string.error_noSignaturePassPhrase))) {
+ pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot encrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + " missing): " + msg);
+ pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_MISSING.shiftedOrdinal());
+ } else if (msg.equals(getBaseContext().getString(R.string.error_couldNotExtractPrivateKey))) {
+ pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot encrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + " probably wrong): " + msg);
+ pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_WRONG.shiftedOrdinal());
} else {
pReturn.getStringArrayList(ret.ERRORS.name()).add("Internal failure (" + e.getClass() + ") in APG when encrypting: " + e.getMessage());
- pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.shifted_ordinal());
+ pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.shiftedOrdinal());
}
return false;
}
if( LOCAL_LOGV ) Log.v(TAG, "Encrypted");
- pReturn.putString(ret.RESULT.name(), _out.toString());
+ pReturn.putString(ret.RESULT.name(), out.toString());
return true;
}
private final IApgService.Stub mBinder = new IApgService.Stub() {
- public boolean get_keys(Bundle pArgs, Bundle pReturn) {
+ public boolean getKeys(Bundle pArgs, Bundle pReturn) {
- prepare_args("get_keys", pArgs, pReturn);
+ prepareArgs("get_keys", pArgs, pReturn);
HashMap qParams = new HashMap();
qParams.put("columns", new String[] {
@@ -459,31 +445,31 @@ public class ApgService extends Service {
qParams.put("key_type", pArgs.getInt(arg.KEY_TYPE.name()));
- Cursor mCursor = get_key_entries(qParams);
- ArrayList fprints = new ArrayList();
+ Cursor cursor = getKeyEntries(qParams);
+ ArrayList fPrints = new ArrayList();
ArrayList ids = new ArrayList();
- while (mCursor.moveToNext()) {
- if( LOCAL_LOGV ) Log.v(TAG, "adding key "+Apg.getSmallFingerPrint(mCursor.getLong(0)));
- fprints.add(Apg.getSmallFingerPrint(mCursor.getLong(0)));
- ids.add(mCursor.getString(1));
+ while (cursor.moveToNext()) {
+ if( LOCAL_LOGV ) Log.v(TAG, "adding key "+Apg.getSmallFingerPrint(cursor.getLong(0)));
+ fPrints.add(Apg.getSmallFingerPrint(cursor.getLong(0)));
+ ids.add(cursor.getString(1));
}
- mCursor.close();
+ cursor.close();
- pReturn.putStringArrayList(ret.FINGERPRINTS.name(), fprints);
+ pReturn.putStringArrayList(ret.FINGERPRINTS.name(), fPrints);
pReturn.putStringArrayList(ret.USER_IDS.name(), ids);
return true;
}
- public boolean encrypt_with_public_key(Bundle pArgs, Bundle pReturn) {
- if (!prepare_args("encrypt_with_public_key", pArgs, pReturn)) {
+ public boolean encryptWithPublicKey(Bundle pArgs, Bundle pReturn) {
+ if (!prepareArgs("encrypt_with_public_key", pArgs, pReturn)) {
return false;
}
return encrypt(pArgs, pReturn);
}
- public boolean encrypt_with_passphrase(Bundle pArgs, Bundle pReturn) {
- if (!prepare_args("encrypt_with_passphrase", pArgs, pReturn)) {
+ public boolean encryptWithPassphrase(Bundle pArgs, Bundle pReturn) {
+ if (!prepareArgs("encrypt_with_passphrase", pArgs, pReturn)) {
return false;
}
@@ -492,11 +478,11 @@ public class ApgService extends Service {
}
public boolean decrypt(Bundle pArgs, Bundle pReturn) {
- if (!prepare_args("decrypt", pArgs, pReturn)) {
+ if (!prepareArgs("decrypt", pArgs, pReturn)) {
return false;
}
- String _passphrase = pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) != null ? pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) : pArgs
+ String passphrase = pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) != null ? pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) : pArgs
.getString(arg.PRIVATE_KEY_PASSPHRASE.name());
InputStream inStream = new ByteArrayInputStream(pArgs.getString(arg.MESSAGE.name()).getBytes());
@@ -504,21 +490,21 @@ public class ApgService extends Service {
OutputStream out = new ByteArrayOutputStream();
if( LOCAL_LOGV ) Log.v(TAG, "About to decrypt");
try {
- Apg.decrypt(getBaseContext(), in, out, _passphrase, null, // progress
+ Apg.decrypt(getBaseContext(), in, out, passphrase, null, // progress
pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) != null // symmetric
);
} catch (Exception e) {
Log.e(TAG, "Exception in decrypt");
- String _msg = e.getMessage();
- if (_msg.equals(getBaseContext().getString(R.string.error_noSecretKeyFound))) {
- pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot decrypt: " + _msg);
- pReturn.putInt(ret.ERROR.name(), error.NO_MATCHING_SECRET_KEY.shifted_ordinal());
- } else if (_msg.equals(getBaseContext().getString(R.string.error_wrongPassPhrase))) {
- pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot decrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + " wrong/missing): " + _msg);
- pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_WRONG.shifted_ordinal());
+ String msg = e.getMessage();
+ if (msg.equals(getBaseContext().getString(R.string.error_noSecretKeyFound))) {
+ pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot decrypt: " + msg);
+ pReturn.putInt(ret.ERROR.name(), error.NO_MATCHING_SECRET_KEY.shiftedOrdinal());
+ } else if (msg.equals(getBaseContext().getString(R.string.error_wrongPassPhrase))) {
+ pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot decrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + " wrong/missing): " + msg);
+ pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_WRONG.shiftedOrdinal());
} else {
- pReturn.getStringArrayList(ret.ERRORS.name()).add("Internal failure (" + e.getClass() + ") in APG when decrypting: " + _msg);
- pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.shifted_ordinal());
+ pReturn.getStringArrayList(ret.ERRORS.name()).add("Internal failure (" + e.getClass() + ") in APG when decrypting: " + msg);
+ pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.shiftedOrdinal());
}
return false;
}
diff --git a/src/org/thialfihar/android/apg/IApgService.aidl b/src/org/thialfihar/android/apg/IApgService.aidl
index 0eb1307b8..df46805ac 100644
--- a/src/org/thialfihar/android/apg/IApgService.aidl
+++ b/src/org/thialfihar/android/apg/IApgService.aidl
@@ -1,12 +1,13 @@
package org.thialfihar.android.apg;
interface IApgService {
-
- /* All functions fill the return_vals Bundle with the following keys:
+
+ /* All functions fill the returnVals Bundle with the following keys:
*
* ArrayList "WARNINGS" = Warnings, if any
* ArrayList "ERRORS" = Human readable error descriptions, if any
- * int "ERROR" = Numeric representation of error, if any, starting with 100
+ * int "ERROR" = Numeric representation of error, if any
+ * starting with 100:
* 100: Required argument missing
* 101: Generic failure of APG
* 102: No matching private key found
@@ -14,11 +15,10 @@ interface IApgService {
* 104: Private key's passphrase missing
*/
- /* *******************************************************
- * Encrypting and decrypting
+ /* ********************************************************
+ * Encryption
* ********************************************************/
-
/* All encryption function's arguments
*
* Bundle params' keys:
@@ -54,27 +54,28 @@ interface IApgService {
* (optional)
* String "PRIVATE_KEY_PASSPHRASE" = Passphrase for signing key
*
- * Bundle return_vals (in addition to the ERRORS/WARNINGS above):
+ * Bundle returnVals (in addition to the ERRORS/WARNINGS above):
* String "RESULT" = Encrypted message
*/
-
- /* Additional argument:
+
+ /* Additional argument for function below:
* (required)
* String "SYMMETRIC_PASSPHRASE" = Symmetric passphrase to use
*/
- boolean encrypt_with_passphrase(in Bundle params, out Bundle return_vals);
-
+ boolean encryptWithPassphrase(in Bundle params, out Bundle returnVals);
+
/* Additional argument:
* (required)
* ArrayList "PUBLIC_KEYS" = Public keys (8char fingerprint "123ABC12" OR
* complete id "Alice Meyer ")
*/
- boolean encrypt_with_public_key(in Bundle params, out Bundle return_vals);
-
+ boolean encryptWithPublicKey(in Bundle params, out Bundle returnVals);
- /* Decrypt something
- *
- * Bundle params:
+ /* ********************************************************
+ * Decryption
+ * ********************************************************/
+
+ /* Bundle params:
* (required)
* String "MESSAGE" = Message to decrypt
*
@@ -87,14 +88,12 @@ interface IApgService {
* Bundle return_vals:
* String "RESULT" = Decrypted message
*/
-
- boolean decrypt(in Bundle params, out Bundle return_vals);
-
-
- /* *******************************************************
+ boolean decrypt(in Bundle params, out Bundle returnVals);
+
+ /* ********************************************************
* Get key information
* ********************************************************/
-
+
/* Get info about all available keys
*
* Bundle params:
@@ -106,8 +105,9 @@ interface IApgService {
* Returns:
* StringArrayList "FINGERPRINTS" = Short fingerprints of keys
*
- * StringArrayList "USER_IDS" = User ids of corrosponding fingerprints (order is the same)
+ * StringArrayList "USER_IDS" = User ids of corresponding fingerprints
+ * (order is the same as in FINGERPRINTS)
*/
- boolean get_keys(in Bundle params, out Bundle return_vals);
+ boolean getKeys(in Bundle params, out Bundle returnVals);
}
\ No newline at end of file
diff --git a/src/org/thialfihar/android/apg/utils/ApgCon.java b/src/org/thialfihar/android/apg/utils/ApgCon.java
index 7ab2ea842..0c216b547 100644
--- a/src/org/thialfihar/android/apg/utils/ApgCon.java
+++ b/src/org/thialfihar/android/apg/utils/ApgCon.java
@@ -46,14 +46,19 @@ import org.thialfihar.android.apg.utils.ApgConInterface.OnCallFinishListener;
*
*
* @author Markus Doits
- * @version 0.9.9
+ * @version 1.0rc1
*
*/
public class ApgCon {
private static final boolean LOCAL_LOGV = true;
private static final boolean LOCAL_LOGD = true;
- private class call_async extends AsyncTask {
+ private final static String TAG = "ApgCon";
+ private final static int API_VERSION = 1; // aidl api-version it expects
+
+ public int secondsToWaitForConnection = 15;
+
+ private class CallAsync extends AsyncTask {
@Override
protected Void doInBackground(String... arg) {
@@ -64,48 +69,46 @@ public class ApgCon {
protected void onPostExecute(Void res) {
if( LOCAL_LOGD ) Log.d(TAG, "Async execution finished");
- async_running = false;
+ mAsyncRunning = false;
}
}
- private final static String TAG = "ApgCon";
- private final static int api_version = 1; // aidl api-version it expects
private final Context mContext;
- private final error connection_status;
- private boolean async_running = false;
- private OnCallFinishListener onCallFinishListener;
+ private final error mConnectionStatus;
+ private boolean mAsyncRunning = false;
+ private OnCallFinishListener mOnCallFinishListener;
- private final Bundle result = new Bundle();
- private final Bundle args = new Bundle();
- private final ArrayList error_list = new ArrayList();
- private final ArrayList warning_list = new ArrayList();
+ private final Bundle mResult = new Bundle();
+ private final Bundle mArgs = new Bundle();
+ private final ArrayList mErrorList = new ArrayList();
+ private final ArrayList mWarningList = new ArrayList();
/** Remote service for decrypting and encrypting data */
- private IApgService apgService = null;
+ private IApgService mApgService = null;
/** Set apgService accordingly to connection status */
- private ServiceConnection apgConnection = new ServiceConnection() {
+ private ServiceConnection mApgConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
if( LOCAL_LOGD ) Log.d(TAG, "IApgService bound to apgService");
- apgService = IApgService.Stub.asInterface(service);
+ mApgService = IApgService.Stub.asInterface(service);
}
public void onServiceDisconnected(ComponentName className) {
if( LOCAL_LOGD ) Log.d(TAG, "IApgService disconnected");
- apgService = null;
+ mApgService = null;
}
};
-
+
/**
* Different types of local errors
- *
- * @author markus
- *
*/
public static enum error {
+ /**
+ * no error
+ */
NO_ERROR,
/**
* generic error
@@ -131,6 +134,9 @@ public class ApgCon {
* found APG but without AIDL interface
*/
APG_AIDL_MISSING,
+ /**
+ * found APG but with wrong API
+ */
APG_API_MISSMATCH
}
@@ -156,77 +162,78 @@ public class ApgCon {
if( LOCAL_LOGV ) Log.v(TAG, "EncryptionService created");
mContext = ctx;
- error tmp_connection_status = null;
+ error tmpError = null;
try {
if( LOCAL_LOGV ) Log.v(TAG, "Searching for the right APG version");
- ServiceInfo apg_services[] = ctx.getPackageManager().getPackageInfo("org.thialfihar.android.apg",
+ ServiceInfo apgServices[] = ctx.getPackageManager().getPackageInfo("org.thialfihar.android.apg",
PackageManager.GET_SERVICES | PackageManager.GET_META_DATA).services;
- if (apg_services == null) {
+ if (apgServices == null) {
Log.e(TAG, "Could not fetch services");
- tmp_connection_status = error.GENERIC;
+ tmpError = error.GENERIC;
} else {
- boolean apg_service_found = false;
- for (ServiceInfo inf : apg_services) {
+ boolean apgServiceFound = false;
+ for (ServiceInfo inf : apgServices) {
if( LOCAL_LOGV ) Log.v(TAG, "Found service of APG: " + inf.name);
if (inf.name.equals("org.thialfihar.android.apg.ApgService")) {
- apg_service_found = true;
+ apgServiceFound = true;
if (inf.metaData == null) {
Log.w(TAG, "Could not determine ApgService API");
Log.w(TAG, "This probably won't work!");
- warning_list.add("(LOCAL) Could not determine ApgService API");
- tmp_connection_status = error.APG_API_MISSMATCH;
- } else if (inf.metaData.getInt("api_version") != api_version) {
- Log.w(TAG, "Found ApgService API version" + inf.metaData.getInt("api_version") + " but exspected " + api_version);
+ mWarningList.add("(LOCAL) Could not determine ApgService API");
+ tmpError = error.APG_API_MISSMATCH;
+ } else if (inf.metaData.getInt("api_version") != API_VERSION) {
+ Log.w(TAG, "Found ApgService API version" + inf.metaData.getInt("api_version") + " but exspected " + API_VERSION);
Log.w(TAG, "This probably won't work!");
- warning_list.add("(LOCAL) Found ApgService API version" + inf.metaData.getInt("api_version") + " but exspected " + api_version);
- tmp_connection_status = error.APG_API_MISSMATCH;
+ mWarningList.add("(LOCAL) Found ApgService API version" + inf.metaData.getInt("api_version") + " but exspected " + API_VERSION);
+ tmpError = error.APG_API_MISSMATCH;
} else {
- if( LOCAL_LOGV ) Log.v(TAG, "Found api_version " + api_version + ", everything should work");
- tmp_connection_status = error.NO_ERROR;
+ if( LOCAL_LOGV ) Log.v(TAG, "Found api_version " + API_VERSION + ", everything should work");
+ tmpError = error.NO_ERROR;
}
}
}
- if (!apg_service_found) {
+ if (!apgServiceFound) {
Log.e(TAG, "Could not find APG with AIDL interface, this probably won't work");
- error_list.add("(LOCAL) Could not find APG with AIDL interface, this probably won't work");
- result.putInt(ret.ERROR.name(), error.APG_AIDL_MISSING.ordinal());
- tmp_connection_status = error.APG_NOT_FOUND;
+ mErrorList.add("(LOCAL) Could not find APG with AIDL interface, this probably won't work");
+ mResult.putInt(ret.ERROR.name(), error.APG_AIDL_MISSING.ordinal());
+ tmpError = error.APG_NOT_FOUND;
}
}
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Could not find APG, is it installed?", e);
- error_list.add("(LOCAL) Could not find APG, is it installed?");
- result.putInt(ret.ERROR.name(), error.APG_NOT_FOUND.ordinal());
- tmp_connection_status = error.APG_NOT_FOUND;
+ mErrorList.add("(LOCAL) Could not find APG, is it installed?");
+ mResult.putInt(ret.ERROR.name(), error.APG_NOT_FOUND.ordinal());
+ tmpError = error.APG_NOT_FOUND;
}
+
+ mConnectionStatus = tmpError;
- connection_status = tmp_connection_status;
}
/** try to connect to the apg service */
private boolean connect() {
if( LOCAL_LOGV ) Log.v(TAG, "trying to bind the apgService to context");
- if (apgService != null) {
+ if (mApgService != null) {
if( LOCAL_LOGV ) Log.v(TAG, "allready connected");
return true;
}
try {
- mContext.bindService(new Intent(IApgService.class.getName()), apgConnection, Context.BIND_AUTO_CREATE);
+ mContext.bindService(new Intent(IApgService.class.getName()), mApgConnection, Context.BIND_AUTO_CREATE);
} catch (Exception e) {
Log.e(TAG, "could not bind APG service", e);
return false;
}
- int wait_count = 0;
- while (apgService == null && wait_count++ < 15) {
+ int waitCount = 0;
+ while (mApgService == null && waitCount++ < secondsToWaitForConnection) {
if( LOCAL_LOGV ) Log.v(TAG, "sleeping 1 second to wait for apg");
android.os.SystemClock.sleep(1000);
}
- if (wait_count >= 15) {
+ if (waitCount >= secondsToWaitForConnection) {
if( LOCAL_LOGV ) Log.v(TAG, "slept waiting for nothing!");
return false;
}
@@ -250,14 +257,14 @@ public class ApgCon {
*/
public void disconnect() {
if( LOCAL_LOGV ) Log.v(TAG, "disconnecting apgService");
- if (apgService != null) {
- mContext.unbindService(apgConnection);
- apgService = null;
+ if (mApgService != null) {
+ mContext.unbindService(mApgConnection);
+ mApgService = null;
}
}
private boolean initialize() {
- if (apgService == null) {
+ if (mApgService == null) {
if (!connect()) {
if( LOCAL_LOGV ) Log.v(TAG, "connection to apg service failed");
return false;
@@ -270,40 +277,40 @@ public class ApgCon {
* Calls a function from APG's AIDL-interface
*
*
- * After you have set up everything with {@link #set_arg(String, String)}
+ * After you have set up everything with {@link #setArg(String, String)}
* (and variants), you can call a function from the AIDL-interface. This
* will
*
* - start connection to the remote interface (if not already connected)
* - call the passed function with all set up parameters synchronously
- * - set up everything to retrieve the result and/or warnings/errors
+ * - set up everything to retrieve the mResult and/or warnings/errors
* - call the callback if provided
*
*
*
*
* Note your thread will be blocked during execution - if you want to call
- * the function asynchronously, see {@link #call_async(String)}.
+ * the function asynchronously, see {@link #callAsync(String)}.
*
*
* @param function
* a remote function to call
* @return true, if call successful (= no errors), else false
*
- * @see #call_async(String)
- * @see #set_arg(String, String)
- * @see #set_onCallFinishListener(OnCallFinishListener)
+ * @see #callAsync(String)
+ * @see #setArg(String, String)
+ * @see #setOnCallFinishListener(OnCallFinishListener)
*/
public boolean call(String function) {
- boolean success = this.call(function, args, result);
- if (onCallFinishListener != null) {
+ boolean success = this.call(function, mArgs, mResult);
+ if (mOnCallFinishListener != null) {
try {
if( LOCAL_LOGD ) Log.d(TAG, "About to execute callback");
- onCallFinishListener.onCallFinish(result);
+ mOnCallFinishListener.onCallFinish(mResult);
if( LOCAL_LOGD ) Log.d(TAG, "Callback executed");
} catch (Exception e) {
Log.w(TAG, "Exception on callback: (" + e.getClass() + ") " + e.getMessage(), e);
- warning_list.add("(LOCAL) Could not execute callback (" + e.getClass() + "): " + e.getMessage());
+ mWarningList.add("(LOCAL) Could not execute callback (" + e.getClass() + "): " + e.getMessage());
}
}
return success;
@@ -321,8 +328,8 @@ public class ApgCon {
*
* To see whether the task is finished, you have to possibilities:
*
- * - In your thread, poll {@link #is_running()}
- * - Supply a callback with {@link #set_onCallFinishListener(OnCallFinishListener)}
+ * - In your thread, poll {@link #isRunning()}
+ * - Supply a callback with {@link #setOnCallFinishListener(OnCallFinishListener)}
*
*
*
@@ -330,47 +337,47 @@ public class ApgCon {
* a remote function to call
*
* @see #call(String)
- * @see #is_running()
- * @see #set_onCallFinishListener(OnCallFinishListener)
+ * @see #isRunning()
+ * @see #setOnCallFinishListener(OnCallFinishListener)
*/
- public void call_async(String function) {
- async_running = true;
- new call_async().execute(function);
+ public void callAsync(String function) {
+ mAsyncRunning = true;
+ new CallAsync().execute(function);
}
private boolean call(String function, Bundle pArgs, Bundle pReturn) {
if (!initialize()) {
- error_list.add("(LOCAL) Cannot bind to ApgService");
- result.putInt(ret.ERROR.name(), error.CANNOT_BIND_TO_APG.ordinal());
+ mErrorList.add("(LOCAL) Cannot bind to ApgService");
+ mResult.putInt(ret.ERROR.name(), error.CANNOT_BIND_TO_APG.ordinal());
return false;
}
if (function == null || function.length() == 0) {
- error_list.add("(LOCAL) Function to call missing");
- result.putInt(ret.ERROR.name(), error.CALL_MISSING.ordinal());
+ mErrorList.add("(LOCAL) Function to call missing");
+ mResult.putInt(ret.ERROR.name(), error.CALL_MISSING.ordinal());
return false;
}
try {
- Boolean success = (Boolean) IApgService.class.getMethod(function, Bundle.class, Bundle.class).invoke(apgService, pArgs, pReturn);
- error_list.addAll(pReturn.getStringArrayList(ret.ERRORS.name()));
- warning_list.addAll(pReturn.getStringArrayList(ret.WARNINGS.name()));
+ Boolean success = (Boolean) IApgService.class.getMethod(function, Bundle.class, Bundle.class).invoke(mApgService, pArgs, pReturn);
+ mErrorList.addAll(pReturn.getStringArrayList(ret.ERRORS.name()));
+ mWarningList.addAll(pReturn.getStringArrayList(ret.WARNINGS.name()));
return success;
} catch (NoSuchMethodException e) {
Log.e(TAG, "Remote call not known (" + function + "): " + e.getMessage(), e);
- error_list.add("(LOCAL) Remote call not known (" + function + "): " + e.getMessage());
- result.putInt(ret.ERROR.name(), error.CALL_NOT_KNOWN.ordinal());
+ mErrorList.add("(LOCAL) Remote call not known (" + function + "): " + e.getMessage());
+ mResult.putInt(ret.ERROR.name(), error.CALL_NOT_KNOWN.ordinal());
return false;
} catch (InvocationTargetException e) {
Throwable orig = e.getTargetException();
Log.w(TAG, "Exception of type '" + orig.getClass() + "' on AIDL call '" + function + "': " + orig.getMessage(), orig);
- error_list.add("(LOCAL) Exception of type '" + orig.getClass() + "' on AIDL call '" + function + "': " + orig.getMessage());
+ mErrorList.add("(LOCAL) Exception of type '" + orig.getClass() + "' on AIDL call '" + function + "': " + orig.getMessage());
return false;
} catch (Exception e) {
Log.e(TAG, "Generic error (" + e.getClass() + "): " + e.getMessage(), e);
- error_list.add("(LOCAL) Generic error (" + e.getClass() + "): " + e.getMessage());
- result.putInt(ret.ERROR.name(), error.GENERIC.ordinal());
+ mErrorList.add("(LOCAL) Generic error (" + e.getClass() + "): " + e.getMessage());
+ mResult.putInt(ret.ERROR.name(), error.GENERIC.ordinal());
return false;
}
@@ -390,7 +397,7 @@ public class ApgCon {
*
*
* Note, that the parameters are not deleted after a call, so you have to
- * reset ({@link #clear_args()}) them manually if you want to.
+ * reset ({@link #clearArgs()}) them manually if you want to.
*
*
*
@@ -399,10 +406,10 @@ public class ApgCon {
* @param val
* the value
*
- * @see #clear_args()
+ * @see #clearArgs()
*/
- public void set_arg(String key, String val) {
- args.putString(key, val);
+ public void setArg(String key, String val) {
+ mArgs.putString(key, val);
}
/**
@@ -415,7 +422,7 @@ public class ApgCon {
*
*
*
- * set_arg("a key", new String[]{ "entry 1", "entry 2" });
+ * setArg("a key", new String[]{ "entry 1", "entry 2" });
*
*
*
@@ -424,14 +431,14 @@ public class ApgCon {
* @param vals
* the value
*
- * @see #set_arg(String, String)
+ * @see #setArg(String, String)
*/
- public void set_arg(String key, String vals[]) {
+ public void setArg(String key, String vals[]) {
ArrayList list = new ArrayList();
for (String val : vals) {
list.add(val);
}
- args.putStringArrayList(key, list);
+ mArgs.putStringArrayList(key, list);
}
/**
@@ -442,10 +449,10 @@ public class ApgCon {
* @param vals
* the value
*
- * @see #set_arg(String, String)
+ * @see #setArg(String, String)
*/
- public void set_arg(String key, boolean val) {
- args.putBoolean(key, val);
+ public void setArg(String key, boolean val) {
+ mArgs.putBoolean(key, val);
}
/**
@@ -456,10 +463,10 @@ public class ApgCon {
* @param vals
* the value
*
- * @see #set_arg(String, String)
+ * @see #setArg(String, String)
*/
- public void set_arg(String key, int val) {
- args.putInt(key, val);
+ public void setArg(String key, int val) {
+ mArgs.putInt(key, val);
}
/**
@@ -474,14 +481,14 @@ public class ApgCon {
* @param vals
* the value
*
- * @see #set_arg(String, String)
+ * @see #setArg(String, String)
*/
- public void set_arg(String key, int vals[]) {
+ public void setArg(String key, int vals[]) {
ArrayList list = new ArrayList();
for (int val : vals) {
list.add(val);
}
- args.putIntegerArrayList(key, list);
+ mArgs.putIntegerArrayList(key, list);
}
/**
@@ -489,17 +496,17 @@ public class ApgCon {
*
*
* Anything the has been set up with the various
- * {@link #set_arg(String, String)} functions, is cleared.
+ * {@link #setArg(String, String)} functions, is cleared.
*
*
- * Note, that any warning, error, callback, result, etc. is not cleared with
+ * Note, that any warning, error, callback, mResult, etc. is not cleared with
* this.
*
*
* @see #reset()
*/
- public void clear_args() {
- args.clear();
+ public void clearArgs() {
+ mArgs.clear();
}
/**
@@ -509,8 +516,8 @@ public class ApgCon {
* the object's key you want to return
* @return an object at position key, or null if not set
*/
- public Object get_arg(String key) {
- return args.get(key);
+ public Object getArg(String key) {
+ return mArgs.get(key);
}
/**
@@ -525,12 +532,12 @@ public class ApgCon {
* @return a human readable description of a error that happened, or null if
* no more errors
*
- * @see #has_next_error()
- * @see #clear_errors()
+ * @see #hasNextError()
+ * @see #clearErrors()
*/
- public String get_next_error() {
- if (error_list.size() != 0)
- return error_list.remove(0);
+ public String getNextError() {
+ if (mErrorList.size() != 0)
+ return mErrorList.remove(0);
else
return null;
}
@@ -540,10 +547,10 @@ public class ApgCon {
*
* @return true, if there are unreturned errors, false otherwise
*
- * @see #get_next_error()
+ * @see #getNextError()
*/
- public boolean has_next_error() {
- return error_list.size() != 0;
+ public boolean hasNextError() {
+ return mErrorList.size() != 0;
}
/**
@@ -552,15 +559,15 @@ public class ApgCon {
*
* Values <100 mean the error happened locally, values >=100 mean the error
* happened at the remote side (APG). See the IApgService.aidl (or get the
- * human readable description with {@link #get_next_error()}) for what
+ * human readable description with {@link #getNextError()}) for what
* errors >=100 mean.
*
*
* @return the id of the error that happened
*/
- public int get_error() {
- if (result.containsKey(ret.ERROR.name()))
- return result.getInt(ret.ERROR.name());
+ public int getError() {
+ if (mResult.containsKey(ret.ERROR.name()))
+ return mResult.getInt(ret.ERROR.name());
else
return -1;
}
@@ -577,12 +584,12 @@ public class ApgCon {
* @return a human readable description of a warning that happened, or null
* if no more warnings
*
- * @see #has_next_warning()
- * @see #clear_warnings()
+ * @see #hasNextWarning()
+ * @see #clearWarnings()
*/
- public String get_next_warning() {
- if (warning_list.size() != 0)
- return warning_list.remove(0);
+ public String getNextWarning() {
+ if (mWarningList.size() != 0)
+ return mWarningList.remove(0);
else
return null;
}
@@ -592,94 +599,94 @@ public class ApgCon {
*
* @return true, if there are unreturned warnings, false otherwise
*
- * @see #get_next_warning()
+ * @see #getNextWarning()
*/
- public boolean has_next_warning() {
- return warning_list.size() != 0;
+ public boolean hasNextWarning() {
+ return mWarningList.size() != 0;
}
/**
* Get the result
*
*
- * This gets your result. After doing an encryption or decryption with APG,
+ * This gets your mResult. After doing an encryption or decryption with APG,
* you get the output with this function.
*
*
- * Note, that when your last remote call is unsuccessful, the result will
+ * Note, that when your last remote call is unsuccessful, the mResult will
* still have the same value like the last successful call (or null, if no
- * call was successful). To ensure you do not work with old call's results,
- * either be sure to {@link #reset()} (or at least {@link #clear_result()})
+ * call was successful). To ensure you do not work with old call's mResults,
+ * either be sure to {@link #reset()} (or at least {@link #clearResult()})
* your instance before each new call or always check that
- * {@link #has_next_error()} is false.
+ * {@link #hasNextError()} is false.
*
*
- * @return the result of the last {@link #call(String)} or
+ * @return the mResult of the last {@link #call(String)} or
* {@link #call_asinc(String)}.
*
* @see #reset()
- * @see #clear_result()
- * @see #get_result_bundle()
+ * @see #clearResult()
+ * @see #getResultBundle()
*/
- public String get_result() {
- return result.getString(ret.RESULT.name());
+ public String getResult() {
+ return mResult.getString(ret.RESULT.name());
}
/**
- * Get the result bundle
+ * Get the mResult bundle
*
*
- * Unlike {@link #get_result()}, which only returns any en-/decrypted
+ * Unlike {@link #getResult()}, which only returns any en-/decrypted
* message, this function returns the complete information that was returned
* by Apg. This also includes the "RESULT", but additionally the warnings,
* errors and any other information.
*
*
* For warnings and errors it is suggested to use the functions that are
- * provided here, namely {@link #get_error()}, {@link #get_next_error()},
+ * provided here, namely {@link #getError()}, {@link #getNextError()},
* {@link #get_next_Warning()} etc.), but if any call returns something non
- * standard, you have access to the complete result bundle to extract the
+ * standard, you have access to the complete mResult bundle to extract the
* information.
*
*
- * @return the complete result-bundle of the last call to apg
+ * @return the complete mResult-bundle of the last call to apg
*/
- public Bundle get_result_bundle() {
- return result;
+ public Bundle getResultBundle() {
+ return mResult;
}
- public error get_connection_status() {
- return connection_status;
+ public error getConnectionStatus() {
+ return mConnectionStatus;
}
/**
* Clears all unfetched errors
*
- * @see #get_next_error()
- * @see #has_next_error()
+ * @see #getNextError()
+ * @see #hasNextError()
*/
- public void clear_errors() {
- error_list.clear();
- result.remove(ret.ERROR.name());
+ public void clearErrors() {
+ mErrorList.clear();
+ mResult.remove(ret.ERROR.name());
}
/**
* Clears all unfetched warnings
*
- * @see #get_next_warning()
- * @see #has_next_warning()
+ * @see #getNextWarning()
+ * @see #hasNextWarning()
*/
- public void clear_warnings() {
- warning_list.clear();
+ public void clearWarnings() {
+ mWarningList.clear();
}
/**
- * Clears the last result
+ * Clears the last mResult
*
- * @see #get_result()
+ * @see #getResult()
*/
- public void clear_result() {
- result.remove(ret.RESULT.name());
+ public void clearResult() {
+ mResult.remove(ret.RESULT.name());
}
/**
@@ -689,34 +696,34 @@ public class ApgCon {
* a object to call back after async execution
* @see ApgConInterface
*/
- public void set_onCallFinishListener(OnCallFinishListener lis) {
- onCallFinishListener = lis;
+ public void setOnCallFinishListener(OnCallFinishListener lis) {
+ mOnCallFinishListener = lis;
}
/**
* Clears any callback object
*
- * @see #set_onCallFinishListener(OnCallFinishListener)
+ * @see #setOnCallFinishListener(OnCallFinishListener)
*/
- public void clear_onCallFinishListener() {
- onCallFinishListener = null;
+ public void clearOnCallFinishListener() {
+ mOnCallFinishListener = null;
}
/**
* Checks, whether an async execution is running
*
*
- * If you started something with {@link #call_async(String)}, this will
+ * If you started something with {@link #callAsync(String)}, this will
* return true if the task is still running
*
*
* @return true, if an async task is still running, false otherwise
*
- * @see #call_async(String)
+ * @see #callAsync(String)
*
*/
- public boolean is_running() {
- return async_running;
+ public boolean isRunning() {
+ return mAsyncRunning;
}
/**
@@ -724,24 +731,24 @@ public class ApgCon {
*
*
* This currently resets everything in this instance. Errors, warnings,
- * results, callbacks, ... are removed. Any connection to the remote
+ * mResults, callbacks, ... are removed. Any connection to the remote
* interface is upheld, though.
*
*
*
- * Note, that when an async execution ({@link #call_async(String)}) is
- * running, it's result, warnings etc. will still be evaluated (which might
+ * Note, that when an async execution ({@link #callAsync(String)}) is
+ * running, it's mResult, warnings etc. will still be evaluated (which might
* be not what you want). Also mind, that any callback you set is also
* reseted, so on finishing the execution any before defined callback will
* NOT BE TRIGGERED.
*
*/
public void reset() {
- clear_errors();
- clear_warnings();
- clear_args();
- clear_onCallFinishListener();
- result.clear();
+ clearErrors();
+ clearWarnings();
+ clearArgs();
+ clearOnCallFinishListener();
+ mResult.clear();
}
}
From 0502be76524cee950fb33aa1e687f70caabf4030 Mon Sep 17 00:00:00 2001
From: Markus Doits
Date: Sun, 5 Jun 2011 19:47:41 +0000
Subject: [PATCH 65/69] Documentation update of ApgCon
---
.../thialfihar/android/apg/utils/ApgCon.java | 59 +++++++++++--------
1 file changed, 33 insertions(+), 26 deletions(-)
diff --git a/src/org/thialfihar/android/apg/utils/ApgCon.java b/src/org/thialfihar/android/apg/utils/ApgCon.java
index 0c216b547..475f7e9a9 100644
--- a/src/org/thialfihar/android/apg/utils/ApgCon.java
+++ b/src/org/thialfihar/android/apg/utils/ApgCon.java
@@ -56,6 +56,11 @@ public class ApgCon {
private final static String TAG = "ApgCon";
private final static int API_VERSION = 1; // aidl api-version it expects
+ /**
+ * How many seconds to wait for a connection to AGP when connecting.
+ * Being unsuccessful for this number of seconds, a connection
+ * is assumed to be failed.
+ */
public int secondsToWaitForConnection = 15;
private class CallAsync extends AsyncTask {
@@ -278,12 +283,12 @@ public class ApgCon {
*
*
* After you have set up everything with {@link #setArg(String, String)}
- * (and variants), you can call a function from the AIDL-interface. This
- * will
+ * (and variants), you can call a function of the AIDL-interface. This
+ * will:
*
* - start connection to the remote interface (if not already connected)
- * - call the passed function with all set up parameters synchronously
- * - set up everything to retrieve the mResult and/or warnings/errors
+ * - call the function passed with all parameters synchronously
+ * - set up everything to retrieve the result and/or warnings/errors
* - call the callback if provided
*
*
@@ -317,7 +322,7 @@ public class ApgCon {
}
/**
- * Calls a function from remote interface asynchronously
+ * Calls a function of remote interface asynchronously
*
*
* This does exactly the same as {@link #call(String)}, but asynchronously.
@@ -326,7 +331,7 @@ public class ApgCon {
*
*
*
- * To see whether the task is finished, you have to possibilities:
+ * To see whether the task is finished, you have two possibilities:
*
* - In your thread, poll {@link #isRunning()}
* - Supply a callback with {@link #setOnCallFinishListener(OnCallFinishListener)}
@@ -396,7 +401,7 @@ public class ApgCon {
*
*
*
- * Note, that the parameters are not deleted after a call, so you have to
+ * Note that parameters are not reseted after a call, so you have to
* reset ({@link #clearArgs()}) them manually if you want to.
*
*
@@ -496,10 +501,11 @@ public class ApgCon {
*
*
* Anything the has been set up with the various
- * {@link #setArg(String, String)} functions, is cleared.
+ * {@link #setArg(String, String)} functions is cleared.
*
+ *
*
- * Note, that any warning, error, callback, mResult, etc. is not cleared with
+ * Note that any warning, error, callback, result, etc. is NOT cleared with
* this.
*
*
@@ -524,7 +530,7 @@ public class ApgCon {
* Iterates through the errors
*
*
- * With this method, you can iterate through all errors. The errors are only
+ * With this method you can iterate through all errors. The errors are only
* returned once and deleted immediately afterwards, so you can only return
* each error once.
*
@@ -543,7 +549,7 @@ public class ApgCon {
}
/**
- * Check, if there are any new errors
+ * Check if there are any new errors
*
* @return true, if there are unreturned errors, false otherwise
*
@@ -576,7 +582,7 @@ public class ApgCon {
* Iterates through the warnings
*
*
- * With this method, you can iterate through all warnings. The warnings are
+ * With this method you can iterate through all warnings. Warnings are
* only returned once and deleted immediately afterwards, so you can only
* return each warning once.
*
@@ -595,7 +601,7 @@ public class ApgCon {
}
/**
- * Check, if there are any new warnings
+ * Check if there are any new warnings
*
* @return true, if there are unreturned warnings, false otherwise
*
@@ -609,20 +615,21 @@ public class ApgCon {
* Get the result
*
*
- * This gets your mResult. After doing an encryption or decryption with APG,
+ * This gets your result. After doing an encryption or decryption with APG,
* you get the output with this function.
*
+ *
*
- * Note, that when your last remote call is unsuccessful, the mResult will
+ * Note when your last remote call is unsuccessful, the result will
* still have the same value like the last successful call (or null, if no
- * call was successful). To ensure you do not work with old call's mResults,
+ * call was successful). To ensure you do not work with old call's results,
* either be sure to {@link #reset()} (or at least {@link #clearResult()})
* your instance before each new call or always check that
* {@link #hasNextError()} is false.
*
*
* @return the mResult of the last {@link #call(String)} or
- * {@link #call_asinc(String)}.
+ * {@link #callAsync(String)}.
*
* @see #reset()
* @see #clearResult()
@@ -633,7 +640,7 @@ public class ApgCon {
}
/**
- * Get the mResult bundle
+ * Get the result bundle
*
*
* Unlike {@link #getResult()}, which only returns any en-/decrypted
@@ -645,11 +652,11 @@ public class ApgCon {
* For warnings and errors it is suggested to use the functions that are
* provided here, namely {@link #getError()}, {@link #getNextError()},
* {@link #get_next_Warning()} etc.), but if any call returns something non
- * standard, you have access to the complete mResult bundle to extract the
+ * standard, you have access to the complete result bundle to extract the
* information.
*
*
- * @return the complete mResult-bundle of the last call to apg
+ * @return the complete result bundle of the last call to apg
*/
public Bundle getResultBundle() {
return mResult;
@@ -710,7 +717,7 @@ public class ApgCon {
}
/**
- * Checks, whether an async execution is running
+ * Checks if an async execution is running
*
*
* If you started something with {@link #callAsync(String)}, this will
@@ -731,15 +738,15 @@ public class ApgCon {
*
*
* This currently resets everything in this instance. Errors, warnings,
- * mResults, callbacks, ... are removed. Any connection to the remote
+ * results, callbacks, ... are removed. Any connection to the remote
* interface is upheld, though.
*
*
*
- * Note, that when an async execution ({@link #callAsync(String)}) is
- * running, it's mResult, warnings etc. will still be evaluated (which might
- * be not what you want). Also mind, that any callback you set is also
- * reseted, so on finishing the execution any before defined callback will
+ * Note when an async execution ({@link #callAsync(String)}) is
+ * running, it's result, warnings etc. will still be evaluated (which might
+ * be not what you want). Also mind that any callback you set is also
+ * reseted, so when finishing the execution any before defined callback will
* NOT BE TRIGGERED.
*
*/
From e6c86a88922cfc6570d2c96067155c958aa02ee2 Mon Sep 17 00:00:00 2001
From: Markus Doits
Date: Thu, 3 Nov 2011 22:14:37 +0100
Subject: [PATCH 66/69] Add .gitignore to ignore eclipse-specific files
---
.gitignore | 4 ++++
1 file changed, 4 insertions(+)
create mode 100644 .gitignore
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 000000000..f82656a0e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+bin/
+gen/
+.classpath
+.project
From 8d9b0e1db83f9effa9cb240ad46f1ae2f85df98b Mon Sep 17 00:00:00 2001
From: Markus Doits
Date: Thu, 3 Nov 2011 22:15:31 +0100
Subject: [PATCH 67/69] Switch to spongycastle
https://github.com/rtyley/spongycastle
It replaces bouncycastle2. Looks like a cleaner and better integration. A
precompiled .jar ist in the "lib/"-dir.
---
lib/bcprov-jdk16-146.jar | Bin 0 -> 3759267 bytes
project.properties | 11 ++
src/org/thialfihar/android/apg/Apg.java | 121 +++++++++---------
.../apg/AskForSecretKeyPassPhrase.java | 9 +-
.../android/apg/DecryptActivity.java | 26 ++--
.../android/apg/EditKeyActivity.java | 18 +--
.../android/apg/EncryptActivity.java | 30 ++---
src/org/thialfihar/android/apg/Id.java | 2 +-
.../android/apg/KeyListActivity.java | 26 ++--
.../thialfihar/android/apg/Preferences.java | 8 +-
.../android/apg/PreferencesActivity.java | 12 +-
.../android/apg/PublicKeyListActivity.java | 2 +-
.../android/apg/provider/Database.java | 20 +--
.../android/apg/ui/widget/KeyEditor.java | 16 +--
.../android/apg/ui/widget/SectionView.java | 16 +--
15 files changed, 162 insertions(+), 155 deletions(-)
create mode 100644 lib/bcprov-jdk16-146.jar
create mode 100644 project.properties
diff --git a/lib/bcprov-jdk16-146.jar b/lib/bcprov-jdk16-146.jar
new file mode 100644
index 0000000000000000000000000000000000000000..66cb1a73bf54ab9d8c48d9f423b7267d743caa7f
GIT binary patch
literal 3759267
zcmbTdW3VtymnC|hW81cE+kB2~+qP}nwr$(CZTr4GUr$fpz8y0+CZjUy&&pj3${v0RH|v6dZuzAL#dASn|1l
z;HG~70FeK={|8h?KvqIjL{W)WM$|d3-(rv+UicR9J22*2U?4&h$;(j?Hl!&vMJtlp
zRzaW(k*a;kS2tV`ysdktCtd$^IFCz6`T-a@dsM|t*?wg|djZ6dPr!%=UN*aId1
z$!0OzlQH^dfiz@yWjDB;T7c@^{#Ru;u$^i@onX=?cgh}Kz+xv0u$WS8x
zW;>+T)|QqVE8FdDLEoV{gTb`YGib=l@ltd4QI)vJAbo4%p(C9_hRo@U_n^{2cQvae
zch;>T%BKFmd(_Dz7aWiBLd!LV24cZ#vbhwQT?E?I|R##MZy`lv+#BABp@BXMx_
z*dXh1=H%?4=h$S_lNA21AS^+|dVU1Uv_!*UdJeqsjrfLT{Cwg>&<|Om_WW_^_ja5n
z<={a@*h3JL^`znpA+6FIYt(LpsKn@{
zgyEz23BrWP*3%?6%w#wX8Ze{W5nv9+!ENJBxkK;bgXAe^-{ttGwAsV<@xoC{%x)nZ
zQiu?UiqFAkg_tZ!5#eTpTvRFDlx3zwygtfs&ldF43I@g^vP0#r8GvlzFAPw@Pvb#<
zywgq74Z{H3CK
zAsZ{W(4N5$2^91-L(D=>tTwNp+V>^i@A
z6@ja^ehWEqmTiW<6`HrQFyp>x4L;7<&u?9;m&}uX!^w0SUpLEmf@LO|bMb1N)SM$#
z-R2c(1*C_N?YqFVE|VzQW~7|sS*$U5YZkbGtBmH{e3)3yE@*>n?c{7aatBJ9A=O!L
z;H0`mX%D_!nr$2j8RkMib#xe`7=7SU*hOM$%HGbgxOVWm;8a@2HA>K}5=|~;rqt&V
znbSzIxw2SYc7DXjA8`a77C>vNxXrOZqA^@NS-zJTN>R{^zGySDC|rCbNe1SN^V0JO
z32n3Rtf$0W!uwlM9kYW#8*hvNinUIe@<$T3Gm@QNTC0DHwn65#(K34v#TM-0M;gpBCM=Z12j&NC2_M;7=)r9!P%
zN416*5z)QB={aLx9n^f|dg|aflST2H(^Y4EY;me3*DA$yx-I)|bLzD^trf|TtXT26
zyrL?DuEEs3kp**PD)Q{Ch)H>g8KSx(TMaui)4Q%U+3zi;^n}A~#J?Mn4Pb~=@5
zStA$eAcmp}O-Z|NS`*k#T0AKEanUWc`?~1Kr21E3zL%NJYV2?GY5P|~
zgun4{@jYK=9bCuV+=0Nbh;jSd{(SMtMiMlZRy@{>EzH>Q1m#C^D$3|>E6b{r!}wCT
z;?%pmmtVk+ax;rF3yk+v@Qo*oDO<$Fs0y2Fwl5MUO$p1O
zP;sobR&mWYIB~8Z`63=_G0r|d8O{MY;_SW8xS4VO9vA=Ks4IY9+H*+H%qwui+{A3X
z$+4Nbmm;hyt_CPUlywvvo^=@3)GOHDw5va#X;i9ma|L|_9y_+b4VaXNJ}M|y3I;{@QI3BH4u
z@o+Mu`}A)f3s^S19N0Ec=ZV-Ot3-NCWAS&daXsLenLc-=aRp78V*R;75s8>RxG=70
z=Ww;<=m5I>poG+fqkXpczy95Fp#7Gjpo32Fh;1aqV7`Aa5XHXNj5u|r7S}N#cQcau
zRTA{U2gmH*j*r;ecE`ZiC`oNeWpkYuZ1u5Zwp@R
z$C4$&t0XG!ZN`t=Wdu^xxflIm&6JiYeN}oxFv1j+a=^4A<-qBQk`AT8XWF|VHSJ>~
zFdZm~Pru6uR;Rc5)7A)oGSR4SeSBpU#SZ2}=T5sN=#ES6p$ksGrwcD%
zlvc!y6fZ0i;6~u>`-m~<_<`U>i5GfTjy6=64o||t0A#?%!Pud|4cVpI3;M^s9daMH
z9rH(_9dzI2oqYi60b&jFowzF23sQw5H--fM2II}`wRxQQo*MAT@$Pi|)X+TG^N+sj
zJE2vRS9m3Vjg%}rohj8>a*WD-BkA
zZz59|$6NG*0ZpL$n=<220jS~64teItdJFfBdpg{29kt(i#R{|l)&hD5CGyCUa&B~e
zrGGOj_=f(-Ubk*b#4^~(*|!Ga{FCOTldmS$+jPP?muAbMLF%=kM?dF~dqYg!+p{cq
z=j06dtyD0A=s&XR^!b>u=0ZjHa_9DOv%?Uu1x>w5<%D#L%))$L|D{wN#
zCeROIyQxFOSq={}k^1IV+PDVZ$lo8O7eAWhPkiJ_??pJlC4)L@GBO$6W?buQFjI1NcuI%
z!MNAPteC|}LcZS+V58N4g0KVUlvU~v#_Pdxj99$1n8*l*
z#<5eKUyWuutLFE?Sb67hTOq*jZ<@{Po5Sz!ZJg_{jJ&xg`bh8Hi4%Ef&&Jn#G7^>|
zK;PV!%exYcI!5brMkLAQB2Dqv&hPm_3(LXBXZ?O`W)tBJH%HPOYSpX6-0=PiF`(YQR*&A)Q%&
zZ*sax8@^O2?HMVk9EM|*RTuY{Br8ah*v8^4dfC
ziOWTRM(X2h(Ki|g0q!veHvA!hZVp@>ed+g?2NhJnc6b5fZPem-bLsc<2bYnkE+7Kh
zuHieOqikyK1d3V*Ti3x`8jMHF<8JfURQw_5i6lP39k^P(ref-f1PZ*${=ho+wn;VH
zBcb~|I8XLXy2(Z7Z}2Z=2N6uh7Q}t!ck%(T1P0%BEtFqkziQDi7E2iq(fZN--UK=N
z^W#KtSzZu4v1@a;;c%Wr+;b~yR>;`~uZh!!dA*rl+Vn@9<4Ev(4>}V2o0a}i!Cyu}
z>>|~@*<@&s?60flD#>a&C*p?Hc9A12b=%#ko*&fLfGq&uI-D|23Hxqugh*|G=2AoevZgo8cXfLsE;ai818DoL-Dp{GyoN_E{KNA@eJ
zoNwYp-W5SoZ|JaT?ym9LMuBhA%^%GL`WD;txCD7TsgG9)xq1{{m0-LD?O($edOm_7
z??*?MS6#QW1nCd!2R0RwcTddgk+N8-Yq_BKhgvH>YoRcdC)>C5cCc(3=lj#&|9KSu
z*V+1r7|b~m9sqy{9{_;m|5z0Y{g1Lx!p6?oNzuu{Sl{|zg<-WCjF;l7GoR}1`Q^EU
z52MeTC}Wx}VIa(qvI1b!n%7YO8tz&VJS(*(Ak|s|(RflEtzr3UZIg^-V^tkW6v1*r
zLdzU_VqXI5_u2~0^+t_mtJStbi%*qyr`3823-Gn?jc0=KotaPX^4(1P>z3mz$7`13
zY`3az=gZckaFYi0!09m89PsOuuz))N}0`4dcu
zS7LuFx>shuZiji=y({_`N?@OV=+MW>rbF&t^Fn6`rEI;
z-LAA}w)yX1wJyC|AdY?V>N}}xEdzNTRbQ_nI4ErEU-U}oEXeTJXn(1;w#$>0P)!{h
z^Q{MaDbqbuc)h>UI3~#T@MqRU}ivfmg(RU)L*f^CV4?9_;PXj4h{HW30Ezv2G-SA;GgQ
zWt^im)$wGn?;4AeB=CzZ$z9F@~dunS6HF2iBJub(GVva3?g5
z(XVADSIbaT?XL1Aj1w!gulS=&L)@J0)OCB>N_m=Iu5_EZ+6KUBE|y!-rc7K%!Nd?F
zUqSvExyIsTy}33xfk7pLV=sYel7=B)1l1@7RT5Cf$@Vl&I_dJMlFqyQsAo*K5$Ncy
zz-d>5m4!6g-xlr)4vbCfM~|G#z`c+v@k=*(Dh=H$c4$!-Szs0wb6^RW&&8D>K(G1n
zuaQ2$FIeCMXb>kPZm(em+@ElADs3(5&p1y39_^m8L&pnh`!u`{l!(b|xJt=RTgr$b
zvx-g^Mr}6_wp2Vd8FC_b!LO%bg(mQ!F8>AC*skvpkhZIqDM@I54zNg>Mz>C>w&q;Q
zMV}#A%)+A_voA-HD7rr~vVz9~Ht)x2ceA1*mnouF%^O#NAze%E*b>MFLrR|#hs?Q-
zRF`%Yv>+U;O8=2bhdy;y)^%YLHUUGt?@Vm}Gl`E(PK@Kg98XnJzL2^N+nLfV5&6-e
ziP(-yg`;m&Ib{}?aAj@T1k>JDSmj9drNJ_{3TfXyG$PE$P0<~=44SgNNc!8{(%f86
zN68fa6PQ4jzF}+MPH|K69Z>N~=76PeZ+#vZe)Du9&6(V2G~S(sh0&rV6qqHqb;`Ja
zGI_)*?uwDH5>G2%Yiik^Gv{$wl!7I(2kAdlqL%)rHTvmPlo5i~Qhm~%Yn!ktl9K^V
zUN~lD61;7gTYD+;o%0*lTd)-PdZj$~fb+WWn-hlqjo4do?n_tW$SFcTS5_j&fi4gk
z<|3&?Kl{coPCw3gL*N4@duKXhXLgS~FqR4Zz#J^?m^ypTJd1{NdXEE?j{XfWkdDzU
zzTfoRaSg6G>xP=7K5rw&sfJf&x1qDz()s%@wIe=4ZL0-l$`F)K1c+C7Pu1dJ)tBPd
zw-9J#I6+7zi}#!`?lZ43+eyam>L8J&YDpPf;xhF;x!=rsk
zcA;Ve<)B>e?6;|zU@6a(V@~qcU^NtXU8JVF4bMb%EW;akARLohP`@#*cTT_9Jc`sF
zLwyq31Ms3xD(>nz!vM$PlT^S;16ElTd{SpaR>#+gLs8nnA3r0eqPTuF3*W_<&&GCO
z+ubMeny;$!31US>)9EUVu`-{*Ei7SjnNBNpLPz}DRF+BID(Uqg>JDBjS*66aJnaBQ
ztpKn^E&lBEn0SJ<6C8|~LI6MilS2mwHV6;2YJ9NHY&bI5pdnAIs57aq)tlE1^l@4S
z*2p1<%ouN?d%x&J)}GZ7aoh0FE1!uQ!$NVd+-N4&nTb@5u3f1ypw_Ki2+C}0BmqZi59Ldf3dHl`lIPM`@`I@owg3McQS^0%L{5kNg
z^IITAF9suJ@b3ds)T(oM03PD)5mX|HNZ)b`5Mw4ZNG&O3M2SbyT7=fC#P6iyvHY9H
z&H-8t`&oXpo%`XyY__K%y=&lO1l9qRgdtSq*t!IR3=TpKD`b4J%NFiNY&;o=Cv
zN-GSu$JIkx=^FyAT|{XcDgm947$O5d#xN{Mr`BH*pQD+#Tl1P!r{#@=aZ1QspueYe
zF~XUv%}PSo2o^m-joHtHls`|Cn)-8&U6(Kk{vgoYFO{h+Ar+Ijj2R6WTDf4As%hhcWAsj+(#(az%95@7Hm}_Mg-4dH-!DWtOdm
zY>=?f_GGRgth3BQGtVyP99fe$t1@-n)pvtk1}VS8H?RX6)r;O2=+{W3(>jo+pz=|J
z!BIGbt4Tb}XAc=P&0h}f&`@mXP03Qqvv6=Qsk;S1E%eYCtv}zhOtm&i#^IA2y2F2r
z$!SJ&s8M3yF<0$3Nm5rcy~lC4ye?>ZBxzOJfOQfP)T4;;?J1%eO96b$(bUBr(VoN{
zQ63lJG^?eMk3Em_kf}ZAl$lH}GqEV~%o=E}C}+vsVOUU2!&SV*eh!m|8UC3lL%Z9A
zlw+tErKsC_qRdWss~~>3TAyUt-mH4LF<0`e?#HVf#%N?Plq2%Pw55iX4YwpmJI!RY
zEcJ7iB%
zlc2i9>FaNR>$G%$S4NA7aLWC5C1{UE?mTu3Q1UayYqGO%#uhbsfhnVo#u{axp<2Pw
ztf6)-Y5_>KT?k9=4Z{6k#qwrFqu^^Z+l3OvZj(xWdD+I*N?s<&h&95mUAw_kp*Qk+
z+?5KyyM6*I%aOLD>X
zUE-KkVc~7|<|*B~;mLe4i{@i6xsG4TBKAEshrKNG3sG^*>TA)JZaQ=vg}3~Hta$1f
zzz0pe+~qfIQBkF57^KK?VOT#FS5jcV++dF_`qB5hD6dPP`z8=rUIUxSySZW;Q{k5?
zSr8KaQ3i&gh)mKRUuimK%2KG4d4xe1&z(YE10(R)kCKKND$G6Zcx+pueUFm-!AY_?
zHmN~mX+8k(B^xfdPv#chW!PzvSQc)X!XzAUp^%+&Li7~*uaHSb2oaeUE4~~K$6tVq
z1ZEL92BMG?eh`ho~RHaopIO-G$lbr51_iJ&w@`((->M^+bszH{=w!%nya
z#Bwqu(mE`MPU7AzZOThjYIoFD=@Ra_mbF&?ike_?MF@o^39Pbnq(*lqVO^r4+A(EV
z#$m4DD6*3{3J9VI>6Vik93$L}dnA-^=zJMZ!SEiNt+m5+Hc^{s$6>VIPrV;pe&c)b1^ADP`f-Uoytwx_lU^cODV7+e=g0cD5`;!Cu5AtF(s45ux?MGB9H=XftG-vh
zg1Wy7)HIPhJz~L11Fo^U)-hW^rrfgZ@M5Gce}+O+wn?kuSa33WrObgv_f2IR0uuFI
z3@8OK*=t`P1I29FSgFV(M)GIc-?6PCYX9eznFjUnpz4j9MunAJ
zGdbp$FUgeL0Jp^
z4dKP%Z`h=UXJCQTgL5}bjkORAx6C6}n>m>tmJLZZb`q=Xa*NmgaeCS-GwWJc_bLMw
zE7R$XxrTnJz2+ll-(R6LJYwr?7=5bINfRIKCdZRICLhH^;O*gn7Dltv)n{Pq!M+K@
zmCSV?VmSpd+}j6wY-<+xMI(U%1U=kg6NEL}^wRPOtTZ}AUiqh?J|-WkbOnZK$-
zEl)KjE5@1*sZB>16&x{SGwvTO%$8W{e9*PVgYWI~SWa_k&ta9v{+Kf+;{&X#d7K^h
zsDG0~)#%Hvx$C!AxVR1uQu%hQwtD$DAHxQSugQIHG^sR&XV}bC{ZH)9X5$8Be1m|J
zt8xZ->Zd}Fd37~z2z)~SyvowJUTUh{M3Z9LE{k^k?B?NE4MUMo`IvEiJ0eUHXpi?ddQUf=BRY80JN+)}l8mO%F>_U2=H
z^r$U7`c;$Z+-S+AJ90g$2$yoSo|De7Y`xIQ^Q_46bdcC=kUAzH>Wo79-2b-f%|=1p
zblLao7SL^abj%$Zw1`4vmv9gadS+B0_w;9{aB9G4H7ARk1!xG3O7N(zBVwwdK|Izv
zIr=q0K*}WIz94@8m!4OcEHYE}KdQ#YKa>6cr@A5M?DQY<1~J3G1de3sX~+S3bg6HB
zNAMd2ZnxSS1Z-UHG1#3h@5@HOBx9A$`x`?ncpV;P*TdGO>dAuAbJKz2g_;Ld*cH0fwgp+DaH8^b=1*
zBVCIJ9gmQ%LMnS1(ff*$S-`q#zFP!~Qgpql&cz(p>;b?Eo9H0N>KlwNJMT(g8
zHTXZ?lZ}5S|NqS^D>~^LT8da1|GT!6{Fg^=kRRGxR&X%{eBq&)k-muO0iHog
z@ZxVd&?XB93B@Y0MUD7fZCV`q+n+D;AVuf1jK-PSQ`5m2X9&!&S2Cl%O41
zZ0e&-WDV5vv?(-7)}Xp?o1n@T8Fo{7oR!s+&QRElL!0_efyijSsgLW&%2{!l>tnR4
z*%C^C#Za!M=3;Xp#{<7_zeV0f@DA?ESR%LoBAdOYFMP&g0sv5R0syf7Uu5}TpVhG@
zgqzlId`-^lP8UZp8&Px7d{h+7S{g!>^}3H=9dt{aK;$@kiWPhaeS=sFa09WEog31D
zpI}2f>mP?Tf))h8V|)k`1WESB@elxxF%fY=)>TAQRtO0FSYWH^pXJ+W0`-wNnV#<+
zZSS0mnu~uMH~(CxWF@!0XA5Y7vlw3i{d5>#QUH7EpuLcD
zupTo-zA%5|at<3#F}nKpcG15w`fbs_Qu-q?!(#?9&-eK(kU8H$qGi1{1GVnBKzmK^
z5Ci$>-O_`9x!4}@qJGE%e+`~up?`+(#(yuG-mn?m<9ycOVp6_SnU(=^cVsYF^JQf
zbNVTuWrJ&kF{i=CzNt$$B=f7cm;
zqGjFRwxVe)H#AvwRyMM1EJHz+V8<^tH#Q{Aw=_0EELUoKtG>IUX{=8fsu7zUHCUT+
zRRy8I8+Nu*cGi5>9_cJCyW2pVuH6NCu6ew9gtoQS&z$PN0wz#;>Ko}cdmBx|D&JdlxVBi5a0OUySMr;QHd`yFK5{DO
z$h=J-_gDqUs&4VN>W$3udTmFWH|GRxR}*IZXRNoirCM$-FwE2zy6WGh1w`d`O9+%6
zto%uLdQ`xmpq;hXcY4d=AkbI>85c^;tflW^oS$8+v2H?Z`n_HP^w0FjW%})o#Z6t{
zO-?rGJ9{ksxJ;lq%1x!P%r-;0S_#iP^Sp69dL7+9I|NX1+d6#jBAl~h-0+A_pI-0(
z+Piqq&ftQ>Sl?n`W9l$*Z#6ptm=)R5v~np~6zsLc_xIQI?4R7oj@`q>JXPObY%**`
z>)2dgyH<}i>w%rz?6x2j0nVH(!{w`;0dUmdyhy}EVZiIk!ax#=wtmy8zE1xFh
z{E(mr_{Zyq!dhPNcyH4GM)}Y5;6nSiyd6#Bv%Z?P|IEx#b1NbkhAy2aUN?vs2b7bTw_
z({P1#dN$s+!f2TO<^lul3<=4@fS&7ihH2pXXq)`YT<0crnPRf683h8p&63sXe7utH
zeB;nwXWF(&FsR<&q4|&P4>vMf!@pVxOEiRyWAIv09B!5`bSDBOmIDnpfHck4;u$X8
zsZru~!0zU%x1zG!cUzCI1PWPWG1VFfk1jAL8>m~``a7^|4z=?GLls7Qo1^ctimEf~
ze0qAC%y7l6)<`t%*@Nf=F
z=UFuYrs)P)+tV$_D*%puZ2xB49xH%7>Z)6s
zxo#1cjJ-=(33_{OKl(OqLGLjrp8nGx(A&KXJkvXt8h1bADgl2rs=QAhTDOdM+{1-!
zt=GyYv#_4=rds+ofAtzNXaNzQ>828>NQg%3NmTF;dXDuK_-$df(6hy-ba?OZ9|qx7
z`|nZp6DH~#2vEKvyx=oKt-8>D9goVq5yLc(>tS(8)yweUY3M+b8HjMyn@vv8(}pG6
z`9y*bSZ_Ar-IJ|XfFXCQr&6_Gynlqx*!u;x4f>TGtsS8`idq^8h>6?Av_cr$w$aIl
zz`4!!RznHT*Sy0h5Eg5Wm68|ClR)2=2!+iW9L$q9{>xKsB~3mbLQ@62dk7jA@@>_qdH($Czx78*GhUTtTiS%
z&99Nq4r!K~^J|c^5XTpz{o$y7w&*MD0uXQpSA3825@HfFvS)(bSpH$5Q~*5kemW2z
zV+dYwuQFgfP+o-qU68K}#4pUf)s(%?yFrKJy>Qhw$y&$7*3NUA)-N1dpYF_^y^=d#
zNz|`2$=&KRTo-dn@7m0sS()A25NZ%=$*S2$=
z;?hvuctSe%(yiB8KO;p;n}=@bV8(d
zTU;gmt5N{(A{;_RY6kIl#!{5;M&7P${ZLnkk4YHyDc
zoeu@i@g=gcqpIUhQl1MTDn6OD4il{UxRPQ+eNf{Jmh2Vf>rHdRD(MgIb9td5!G*Y<
zCgv*#qe;aUkbV_PR1@jlWXWiG7*lQL={efmvF{*=1qY4KEato`>!WYL_oDpRNVyR~
zkBJw+hA(8y33Hcr6U_{q`9~TN{7cNugcRnHaV~*Nb~aJ_<(6Vog&0)S%RQWCVC2Z8
z1k$pF<*5K2R7>a91C9it>DUWE(3b;KNpC4kB7Ensu5$618le%T^eCyqEGZ$A
ztO=+g2uPH(^lfy3aLQG1wbJ|2+svyTXqN>1I&R;v+;)+$uS9+e%<9AH%jDk@n`VmZL7OuFD|Mh|0F&uGSiu}
zNH5q!OvbVpyk{bQpksI_GBQX!&aZ>K;l%Dj3|Hd|=3svZoSyNJegj2aW$QBs-PQQJ
z_8VC>K}#c=($581lOC+gS+dJu=M8u53%d`72OvhzJ+W8wTauyDF#C5$KyW_tmyZQy
zqE^mq6we^4sE3Q<@-nmyy78HzJKXCxwZQj^7#gtIhF8Vx#AqipqZ5S_Pc>!U6ecdo
zz5$|nX~@LUwO1y4qK@7=eSN5>2UkH$MU$Wu09$3ij~Al#h_ZOR&z8Sv0FG|uh)!4S
z{G_7%gh=H9RVu~gYfm*shPJUsp&W4uFCU;pOiQiRE`+F_m*|a$U3d*So~99xuD&O}
z&X30>WVJ{1`t71YO~Ht#x5Hv8T@ifaQ!YPFRq#(M@^e4)au%0`hz_tBTI}k^Ikiwx
zgiBJ8KzMJ2is+_w%8sVgJt1ePYamBboIy>+eew&~L~mxpU(h-tYp`z8xxdk0J>*JW
zm>^FgTNeBGKNKzV1dABah&;bz%mj2ih!en}7z{tx5FLRIzQ#}EsHMSS(4a6{Tw7p#
z(PHpK54&h4uS;ksT_xsnhn7JTsr-?ELtFYRvw-RMTtM*tAkOYzPyS$mu0Gu9!0Nci
zR)_eCy2MB?7%6I&cGiy$z=5PysH+y=hg5VTO;GkMqb$EvTpCJ9d9>2x^~cD!l+Gwv
z7UAhWa!(G4#t3mM%Db^}Rl-V8X|^!?+m8w&r)mc@2<|<%tVd!=FJg*gu9Nkw{n!I?
z@=T;%yl#?xovc&7D?6!VR~68vSY#XggqsInU|?P%CX*i!V_F=ZHjDjC_*-oNN6iSE
zs2V18gvK&Lg)FS8JCbwK)C_;1li4jmOnZ&
zX1lf)Ca2hTO1P&pBB#*i!)BLwZxQ^-)aMG=`VM~-AcXF+y6DzqM5)>jses%KL?PI~5F}N|w-w8?4=rSy96KUCj
zDrdO#aA2kR=ghWhNM0Cpn&FXtaHOD)8d3^6Qr{0tkLgbR
z3me;(bZB|OlEr8Zalt7}KsL$zAzEq0JTqI=Xei)xt<-s~8ONn+u;#q3lIx0cZO-yi
z;j~64>f*AfXCX#Py_RL{En;e#ytZO>+bg-MhHcBMxvKoN;~f*Dl5N{ddS&Hv%Znx^
z3aOpTAUPu`(=fTC3Xs`|B~Nt)AcGO~EU`J0>@2E)u)K?K;aZ%9(_vgvnw^4R^?V*m
z^3Ap2bmLF#wJXMuY}}m(Y#