diff options
author | Dominik <dominik@dominikschuermann.de> | 2012-03-22 20:38:50 +0100 |
---|---|---|
committer | Dominik <dominik@dominikschuermann.de> | 2012-06-13 19:28:21 +0300 |
commit | 428a9c539655c17169df2f21ade077d87ce94869 (patch) | |
tree | 1610f73f5badc7247b19deb510f3b67000ac1ec3 | |
parent | ea39b14bf591ca5e49bbcdbb06bcd211a21d018f (diff) | |
download | open-keychain-428a9c539655c17169df2f21ade077d87ce94869.tar.gz open-keychain-428a9c539655c17169df2f21ade077d87ce94869.tar.bz2 open-keychain-428a9c539655c17169df2f21ade077d87ce94869.zip |
Started working on API demo app
17 files changed, 741 insertions, 1 deletions
diff --git a/org_apg/AndroidManifest.xml b/org_apg/AndroidManifest.xml index b96c442fe..1e91eb928 100644 --- a/org_apg/AndroidManifest.xml +++ b/org_apg/AndroidManifest.xml @@ -4,9 +4,11 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="auto" package="org.apg" - android:versionCode="11000" + android:versionCode="50" android:versionName="1.1" > + <!-- APG Plus starting with versionCode 50! --> + <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="14" /> diff --git a/org_apg_api_demo/.gitignore b/org_apg_api_demo/.gitignore new file mode 100644 index 000000000..2e423e1a3 --- /dev/null +++ b/org_apg_api_demo/.gitignore @@ -0,0 +1,23 @@ +#Android generated +bin +gen +obj +libs/armeabi +lint.xml +local.properties + +#Eclipse +.project +.classpath +.settings + +#IntelliJ IDEA +.idea +*.iml + +#Maven +target +release.properties + +#Mac +.DS_Store
\ No newline at end of file diff --git a/org_apg_api_demo/AndroidManifest.xml b/org_apg_api_demo/AndroidManifest.xml new file mode 100644 index 000000000..8e1bb1e25 --- /dev/null +++ b/org_apg_api_demo/AndroidManifest.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="org.apg.api_demo" + android:versionCode="1" + android:versionName="1.0" > + + <uses-sdk + android:minSdkVersion="4" + android:targetSdkVersion="14" /> + + <application + android:icon="@drawable/icon" + android:label="APG API Demo" > + <activity + android:name=".BaseActivity" + android:label="APG API Demo" > + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + <activity + android:name=".IntentDemo1Activity" + android:label="Intent Demo 1" /> + </application> + +</manifest>
\ No newline at end of file diff --git a/org_apg_api_demo/proguard.cfg b/org_apg_api_demo/proguard.cfg new file mode 100644 index 000000000..b1cdf17b5 --- /dev/null +++ b/org_apg_api_demo/proguard.cfg @@ -0,0 +1,40 @@ +-optimizationpasses 5 +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses +-dontpreverify +-verbose +-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class * extends android.app.backup.BackupAgentHelper +-keep public class * extends android.preference.Preference +-keep public class com.android.vending.licensing.ILicensingService + +-keepclasseswithmembernames class * { + native <methods>; +} + +-keepclasseswithmembers class * { + public <init>(android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembers class * { + public <init>(android.content.Context, android.util.AttributeSet, int); +} + +-keepclassmembers class * extends android.app.Activity { + public void *(android.view.View); +} + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} diff --git a/org_apg_api_demo/project.properties b/org_apg_api_demo/project.properties new file mode 100644 index 000000000..8da376af8 --- /dev/null +++ b/org_apg_api_demo/project.properties @@ -0,0 +1,11 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "ant.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-15 diff --git a/org_apg_api_demo/res/drawable-hdpi/icon.png b/org_apg_api_demo/res/drawable-hdpi/icon.png Binary files differnew file mode 100644 index 000000000..d0a519c3e --- /dev/null +++ b/org_apg_api_demo/res/drawable-hdpi/icon.png diff --git a/org_apg_api_demo/res/drawable-ldpi/icon.png b/org_apg_api_demo/res/drawable-ldpi/icon.png Binary files differnew file mode 100644 index 000000000..c3e3a4ee7 --- /dev/null +++ b/org_apg_api_demo/res/drawable-ldpi/icon.png diff --git a/org_apg_api_demo/res/drawable-mdpi/icon.png b/org_apg_api_demo/res/drawable-mdpi/icon.png Binary files differnew file mode 100644 index 000000000..b23eeb8ab --- /dev/null +++ b/org_apg_api_demo/res/drawable-mdpi/icon.png diff --git a/org_apg_api_demo/res/drawable-xhdpi/icon.png b/org_apg_api_demo/res/drawable-xhdpi/icon.png Binary files differnew file mode 100644 index 000000000..52842c4f6 --- /dev/null +++ b/org_apg_api_demo/res/drawable-xhdpi/icon.png diff --git a/org_apg_api_demo/res/layout/intent_demo_1.xml b/org_apg_api_demo/res/layout/intent_demo_1.xml new file mode 100644 index 000000000..fd4712d18 --- /dev/null +++ b/org_apg_api_demo/res/layout/intent_demo_1.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:orientation="vertical" > + + <Button + android:id="@+id/button1" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="send Intent" /> + +</LinearLayout>
\ No newline at end of file diff --git a/org_apg_api_demo/res/xml/base_preference.xml b/org_apg_api_demo/res/xml/base_preference.xml new file mode 100644 index 000000000..aba1ca9bb --- /dev/null +++ b/org_apg_api_demo/res/xml/base_preference.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > + + + <PreferenceCategory android:title="Intent Demos" > + <Preference + android:key="intent_demo_1" + android:title="Intent Demo 1" /> + <Preference + android:key="intent_demo_2" + android:title="Intent Demo 2" /> + </PreferenceCategory> + <PreferenceCategory android:title="AIDL Demos" > + <Preference + android:key="aidl_demo" + android:title="AIDL Demo 1" /> + </PreferenceCategory> + + +</PreferenceScreen>
\ No newline at end of file diff --git a/org_apg_api_demo/src/org/apg/api_demo/BaseActivity.java b/org_apg_api_demo/src/org/apg/api_demo/BaseActivity.java new file mode 100644 index 000000000..8293e3a19 --- /dev/null +++ b/org_apg_api_demo/src/org/apg/api_demo/BaseActivity.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2012 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.apg.api_demo; + +import org.apg.api_demo.R; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.preference.Preference; +import android.preference.Preference.OnPreferenceClickListener; +import android.preference.PreferenceActivity; + +public class BaseActivity extends PreferenceActivity { + private Activity mActivity; + + private Preference mIntentDemo; + + /** + * Called when the activity is first created. + */ + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mActivity = this; + + // load preferences from xml + addPreferencesFromResource(R.xml.base_preference); + + // find preferences + mIntentDemo = (Preference) findPreference("intent_demo_1"); + + mIntentDemo.setOnPreferenceClickListener(new OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + startActivity(new Intent(mActivity, IntentDemo1Activity.class)); + + return false; + } + }); + + } +} diff --git a/org_apg_api_demo/src/org/apg/api_demo/IntentDemo1Activity.java b/org_apg_api_demo/src/org/apg/api_demo/IntentDemo1Activity.java new file mode 100644 index 000000000..a08150b15 --- /dev/null +++ b/org_apg_api_demo/src/org/apg/api_demo/IntentDemo1Activity.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2012 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.apg.api_demo; + +import org.apg.api_demo.R; + +import android.app.Activity; +import android.os.Bundle; + +public class IntentDemo1Activity extends Activity { + Activity mActivity; + + /** + * Instantiate View for this Activity + */ + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.intent_demo_1); + + // org.apg.intent.SELECT_PUBLIC_KEYS + + // get back: + // long[] selectedKeyIds data.putExtra(Apg.EXTRA_SELECTION, selectedKeyIds); + // String[] userIds data.putExtra(Apg.EXTRA_USER_IDS, userIds.toArray(userIdArray)); + + mActivity = this; + } +} diff --git a/org_apg_api_demo/src/org/apg/api_demo/util/Constants.java b/org_apg_api_demo/src/org/apg/api_demo/util/Constants.java new file mode 100644 index 000000000..7047ed788 --- /dev/null +++ b/org_apg_api_demo/src/org/apg/api_demo/util/Constants.java @@ -0,0 +1,70 @@ +package org.apg.api_demo.util; + +import java.util.regex.Pattern; + +import android.net.Uri; + +public class Constants { + public static final String NAME = "apg"; + + public static final String APG_PACKAGE_NAME = "org.apg"; + public static final int MIN_REQUIRED_VERSION = 50; + + public static final String AUTHORITY = "org.apg.provider"; + public static final Uri CONTENT_URI_SECRET_KEY_RING_BY_KEY_ID = Uri.parse("content://" + + AUTHORITY + "/key_rings/secret/key_id/"); + public static final Uri CONTENT_URI_SECRET_KEY_RING_BY_EMAILS = Uri.parse("content://" + + AUTHORITY + "/key_rings/secret/emails/"); + + public static final Uri CONTENT_URI_PUBLIC_KEY_RING_BY_KEY_ID = Uri.parse("content://" + + AUTHORITY + "/key_rings/public/key_id/"); + public static final Uri CONTENT_URI_PUBLIC_KEY_RING_BY_EMAILS = Uri.parse("content://" + + AUTHORITY + "/key_rings/public/emails/"); + + public static class Intent { + public static final String DECRYPT = APG_PACKAGE_NAME + ".intent.DECRYPT"; + public static final String ENCRYPT = APG_PACKAGE_NAME + ".intent.ENCRYPT"; + public static final String DECRYPT_FILE = APG_PACKAGE_NAME + ".intent.DECRYPT_FILE"; + public static final String ENCRYPT_FILE = APG_PACKAGE_NAME + ".intent.ENCRYPT_FILE"; + public static final String DECRYPT_AND_RETURN = APG_PACKAGE_NAME + + ".intent.DECRYPT_AND_RETURN"; + public static final String ENCRYPT_AND_RETURN = APG_PACKAGE_NAME + + ".intent.ENCRYPT_AND_RETURN"; + public static final String SELECT_PUBLIC_KEYS = APG_PACKAGE_NAME + + ".intent.SELECT_PUBLIC_KEYS"; + public static final String SELECT_SECRET_KEY = APG_PACKAGE_NAME + + ".intent.SELECT_SECRET_KEY"; + } + + public static final String EXTRA_TEXT = "text"; + public static final String EXTRA_DATA = "data"; + public static final String EXTRA_ERROR = "error"; + public static final String EXTRA_DECRYPTED_MESSAGE = "decryptedMessage"; + public static final String EXTRA_ENCRYPTED_MESSAGE = "encryptedMessage"; + public static final String EXTRA_SIGNATURE = "signature"; + public static final String EXTRA_SIGNATURE_KEY_ID = "signatureKeyId"; + public static final String EXTRA_SIGNATURE_USER_ID = "signatureUserId"; + public static final String EXTRA_SIGNATURE_SUCCESS = "signatureSuccess"; + public static final String EXTRA_SIGNATURE_UNKNOWN = "signatureUnknown"; + public static final String EXTRA_USER_ID = "userId"; + public static final String EXTRA_KEY_ID = "keyId"; + public static final String EXTRA_ENCRYPTION_KEY_IDS = "encryptionKeyIds"; + public static final String EXTRA_SELECTION = "selection"; + public static final String EXTRA_MESSAGE = "message"; + public static final String EXTRA_INTENT_VERSION = "intentVersion"; + + public static final String INTENT_VERSION = "1"; + + public static final int DECRYPT_MESSAGE = 0x21070001; + public static final int ENCRYPT_MESSAGE = 0x21070002; + public static final int SELECT_PUBLIC_KEYS = 0x21070003; + public static final int SELECT_SECRET_KEY = 0x21070004; + + // public static Pattern PGP_MESSAGE = Pattern.compile( + // ".*?(-----BEGIN PGP MESSAGE-----.*?-----END PGP MESSAGE-----).*", Pattern.DOTALL); + + // public static Pattern PGP_SIGNED_MESSAGE = Pattern + // .compile( + // ".*?(-----BEGIN PGP SIGNED MESSAGE-----.*?-----BEGIN PGP SIGNATURE-----.*?-----END PGP SIGNATURE-----).*", + // Pattern.DOTALL); +} diff --git a/org_apg_api_demo/src/org/apg/api_demo/util/IntentHelper.java b/org_apg_api_demo/src/org/apg/api_demo/util/IntentHelper.java new file mode 100644 index 000000000..769abe924 --- /dev/null +++ b/org_apg_api_demo/src/org/apg/api_demo/util/IntentHelper.java @@ -0,0 +1,216 @@ +package org.apg.api_demo.util; + +import android.app.Activity; +import android.content.ActivityNotFoundException; +import android.content.Intent; +import android.widget.Toast; + +public class IntentHelper { + + /** + * Select the signature key. + * + * @param activity + * @param pgpData + * @return success or failure + */ + public boolean selectSecretKey(Activity activity) { + android.content.Intent intent = new android.content.Intent( + Constants.Intent.SELECT_SECRET_KEY); + intent.putExtra(Constants.EXTRA_INTENT_VERSION, Constants.INTENT_VERSION); + try { + activity.startActivityForResult(intent, Constants.SELECT_SECRET_KEY); + return true; + } catch (ActivityNotFoundException e) { + activityNotFound(activity); + return false; + } + } + + /** + * Start the encrypt activity. + * + * @param activity + * @param data + * @param pgpData + * @return success or failure + */ + public boolean encrypt(Activity activity, String data, long[] encryptionKeyIds, + long signatureKeyId) { + android.content.Intent intent = new android.content.Intent( + Constants.Intent.ENCRYPT_AND_RETURN); + intent.putExtra(Constants.EXTRA_INTENT_VERSION, Constants.INTENT_VERSION); + intent.setType("text/plain"); + intent.putExtra(Constants.EXTRA_TEXT, data); + intent.putExtra(Constants.EXTRA_ENCRYPTION_KEY_IDS, encryptionKeyIds); + intent.putExtra(Constants.EXTRA_SIGNATURE_KEY_ID, signatureKeyId); + try { + activity.startActivityForResult(intent, Constants.ENCRYPT_MESSAGE); + return true; + } catch (ActivityNotFoundException e) { + activityNotFound(activity); + return false; + } + } + + /** + * Start the decrypt activity. + * + * @param activity + * @param data + * @param pgpData + * @return success or failure + */ + public boolean decrypt(Activity activity, String data) { + android.content.Intent intent = new android.content.Intent( + Constants.Intent.DECRYPT_AND_RETURN); + intent.putExtra(Constants.EXTRA_INTENT_VERSION, Constants.INTENT_VERSION); + intent.setType("text/plain"); + if (data == null) { + return false; + } + try { + intent.putExtra(Constants.EXTRA_TEXT, data); + activity.startActivityForResult(intent, Constants.DECRYPT_MESSAGE); + return true; + } catch (ActivityNotFoundException e) { + activityNotFound(activity); + return false; + } + } + + private void activityNotFound(Activity activity) { + Toast.makeText(activity, "APG Activity not found! Is APG installed correctly?", + Toast.LENGTH_LONG).show(); + } + + /** + * Handle the activity results that concern us. + * + * @param activity + * @param requestCode + * @param resultCode + * @param data + * @return handled or not + */ + public boolean onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) { + switch (requestCode) { + case Constants.SELECT_SECRET_KEY: + // if (resultCode != Activity.RESULT_OK || data == null) { + // break; + // } + // pgpData.setSignatureKeyId(data.getLongExtra(Apg.EXTRA_KEY_ID, 0)); + // pgpData.setSignatureUserId(data.getStringExtra(Apg.EXTRA_USER_ID)); + // ((MessageCompose) activity).updateEncryptLayout(); + break; + + case Constants.SELECT_PUBLIC_KEYS: + // if (resultCode != Activity.RESULT_OK || data == null) { + // pgpData.setEncryptionKeys(null); + // ((MessageCompose) activity).onEncryptionKeySelectionDone(); + // break; + // } + // pgpData.setEncryptionKeys(data.getLongArrayExtra(Apg.EXTRA_SELECTION)); + // ((MessageCompose) activity).onEncryptionKeySelectionDone(); + break; + + case Constants.ENCRYPT_MESSAGE: + // if (resultCode != Activity.RESULT_OK || data == null) { + // pgpData.setEncryptionKeys(null); + // ((MessageCompose) activity).onEncryptDone(); + // break; + // } + // pgpData.setEncryptedData(data.getStringExtra(Apg.EXTRA_ENCRYPTED_MESSAGE)); + // // this was a stupid bug in an earlier version, just gonna leave this in for an APG + // // version or two + // if (pgpData.getEncryptedData() == null) { + // pgpData.setEncryptedData(data.getStringExtra(Apg.EXTRA_DECRYPTED_MESSAGE)); + // } + // if (pgpData.getEncryptedData() != null) { + // ((MessageCompose) activity).onEncryptDone(); + // } + break; + + case Constants.DECRYPT_MESSAGE: + if (resultCode != Activity.RESULT_OK || data == null) { + break; + } + + // pgpData.setSignatureUserId(data.getStringExtra(Apg.EXTRA_SIGNATURE_USER_ID)); + // pgpData.setSignatureKeyId(data.getLongExtra(Apg.EXTRA_SIGNATURE_KEY_ID, 0)); + // pgpData.setSignatureSuccess(data.getBooleanExtra(Apg.EXTRA_SIGNATURE_SUCCESS, + // false)); + // pgpData.setSignatureUnknown(data.getBooleanExtra(Apg.EXTRA_SIGNATURE_UNKNOWN, + // false)); + // + // pgpData.setDecryptedData(data.getStringExtra(Apg.EXTRA_DECRYPTED_MESSAGE)); + // ((MessageView) activity).onDecryptDone(pgpData); + + break; + + default: + return false; + } + + return true; + } + + // + // /** + // * Select encryption keys. + // * + // * @param activity + // * @param emails + // * The emails that should be used for preselection. + // * @param pgpData + // * @return success or failure + // */ + // public boolean selectEncryptionKeys(Activity activity, String emails) { + // android.content.Intent intent = new android.content.Intent(Apg.Intent.SELECT_PUBLIC_KEYS); + // intent.putExtra(EXTRA_INTENT_VERSION, INTENT_VERSION); + // long[] initialKeyIds = null; + // if (!pgpData.hasEncryptionKeys()) { + // List<Long> keyIds = new ArrayList<Long>(); + // if (pgpData.hasSignatureKey()) { + // keyIds.add(pgpData.getSignatureKeyId()); + // } + // + // try { + // Uri contentUri = Uri.withAppendedPath(Apg.CONTENT_URI_PUBLIC_KEY_RING_BY_EMAILS, + // emails); + // Cursor c = activity.getContentResolver().query(contentUri, + // new String[] { "master_key_id" }, null, null, null); + // if (c != null) { + // while (c.moveToNext()) { + // keyIds.add(c.getLong(0)); + // } + // } + // + // if (c != null) { + // c.close(); + // } + // } catch (SecurityException e) { + // Toast.makeText(activity, + // activity.getResources().getString(R.string.insufficient_apg_permissions), + // Toast.LENGTH_LONG).show(); + // } + // if (!keyIds.isEmpty()) { + // initialKeyIds = new long[keyIds.size()]; + // for (int i = 0, size = keyIds.size(); i < size; ++i) { + // initialKeyIds[i] = keyIds.get(i); + // } + // } + // } else { + // initialKeyIds = pgpData.getEncryptionKeys(); + // } + // intent.putExtra(Apg.EXTRA_SELECTION, initialKeyIds); + // try { + // activity.startActivityForResult(intent, Apg.SELECT_PUBLIC_KEYS); + // return true; + // } catch (ActivityNotFoundException e) { + // Toast.makeText(activity, R.string.error_activity_not_found, Toast.LENGTH_SHORT).show(); + // return false; + // } + // } + +} diff --git a/org_apg_api_demo/src/org/apg/api_demo/util/ProviderHelper.java b/org_apg_api_demo/src/org/apg/api_demo/util/ProviderHelper.java new file mode 100644 index 000000000..3e4520b7d --- /dev/null +++ b/org_apg_api_demo/src/org/apg/api_demo/util/ProviderHelper.java @@ -0,0 +1,164 @@ +package org.apg.api_demo.util; + +import android.content.ContentUris; +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.widget.Toast; + +public class ProviderHelper { + + /** + * Get secret key ids based on a given email. + * + * @param context + * @param email + * The email in question. + * @return key ids + */ + public long[] getSecretKeyIdsFromEmail(Context context, String email) { + long ids[] = null; + try { + Uri contentUri = Uri.withAppendedPath(Constants.CONTENT_URI_SECRET_KEY_RING_BY_EMAILS, + email); + Cursor c = context.getContentResolver().query(contentUri, + new String[] { "master_key_id" }, null, null, null); + if (c != null && c.getCount() > 0) { + ids = new long[c.getCount()]; + while (c.moveToNext()) { + ids[c.getPosition()] = c.getLong(0); + } + } + + if (c != null) { + c.close(); + } + } catch (SecurityException e) { + insufficientPermissionsInfo(context); + } + + return ids; + } + + /** + * Get public key ids based on a given email. + * + * @param context + * @param email + * The email in question. + * @return key ids + */ + public long[] getPublicKeyIdsFromEmail(Context context, String email) { + long ids[] = null; + try { + Uri contentUri = Uri.withAppendedPath(Constants.CONTENT_URI_PUBLIC_KEY_RING_BY_EMAILS, + email); + Cursor c = context.getContentResolver().query(contentUri, + new String[] { "master_key_id" }, null, null, null); + if (c != null && c.getCount() > 0) { + ids = new long[c.getCount()]; + while (c.moveToNext()) { + ids[c.getPosition()] = c.getLong(0); + } + } + + if (c != null) { + c.close(); + } + } catch (SecurityException e) { + insufficientPermissionsInfo(context); + } + + return ids; + } + + /** + * Find out if a given email has a secret key. + * + * @param context + * @param email + * The email in question. + * @return true if there is a secret key for this email. + */ + public boolean hasSecretKeyForEmail(Context context, String email) { + try { + Uri contentUri = Uri.withAppendedPath(Constants.CONTENT_URI_SECRET_KEY_RING_BY_EMAILS, + email); + Cursor c = context.getContentResolver().query(contentUri, + new String[] { "master_key_id" }, null, null, null); + if (c != null && c.getCount() > 0) { + c.close(); + return true; + } + if (c != null) { + c.close(); + } + } catch (SecurityException e) { + insufficientPermissionsInfo(context); + } + return false; + } + + /** + * Find out if a given email has a public key. + * + * @param context + * @param email + * The email in question. + * @return true if there is a public key for this email. + */ + public boolean hasPublicKeyForEmail(Context context, String email) { + try { + Uri contentUri = Uri.withAppendedPath(Constants.CONTENT_URI_PUBLIC_KEY_RING_BY_EMAILS, + email); + Cursor c = context.getContentResolver().query(contentUri, + new String[] { "master_key_id" }, null, null, null); + if (c != null && c.getCount() > 0) { + c.close(); + return true; + } + if (c != null) { + c.close(); + } + } catch (SecurityException e) { + insufficientPermissionsInfo(context); + } + return false; + } + + /** + * Get the user id based on the key id. + * + * @param context + * @param keyId + * @return user id + */ + public String getUserId(Context context, long keyId) { + String userId = null; + try { + Uri contentUri = ContentUris.withAppendedId( + Constants.CONTENT_URI_SECRET_KEY_RING_BY_KEY_ID, keyId); + Cursor c = context.getContentResolver().query(contentUri, new String[] { "user_id" }, + null, null, null); + if (c != null && c.moveToFirst()) { + userId = c.getString(0); + } + + if (c != null) { + c.close(); + } + } catch (SecurityException e) { + insufficientPermissionsInfo(context); + } + + if (userId == null) { + userId = "unknown"; + } + return userId; + } + + private void insufficientPermissionsInfo(Context context) { + Toast.makeText(context, "Permission to access APG Provider is missing!", Toast.LENGTH_LONG) + .show(); + } +} diff --git a/org_apg_api_demo/src/org/apg/api_demo/util/Util.java b/org_apg_api_demo/src/org/apg/api_demo/util/Util.java new file mode 100644 index 000000000..c698d723e --- /dev/null +++ b/org_apg_api_demo/src/org/apg/api_demo/util/Util.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2010-2011 K9-Mail Contributors + * Copyright (C) 2012 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.apg.api_demo.util; + +import android.content.Context; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager.NameNotFoundException; + +import android.widget.Toast; + +public class Util { + + /** + * Check whether APG is installed and at a high enough version. + * + * @param context + * @return whether a suitable version of APG was found + */ + public boolean isApgAvailable(Context context) { + try { + PackageInfo pi = context.getPackageManager().getPackageInfo(Constants.APG_PACKAGE_NAME, + 0); + if (pi.versionCode >= Constants.MIN_REQUIRED_VERSION) { + return true; + } else { + Toast.makeText(context, + "This APG version is not supported! Please update to a newer one!", + Toast.LENGTH_LONG).show(); + } + } catch (NameNotFoundException e) { + // not found + } + + return false; + } +} |