diff options
Diffstat (limited to 'OpenPGP-Keychain-API/libraries')
15 files changed, 375 insertions, 250 deletions
| diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/build.gradle b/OpenPGP-Keychain-API/libraries/keychain-api-library/build.gradle index 1d5911783..98c9a3bd6 100644 --- a/OpenPGP-Keychain-API/libraries/keychain-api-library/build.gradle +++ b/OpenPGP-Keychain-API/libraries/keychain-api-library/build.gradle @@ -5,7 +5,7 @@ buildscript {      }      dependencies { -        classpath 'com.android.tools.build:gradle:0.8.3' +        classpath 'com.android.tools.build:gradle:0.9.0'      }  } @@ -13,7 +13,7 @@ apply plugin: 'android-library'  android {      compileSdkVersion 19 -    buildToolsVersion '19.0.1' +    buildToolsVersion '19.0.3'      // NOTE: We are using the old folder structure to also support Eclipse      sourceSets { diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/build.xml b/OpenPGP-Keychain-API/libraries/keychain-api-library/build.xml new file mode 100644 index 000000000..48ebf198c --- /dev/null +++ b/OpenPGP-Keychain-API/libraries/keychain-api-library/build.xml @@ -0,0 +1,92 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project name="keychain-api-library" default="help"> + +    <!-- The local.properties file is created and updated by the 'android' tool. +         It contains the path to the SDK. It should *NOT* be checked into +         Version Control Systems. --> +    <property file="local.properties" /> + +    <!-- The ant.properties file can be created by you. It is only edited by the +         'android' tool to add properties to it. +         This is the place to change some Ant specific build properties. +         Here are some properties you may want to change/update: + +         source.dir +             The name of the source directory. Default is 'src'. +         out.dir +             The name of the output directory. Default is 'bin'. + +         For other overridable properties, look at the beginning of the rules +         files in the SDK, at tools/ant/build.xml + +         Properties related to the SDK location or the project target should +         be updated using the 'android' tool with the 'update' action. + +         This file is an integral part of the build system for your +         application and should be checked into Version Control Systems. + +         --> +    <property file="ant.properties" /> + +    <!-- if sdk.dir was not set from one of the property file, then +         get it from the ANDROID_HOME env var. +         This must be done before we load project.properties since +         the proguard config can use sdk.dir --> +    <property environment="env" /> +    <condition property="sdk.dir" value="${env.ANDROID_HOME}"> +        <isset property="env.ANDROID_HOME" /> +    </condition> + +    <!-- The project.properties file is created and updated by the 'android' +         tool, as well as ADT. + +         This contains project specific properties such as project target, and library +         dependencies. Lower level build properties are stored in ant.properties +         (or in .classpath for Eclipse projects). + +         This file is an integral part of the build system for your +         application and should be checked into Version Control Systems. --> +    <loadproperties srcFile="project.properties" /> + +    <!-- quick check on sdk.dir --> +    <fail +            message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable." +            unless="sdk.dir" +    /> + +    <!-- +        Import per project custom build rules if present at the root of the project. +        This is the place to put custom intermediary targets such as: +            -pre-build +            -pre-compile +            -post-compile (This is typically used for code obfuscation. +                           Compiled code location: ${out.classes.absolute.dir} +                           If this is not done in place, override ${out.dex.input.absolute.dir}) +            -post-package +            -post-build +            -pre-clean +    --> +    <import file="custom_rules.xml" optional="true" /> + +    <!-- Import the actual build file. + +         To customize existing targets, there are two options: +         - Customize only one target: +             - copy/paste the target into this file, *before* the +               <import> task. +             - customize it to your needs. +         - Customize the whole content of build.xml +             - copy/paste the content of the rules files (minus the top node) +               into this file, replacing the <import> task. +             - customize to your needs. + +         *********************** +         ****** IMPORTANT ****** +         *********************** +         In all cases you must update the value of version-tag below to read 'custom' instead of an integer, +         in order to avoid having your file be overridden by tools such as "android update project" +    --> +    <!-- version-tag: 1 --> +    <import file="${sdk.dir}/tools/ant/build.xml" /> + +</project> diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/proguard-project.txt b/OpenPGP-Keychain-API/libraries/keychain-api-library/proguard-project.txt new file mode 100644 index 000000000..f2fe1559a --- /dev/null +++ b/OpenPGP-Keychain-API/libraries/keychain-api-library/proguard-project.txt @@ -0,0 +1,20 @@ +# To enable ProGuard in your project, edit project.properties +# to define the proguard.config property as described in that file. +# +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in ${sdk.dir}/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the ProGuard +# include property in project.properties. +# +# For more details, see +#   http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +#   public *; +#} diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-hdpi/ic_action_cancel_launchersize_light.png b/OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-hdpi/ic_action_cancel_launchersize_light.pngBinary files differ new file mode 100644 index 000000000..73b1d08f3 --- /dev/null +++ b/OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-hdpi/ic_action_cancel_launchersize_light.png diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-mdpi/ic_action_cancel_launchersize_light.png b/OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-mdpi/ic_action_cancel_launchersize_light.pngBinary files differ new file mode 100644 index 000000000..d841821c8 --- /dev/null +++ b/OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-mdpi/ic_action_cancel_launchersize_light.png diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-xhdpi/ic_action_cancel_launchersize_light.png b/OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-xhdpi/ic_action_cancel_launchersize_light.pngBinary files differ new file mode 100644 index 000000000..d505046b4 --- /dev/null +++ b/OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-xhdpi/ic_action_cancel_launchersize_light.png diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-xxhdpi/ic_action_cancel_launchersize_light.png b/OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-xxhdpi/ic_action_cancel_launchersize_light.pngBinary files differ new file mode 100644 index 000000000..d6fb86bdd --- /dev/null +++ b/OpenPGP-Keychain-API/libraries/keychain-api-library/res/drawable-xxhdpi/ic_action_cancel_launchersize_light.png diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/res/values/strings.xml b/OpenPGP-Keychain-API/libraries/keychain-api-library/res/values/strings.xml index a198d0b5e..0119831cc 100644 --- a/OpenPGP-Keychain-API/libraries/keychain-api-library/res/values/strings.xml +++ b/OpenPGP-Keychain-API/libraries/keychain-api-library/res/values/strings.xml @@ -2,5 +2,6 @@  <resources>      <string name="openpgp_list_preference_none">None</string> +    <string name="openpgp_install_openkeychain_via">Install OpenKeychain via %s</string>  </resources>
\ No newline at end of file diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/IOpenPgpService.aidl b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/IOpenPgpService.aidl index 578a7d4b5..7ee79d6ab 100644 --- a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/IOpenPgpService.aidl +++ b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/IOpenPgpService.aidl @@ -18,68 +18,7 @@ package org.openintents.openpgp;  interface IOpenPgpService { -    /** -     * General extras -     * -------------- -     *  -     * Bundle params: -     * int          api_version (required) -     * boolean      ascii_armor (request ascii armor for ouput) -     * -     * returned Bundle: -     * int          result_code (0, 1, or 2 (see OpenPgpConstants)) -     * OpenPgpError error       (if result_code == 0) -     * Intent       intent      (if result_code == 2) -     * -     */ - -    /** -     * Sign only -     * -     * optional params: -     * String       passphrase  (for key passphrase) -     */ -    Bundle sign(in Bundle params, in ParcelFileDescriptor input, in ParcelFileDescriptor output); - -    /** -     * Encrypt -     * -     * Bundle params: -     * long[]       key_ids -     * or -     * String[]     user_ids    (= emails of recipients) (if more than one key has this user_id, a PendingIntent is returned) -     * -     * optional params: -     * String       passphrase  (for key passphrase) -     */ -    Bundle encrypt(in Bundle params, in ParcelFileDescriptor input, in ParcelFileDescriptor output); - -    /** -     * Sign and encrypt -     * -     * Bundle params: -     * same as in encrypt() -     */ -    Bundle signAndEncrypt(in Bundle params, in ParcelFileDescriptor input, in ParcelFileDescriptor output); - -    /** -     * Decrypts and verifies given input bytes. This methods handles encrypted-only, signed-and-encrypted, -     * and also signed-only input. -     * -     * returned Bundle: -     * OpenPgpSignatureResult   signature_result -     */ -    Bundle decryptAndVerify(in Bundle params, in ParcelFileDescriptor input, in ParcelFileDescriptor output); - -    /** -     * Retrieves key ids based on given user ids (=emails) -     * -     * Bundle params: -     * String[]     user_ids -     * -     * returned Bundle: -     * long[]       key_ids -     */ -    Bundle getKeyIds(in Bundle params); +    // see OpenPgpApi for documentation +    Intent execute(in Intent data, in ParcelFileDescriptor input, in ParcelFileDescriptor output);  }
\ No newline at end of file diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/OpenPgpSignatureResult.java b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/OpenPgpSignatureResult.java index 16c79ca27..cb220cf6d 100644 --- a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/OpenPgpSignatureResult.java +++ b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/OpenPgpSignatureResult.java @@ -25,10 +25,8 @@ public class OpenPgpSignatureResult implements Parcelable {      // successfully verified signature, with certified public key      public static final int SIGNATURE_SUCCESS_CERTIFIED = 1;      // no public key was found for this signature verification -    // you can retrieve the key with -    // getKeys(new String[] {String.valueOf(signatureResult.getKeyId)}, true, callback)      public static final int SIGNATURE_UNKNOWN_PUB_KEY = 2; -    // successfully verified signature, but with certified public key +    // successfully verified signature, but with uncertified public key      public static final int SIGNATURE_SUCCESS_UNCERTIFIED = 3;      int status; @@ -40,24 +38,40 @@ public class OpenPgpSignatureResult implements Parcelable {          return status;      } +    public void setStatus(int status) { +        this.status = status; +    } +      public boolean isSignatureOnly() {          return signatureOnly;      } +    public void setSignatureOnly(boolean signatureOnly) { +        this.signatureOnly = signatureOnly; +    } +      public String getUserId() {          return userId;      } +    public void setUserId(String userId) { +        this.userId = userId; +    } +      public long getKeyId() {          return keyId;      } +    public void setKeyId(long keyId) { +        this.keyId = keyId; +    } +      public OpenPgpSignatureResult() {      }      public OpenPgpSignatureResult(int signatureStatus, String signatureUserId, -            boolean signatureOnly, long keyId) { +                                  boolean signatureOnly, long keyId) {          this.status = signatureStatus;          this.signatureOnly = signatureOnly;          this.userId = signatureUserId; diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpApi.java b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpApi.java index f121c345d..f768a1685 100644 --- a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpApi.java +++ b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpApi.java @@ -16,137 +16,213 @@  package org.openintents.openpgp.util; +import android.annotation.TargetApi;  import android.content.Context; +import android.content.Intent;  import android.os.AsyncTask; -import android.os.Bundle; +import android.os.Build;  import android.os.ParcelFileDescriptor;  import android.util.Log; -  import org.openintents.openpgp.IOpenPgpService;  import org.openintents.openpgp.OpenPgpError; -  import java.io.InputStream;  import java.io.OutputStream;  public class OpenPgpApi { +    public static final String TAG = "OpenPgp API"; + +    public static final int API_VERSION = 2; +    public static final String SERVICE_INTENT = "org.openintents.openpgp.IOpenPgpService"; +     +    /** +     * General extras +     * -------------- +     * +     * required extras: +     * int           EXTRA_API_VERSION           (always required) +     * +     * returned extras: +     * int           RESULT_CODE                 (RESULT_CODE_ERROR, RESULT_CODE_SUCCESS or RESULT_CODE_USER_INTERACTION_REQUIRED) +     * OpenPgpError  RESULT_ERROR                (if RESULT_CODE == RESULT_CODE_ERROR) +     * PendingIntent RESULT_INTENT               (if RESULT_CODE == RESULT_CODE_USER_INTERACTION_REQUIRED) +     */ + +    /** +     * Sign only +     * +     * optional extras: +     * boolean       EXTRA_REQUEST_ASCII_ARMOR   (request ascii armor for ouput) +     * String        EXTRA_PASSPHRASE            (key passphrase) +     */ +    public static final String ACTION_SIGN = "org.openintents.openpgp.action.SIGN"; + +    /** +     * Encrypt +     * +     * required extras: +     * String[]      EXTRA_USER_IDS              (=emails of recipients, if more than one key has a user_id, a PendingIntent is returned via RESULT_INTENT) +     * or +     * long[]        EXTRA_KEY_IDS +     * +     * optional extras: +     * boolean       EXTRA_REQUEST_ASCII_ARMOR   (request ascii armor for ouput) +     * String        EXTRA_PASSPHRASE            (key passphrase) +     */ +    public static final String ACTION_ENCRYPT = "org.openintents.openpgp.action.ENCRYPT"; + +    /** +     * Sign and encrypt +     * +     * required extras: +     * String[]      EXTRA_USER_IDS              (=emails of recipients, if more than one key has a user_id, a PendingIntent is returned via RESULT_INTENT) +     * or +     * long[]        EXTRA_KEY_IDS +     * +     * optional extras: +     * boolean       EXTRA_REQUEST_ASCII_ARMOR   (request ascii armor for ouput) +     * String        EXTRA_PASSPHRASE            (key passphrase) +     */ +    public static final String ACTION_SIGN_AND_ENCRYPT = "org.openintents.openpgp.action.SIGN_AND_ENCRYPT"; + +    /** +     * Decrypts and verifies given input stream. This methods handles encrypted-only, signed-and-encrypted, +     * and also signed-only input. +     * +     * If OpenPgpSignatureResult.getStatus() == OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY +     * in addition a PendingIntent is returned via RESULT_INTENT to download missing keys. +     * +     * optional extras: +     * boolean       EXTRA_REQUEST_ASCII_ARMOR   (request ascii armor for ouput) +     * +     * returned extras: +     * OpenPgpSignatureResult   RESULT_SIGNATURE +     */ +    public static final String ACTION_DECRYPT_VERIFY = "org.openintents.openpgp.action.DECRYPT_VERIFY"; + +    /** +     * Get key ids based on given user ids (=emails) +     * +     * required extras: +     * String[]      EXTRA_USER_IDS +     * +     * returned extras: +     * long[]        EXTRA_KEY_IDS +     */ +    public static final String ACTION_GET_KEY_IDS = "org.openintents.openpgp.action.GET_KEY_IDS"; + +    /** +     * This action returns RESULT_CODE_SUCCESS if the OpenPGP Provider already has the key +     * corresponding to the given key id in its database. +     * +     * It returns RESULT_CODE_USER_INTERACTION_REQUIRED if the Provider does not have the key. +     * The PendingIntent from RESULT_INTENT can be used to retrieve those from a keyserver. +     * +     * required extras: +     * long        EXTRA_KEY_ID +     */ +    public static final String ACTION_GET_KEY = "org.openintents.openpgp.action.GET_KEY"; + +    /* Intent extras */ +    public static final String EXTRA_API_VERSION = "api_version"; + +    // SIGN, ENCRYPT, SIGN_AND_ENCRYPT, DECRYPT_VERIFY +    // request ASCII Armor for output +    // OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53) +    public static final String EXTRA_REQUEST_ASCII_ARMOR = "ascii_armor"; + +    // ENCRYPT, SIGN_AND_ENCRYPT +    public static final String EXTRA_USER_IDS = "user_ids"; +    public static final String EXTRA_KEY_IDS = "key_ids"; +    // optional extras: +    public static final String EXTRA_PASSPHRASE = "passphrase"; + +    // GET_KEY +    public static final String EXTRA_KEY_ID = "key_id"; + +    /* Service Intent returns */ +    public static final String RESULT_CODE = "result_code"; + +    // get actual error object from RESULT_ERROR +    public static final int RESULT_CODE_ERROR = 0; +    // success! +    public static final int RESULT_CODE_SUCCESS = 1; +    // get PendingIntent from RESULT_INTENT, start PendingIntent with startIntentSenderForResult, +    // and execute service method again in onActivityResult +    public static final int RESULT_CODE_USER_INTERACTION_REQUIRED = 2; + +    public static final String RESULT_ERROR = "error"; +    public static final String RESULT_INTENT = "intent"; + +    // DECRYPT_VERIFY +    public static final String RESULT_SIGNATURE = "signature"; +      IOpenPgpService mService;      Context mContext; -    private static final int OPERATION_SIGN = 0; -    private static final int OPERATION_ENCRYPT = 1; -    private static final int OPERATION_SIGN_ENCRYPT = 2; -    private static final int OPERATION_DECRYPT_VERIFY = 3; -    private static final int OPERATION_GET_KEY_IDS = 4; -      public OpenPgpApi(Context context, IOpenPgpService service) {          this.mContext = context;          this.mService = service;      } -    public Bundle sign(InputStream is, final OutputStream os) { -        return executeApi(OPERATION_SIGN, new Bundle(), is, os); -    } - -    public Bundle sign(Bundle params, InputStream is, final OutputStream os) { -        return executeApi(OPERATION_SIGN, params, is, os); -    } - -    public void sign(Bundle params, InputStream is, final OutputStream os, IOpenPgpCallback callback) { -        executeApiAsync(OPERATION_SIGN, params, is, os, callback); -    } - -    public Bundle encrypt(InputStream is, final OutputStream os) { -        return executeApi(OPERATION_ENCRYPT, new Bundle(), is, os); -    } - -    public Bundle encrypt(Bundle params, InputStream is, final OutputStream os) { -        return executeApi(OPERATION_ENCRYPT, params, is, os); -    } - -    public void encrypt(Bundle params, InputStream is, final OutputStream os, IOpenPgpCallback callback) { -        executeApiAsync(OPERATION_ENCRYPT, params, is, os, callback); -    } - -    public Bundle signAndEncrypt(InputStream is, final OutputStream os) { -        return executeApi(OPERATION_SIGN_ENCRYPT, new Bundle(), is, os); -    } - -    public Bundle signAndEncrypt(Bundle params, InputStream is, final OutputStream os) { -        return executeApi(OPERATION_SIGN_ENCRYPT, params, is, os); -    } - -    public void signAndEncrypt(Bundle params, InputStream is, final OutputStream os, IOpenPgpCallback callback) { -        executeApiAsync(OPERATION_SIGN_ENCRYPT, params, is, os, callback); -    } - -    public Bundle decryptAndVerify(InputStream is, final OutputStream os) { -        return executeApi(OPERATION_DECRYPT_VERIFY, new Bundle(), is, os); -    } - -    public Bundle decryptAndVerify(Bundle params, InputStream is, final OutputStream os) { -        return executeApi(OPERATION_DECRYPT_VERIFY, params, is, os); -    } - -    public void decryptAndVerify(Bundle params, InputStream is, final OutputStream os, IOpenPgpCallback callback) { -        executeApiAsync(OPERATION_DECRYPT_VERIFY, params, is, os, callback); -    } - -    public Bundle getKeyIds(Bundle params) { -        return executeApi(OPERATION_GET_KEY_IDS, params, null, null); -    } -      public interface IOpenPgpCallback { -        void onReturn(final Bundle result); +        void onReturn(final Intent result);      } -    private class OpenPgpAsyncTask extends AsyncTask<Void, Integer, Bundle> { -        int operationId; -        Bundle params; +    private class OpenPgpAsyncTask extends AsyncTask<Void, Integer, Intent> { +        Intent data;          InputStream is;          OutputStream os;          IOpenPgpCallback callback; -        private OpenPgpAsyncTask(int operationId, Bundle params, InputStream is, OutputStream os, IOpenPgpCallback callback) { -            this.operationId = operationId; -            this.params = params; +        private OpenPgpAsyncTask(Intent data, InputStream is, OutputStream os, IOpenPgpCallback callback) { +            this.data = data;              this.is = is;              this.os = os;              this.callback = callback;          }          @Override -        protected Bundle doInBackground(Void... unused) { -            return executeApi(operationId, params, is, os); +        protected Intent doInBackground(Void... unused) { +            return executeApi(data, is, os);          } -        protected void onPostExecute(Bundle result) { +        protected void onPostExecute(Intent result) {              callback.onReturn(result);          }      } -    private void executeApiAsync(int operationId, Bundle params, InputStream is, OutputStream os, IOpenPgpCallback callback) { -        new OpenPgpAsyncTask(operationId, params, is, os, callback).execute((Void[]) null); +    @TargetApi(Build.VERSION_CODES.HONEYCOMB) +    public void executeApiAsync(Intent data, InputStream is, OutputStream os, IOpenPgpCallback callback) { +        OpenPgpAsyncTask task = new OpenPgpAsyncTask(data, is, os, callback); + +        // don't serialize async tasks! +        // http://commonsware.com/blog/2012/04/20/asynctask-threading-regression-confirmed.html +        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { +            task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null); +        } else { +            task.execute((Void[]) null); +        }      } -    private Bundle executeApi(int operationId, Bundle params, InputStream is, OutputStream os) { +    public Intent executeApi(Intent data, InputStream is, OutputStream os) {          try { -            params.putInt(OpenPgpConstants.PARAMS_API_VERSION, OpenPgpConstants.API_VERSION); +            data.putExtra(EXTRA_API_VERSION, OpenPgpApi.API_VERSION); -            Bundle result = null; +            Intent result = null; -            if (operationId == OPERATION_GET_KEY_IDS) { -                result = mService.getKeyIds(params); +            if (ACTION_GET_KEY_IDS.equals(data.getAction())) { +                result = mService.execute(data, null, null);                  return result;              } else { -                // send the input and output pfds +                // pipe the input and output                  ParcelFileDescriptor input = ParcelFileDescriptorUtil.pipeFrom(is,                          new ParcelFileDescriptorUtil.IThreadListener() {                              @Override                              public void onThreadFinished(Thread thread) { -                                Log.d(OpenPgpConstants.TAG, "Copy to service finished"); +                                //Log.d(OpenPgpApi.TAG, "Copy to service finished");                              }                          });                  ParcelFileDescriptor output = ParcelFileDescriptorUtil.pipeTo(os, @@ -154,45 +230,30 @@ public class OpenPgpApi {                              @Override                              public void onThreadFinished(Thread thread) { -                                Log.d(OpenPgpConstants.TAG, "Service finished writing!"); +                                //Log.d(OpenPgpApi.TAG, "Service finished writing!");                              }                          }); -                  // blocks until result is ready -                switch (operationId) { -                    case OPERATION_SIGN: -                        result = mService.sign(params, input, output); -                        break; -                    case OPERATION_ENCRYPT: -                        result = mService.encrypt(params, input, output); -                        break; -                    case OPERATION_SIGN_ENCRYPT: -                        result = mService.signAndEncrypt(params, input, output); -                        break; -                    case OPERATION_DECRYPT_VERIFY: -                        result = mService.decryptAndVerify(params, input, output); -                        break; -                } +                result = mService.execute(data, input, output);                  // close() is required to halt the TransferThread                  output.close();                  // set class loader to current context to allow unparcelling                  // of OpenPgpError and OpenPgpSignatureResult                  // http://stackoverflow.com/a/3806769 -                result.setClassLoader(mContext.getClassLoader()); +                result.setExtrasClassLoader(mContext.getClassLoader());                  return result;              }          } catch (Exception e) { -            Log.e(OpenPgpConstants.TAG, "Exception", e); -            Bundle result = new Bundle(); -            result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR); -            result.putParcelable(OpenPgpConstants.RESULT_ERRORS, +            Log.e(OpenPgpApi.TAG, "Exception", e); +            Intent result = new Intent(); +            result.putExtra(RESULT_CODE, RESULT_CODE_ERROR); +            result.putExtra(RESULT_ERROR,                      new OpenPgpError(OpenPgpError.CLIENT_SIDE_ERROR, e.getMessage()));              return result;          }      } -  } diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpConstants.java b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpConstants.java deleted file mode 100644 index 263b42aaa..000000000 --- a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpConstants.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - *      http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.openintents.openpgp.util; - -public class OpenPgpConstants { - -    public static final String TAG = "OpenPgp API"; - -    public static final int API_VERSION = 1; -    public static final String SERVICE_INTENT = "org.openintents.openpgp.IOpenPgpService"; - - -    /* Bundle params */ -    public static final String PARAMS_API_VERSION = "api_version"; -    // request ASCII Armor for output -    // OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53) -    public static final String PARAMS_REQUEST_ASCII_ARMOR = "ascii_armor"; -    // (for encrypt method) -    public static final String PARAMS_USER_IDS = "user_ids"; -    public static final String PARAMS_KEY_IDS = "key_ids"; -    // optional parameter: -    public static final String PARAMS_PASSPHRASE = "passphrase"; - -    /* Service Bundle returns */ -    public static final String RESULT_CODE = "result_code"; -    public static final String RESULT_SIGNATURE = "signature"; -    public static final String RESULT_ERRORS = "error"; -    public static final String RESULT_INTENT = "intent"; - -    // get actual error object from RESULT_ERRORS -    public static final int RESULT_CODE_ERROR = 0; -    // success! -    public static final int RESULT_CODE_SUCCESS = 1; -    // executeServiceMethod intent and do it again with params from intent -    public static final int RESULT_CODE_USER_INTERACTION_REQUIRED = 2; - -    /* PendingIntent returns */ -    public static final String PI_RESULT_PARAMS = "params"; - -} diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpListPreference.java b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpListPreference.java index 034186a3a..ecc2b8ec1 100644 --- a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpListPreference.java +++ b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpListPreference.java @@ -23,6 +23,7 @@ import android.content.Intent;  import android.content.pm.ResolveInfo;  import android.content.res.TypedArray;  import android.graphics.drawable.Drawable; +import android.net.Uri;  import android.preference.DialogPreference;  import android.util.AttributeSet;  import android.view.View; @@ -30,18 +31,24 @@ import android.view.ViewGroup;  import android.widget.ArrayAdapter;  import android.widget.ListAdapter;  import android.widget.TextView; +import org.sufficientlysecure.keychain.api.R;  import java.util.ArrayList;  import java.util.List; -import org.sufficientlysecure.keychain.api.R; -  /**   * Does not extend ListPreference, but is very similar to it!   * http://grepcode.com/file_/repository.grepcode.com/java/ext/com.google.android/android/4.4_r1/android/preference/ListPreference.java/?v=source   */  public class OpenPgpListPreference extends DialogPreference { -    private ArrayList<OpenPgpProviderEntry> mProviderList = new ArrayList<OpenPgpProviderEntry>(); +    private static final String OPENKEYCHAIN_PACKAGE = "org.sufficientlysecure.keychain"; +    private static final String MARKET_INTENT_URI_BASE = "market://details?id=%s"; +    private static final Intent MARKET_INTENT = new Intent(Intent.ACTION_VIEW, Uri.parse( +            String.format(MARKET_INTENT_URI_BASE, OPENKEYCHAIN_PACKAGE))); + +    private ArrayList<OpenPgpProviderEntry> mLegacyList = new ArrayList<OpenPgpProviderEntry>(); +    private ArrayList<OpenPgpProviderEntry> mList = new ArrayList<OpenPgpProviderEntry>(); +      private String mSelectedPackage;      public OpenPgpListPreference(Context context, AttributeSet attrs) { @@ -59,16 +66,25 @@ public class OpenPgpListPreference extends DialogPreference {       * @param simpleName       * @param icon       */ -    public void addProvider(int position, String packageName, String simpleName, Drawable icon) { -        mProviderList.add(position, new OpenPgpProviderEntry(packageName, simpleName, icon)); +    public void addLegacyProvider(int position, String packageName, String simpleName, Drawable icon) { +        mLegacyList.add(position, new OpenPgpProviderEntry(packageName, simpleName, icon));      }      @Override      protected void onPrepareDialogBuilder(Builder builder) { - -        // get providers -        mProviderList.clear(); -        Intent intent = new Intent(OpenPgpConstants.SERVICE_INTENT); +        mList.clear(); +         +        // add "none"-entry +        mList.add(0, new OpenPgpProviderEntry("", +                getContext().getString(R.string.openpgp_list_preference_none), +                getContext().getResources().getDrawable(R.drawable.ic_action_cancel_launchersize))); +         +        // add all additional (legacy) providers +        mList.addAll(mLegacyList); +         +        // search for OpenPGP providers... +        ArrayList<OpenPgpProviderEntry> providerList = new ArrayList<OpenPgpProviderEntry>(); +        Intent intent = new Intent(OpenPgpApi.SERVICE_INTENT);          List<ResolveInfo> resInfo = getContext().getPackageManager().queryIntentServices(intent, 0);          if (!resInfo.isEmpty()) {              for (ResolveInfo resolveInfo : resInfo) { @@ -80,25 +96,40 @@ public class OpenPgpListPreference extends DialogPreference {                          .getPackageManager()));                  Drawable icon = resolveInfo.serviceInfo.loadIcon(getContext().getPackageManager()); -                mProviderList.add(new OpenPgpProviderEntry(packageName, simpleName, icon)); +                providerList.add(new OpenPgpProviderEntry(packageName, simpleName, icon));              }          } -        // add "none"-entry -        mProviderList.add(0, new OpenPgpProviderEntry("", -                getContext().getString(R.string.openpgp_list_preference_none), -                getContext().getResources().getDrawable(R.drawable.ic_action_cancel_launchersize))); +        if (providerList.isEmpty()) { +            // add install links if provider list is empty +            resInfo = getContext().getPackageManager().queryIntentActivities +                    (MARKET_INTENT, 0); +            for (ResolveInfo resolveInfo : resInfo) { +                Intent marketIntent = new Intent(MARKET_INTENT); +                marketIntent.setPackage(resolveInfo.activityInfo.packageName); +                Drawable icon = resolveInfo.activityInfo.loadIcon(getContext().getPackageManager()); +                String marketName = String.valueOf(resolveInfo.activityInfo.applicationInfo +                        .loadLabel(getContext().getPackageManager())); +                String simpleName = String.format(getContext().getString(R.string +                        .openpgp_install_openkeychain_via), marketName); +                mList.add(new OpenPgpProviderEntry(OPENKEYCHAIN_PACKAGE, simpleName, +                        icon, marketIntent)); +            } +        } else { +            // add provider +            mList.addAll(providerList); +        }          // Init ArrayAdapter with OpenPGP Providers          ListAdapter adapter = new ArrayAdapter<OpenPgpProviderEntry>(getContext(), -                android.R.layout.select_dialog_singlechoice, android.R.id.text1, mProviderList) { +                android.R.layout.select_dialog_singlechoice, android.R.id.text1, mList) {              public View getView(int position, View convertView, ViewGroup parent) {                  // User super class to create the View                  View v = super.getView(position, convertView, parent);                  TextView tv = (TextView) v.findViewById(android.R.id.text1);                  // Put the image on the TextView -                tv.setCompoundDrawablesWithIntrinsicBounds(mProviderList.get(position).icon, null, +                tv.setCompoundDrawablesWithIntrinsicBounds(mList.get(position).icon, null,                          null, null);                  // Add margin between image and text (support various screen densities) @@ -114,7 +145,22 @@ public class OpenPgpListPreference extends DialogPreference {                      @Override                      public void onClick(DialogInterface dialog, int which) { -                        mSelectedPackage = mProviderList.get(which).packageName; +                        OpenPgpProviderEntry entry = mList.get(which); + +                        if (entry.intent != null) { +                            /* +                             * Intents are called as activity +                             * +                             * Current approach is to assume the user installed the app. +                             * If he does not, the selected package is not valid. +                             * +                             * However  applications should always consider this could happen, +                             * as the user might remove the currently used OpenPGP app. +                             */ +                            getContext().startActivity(entry.intent); +                        } + +                        mSelectedPackage = entry.packageName;                          /*                           * Clicking on an item simulates the positive button click, and dismisses @@ -144,9 +190,9 @@ public class OpenPgpListPreference extends DialogPreference {      }      private int getIndexOfProviderList(String packageName) { -        for (OpenPgpProviderEntry app : mProviderList) { +        for (OpenPgpProviderEntry app : mList) {              if (app.packageName.equals(packageName)) { -                return mProviderList.indexOf(app); +                return mList.indexOf(app);              }          } @@ -177,7 +223,7 @@ public class OpenPgpListPreference extends DialogPreference {      }      public String getEntryByValue(String packageName) { -        for (OpenPgpProviderEntry app : mProviderList) { +        for (OpenPgpProviderEntry app : mList) {              if (app.packageName.equals(packageName)) {                  return app.simpleName;              } @@ -190,6 +236,7 @@ public class OpenPgpListPreference extends DialogPreference {          private String packageName;          private String simpleName;          private Drawable icon; +        private Intent intent;          public OpenPgpProviderEntry(String packageName, String simpleName, Drawable icon) {              this.packageName = packageName; @@ -197,6 +244,11 @@ public class OpenPgpListPreference extends DialogPreference {              this.icon = icon;          } +        public OpenPgpProviderEntry(String packageName, String simpleName, Drawable icon, Intent intent) { +            this(packageName, simpleName, icon); +            this.intent = intent; +        } +          @Override          public String toString() {              return simpleName; diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpUtils.java b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpUtils.java index ffecaceba..67fe86291 100644 --- a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpUtils.java +++ b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpUtils.java @@ -52,7 +52,7 @@ public class OpenPgpUtils {      }      public static boolean isAvailable(Context context) { -        Intent intent = new Intent(OpenPgpConstants.SERVICE_INTENT); +        Intent intent = new Intent(OpenPgpApi.SERVICE_INTENT);          List<ResolveInfo> resInfo = context.getPackageManager().queryIntentServices(intent, 0);          if (!resInfo.isEmpty()) {              return true; diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/ParcelFileDescriptorUtil.java b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/ParcelFileDescriptorUtil.java index 3569caf5b..58c62110d 100644 --- a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/ParcelFileDescriptorUtil.java +++ b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/ParcelFileDescriptorUtil.java @@ -81,21 +81,21 @@ public class ParcelFileDescriptorUtil {                  }                  mOut.flush(); // just to be safe              } catch (IOException e) { -                //Log.e(OpenPgpConstants.TAG, "TransferThread" + getId() + ": writing failed", e); +                //Log.e(OpenPgpApi.TAG, "TransferThread" + getId() + ": writing failed", e);              } finally {                  try {                      mIn.close();                  } catch (IOException e) { -                    //Log.e(OpenPgpConstants.TAG, "TransferThread" + getId(), e); +                    //Log.e(OpenPgpApi.TAG, "TransferThread" + getId(), e);                  }                  try {                      mOut.close();                  } catch (IOException e) { -                    //Log.e(OpenPgpConstants.TAG, "TransferThread" + getId(), e); +                    //Log.e(OpenPgpApi.TAG, "TransferThread" + getId(), e);                  }              }              if (mListener != null) { -                //Log.d(OpenPgpConstants.TAG, "TransferThread " + getId() + " finished!"); +                //Log.d(OpenPgpApi.TAG, "TransferThread " + getId() + " finished!");                  mListener.onThreadFinished(this);              }          } | 
