package org.thialfihar.android.apg.utils;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import android.content.Context;
import android.content.ComponentName;
import android.content.ServiceConnection;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
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.
*
* It is not used in this project.
*/
public class ApgCon {
private class call_async extends AsyncTask
* 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
*
*
*
* 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); else 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; } /** * Returns the type of error happened * ** Currently, two error types are possible: *
* 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); else 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(ret.RESULT.name()); } /** * Clears all unfetched errors * * @see #get_next_error() * @see #has_next_error() */ public void clear_errors() { error_list.clear(); result.remove(ret.ERROR.name()); clear_local_error(); } /** * 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.remove(ret.RESULT.name()); } /** * 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
*/
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;
}
/**
* 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(); clear_args(); clear_callback_object(); clear_callback_method(); result.clear(); } }