diff options
79 files changed, 1335 insertions, 520 deletions
diff --git a/OpenPGP-Keychain-API/libraries/openpgp-api-library/src/org/openintents/openpgp/util/OpenPgpApi.java b/OpenPGP-Keychain-API/libraries/openpgp-api-library/src/org/openintents/openpgp/util/OpenPgpApi.java index f768a1685..c59590fec 100644 --- a/OpenPGP-Keychain-API/libraries/openpgp-api-library/src/org/openintents/openpgp/util/OpenPgpApi.java +++ b/OpenPGP-Keychain-API/libraries/openpgp-api-library/src/org/openintents/openpgp/util/OpenPgpApi.java @@ -126,6 +126,8 @@ public class OpenPgpApi { /* Intent extras */ public static final String EXTRA_API_VERSION = "api_version"; + public static final String EXTRA_ACCOUNT_NAME = "account_name"; + // 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) diff --git a/OpenPGP-Keychain/src/main/AndroidManifest.xml b/OpenPGP-Keychain/src/main/AndroidManifest.xml index b1fbcf555..3ab39280e 100644 --- a/OpenPGP-Keychain/src/main/AndroidManifest.xml +++ b/OpenPGP-Keychain/src/main/AndroidManifest.xml @@ -384,24 +384,24 @@ <!-- Internal classes of the remote APIs (not exported) --> <activity - android:name="org.sufficientlysecure.keychain.service.remote.RemoteServiceActivity" + android:name="org.sufficientlysecure.keychain.remote.ui.RemoteServiceActivity" android:exported="false" android:label="@string/app_name" /> <!--android:launchMode="singleTop"--> <!--android:process=":remote_api"--> <activity - android:name="org.sufficientlysecure.keychain.service.remote.RegisteredAppsListActivity" + android:name=".remote.ui.AppsListActivity" android:configChanges="orientation|screenSize|keyboardHidden|keyboard" android:exported="false" android:label="@string/title_api_registered_apps" /> <activity - android:name="org.sufficientlysecure.keychain.service.remote.AppSettingsActivity" + android:name="org.sufficientlysecure.keychain.remote.ui.AppSettingsActivity" android:configChanges="orientation|screenSize|keyboardHidden|keyboard" android:exported="false" /> <!-- OpenPGP Remote API --> <service - android:name="org.sufficientlysecure.keychain.service.remote.OpenPgpService" + android:name="org.sufficientlysecure.keychain.remote.OpenPgpService" android:enabled="true" android:exported="true" android:process=":remote_api"> diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java index ff4abe56a..f9a7962ec 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java @@ -19,7 +19,7 @@ package org.sufficientlysecure.keychain; import android.os.Environment; import org.spongycastle.jce.provider.BouncyCastleProvider; -import org.sufficientlysecure.keychain.service.remote.RegisteredAppsListActivity; +import org.sufficientlysecure.keychain.remote.ui.AppsListActivity; import org.sufficientlysecure.keychain.ui.DecryptActivity; import org.sufficientlysecure.keychain.ui.EncryptActivity; import org.sufficientlysecure.keychain.ui.ImportKeysActivity; @@ -73,7 +73,7 @@ public final class Constants { public static final Class ENCRYPT = EncryptActivity.class; public static final Class DECRYPT = DecryptActivity.class; public static final Class IMPORT_KEYS = ImportKeysActivity.class; - public static final Class REGISTERED_APPS_LIST = RegisteredAppsListActivity.class; + public static final Class REGISTERED_APPS_LIST = AppsListActivity.class; public static final Class[] ARRAY = new Class[]{KEY_LIST, ENCRYPT, DECRYPT, IMPORT_KEYS, REGISTERED_APPS_LIST}; } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java index 2bfa796c7..cc240a67b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java @@ -139,7 +139,7 @@ public class ExportHelper { intent.putExtra(KeychainIntentService.EXTRA_DATA, data); - // Message is received after exporting is done in ApgService + // Message is received after exporting is done in KeychainIntentService KeychainIntentServiceHandler exportHandler = new KeychainIntentServiceHandler(mActivity, mActivity.getString(R.string.progress_exporting), ProgressDialog.STYLE_HORIZONTAL, @@ -151,7 +151,7 @@ public class ExportHelper { } }) { public void handleMessage(Message message) { - // handle messages by standard ApgHandler first + // handle messages by standard KeychainIntentServiceHandler first super.handleMessage(message); if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java index 5f2354c24..6e4899fc2 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java @@ -19,6 +19,7 @@ package org.sufficientlysecure.keychain.provider; import android.net.Uri; import android.provider.BaseColumns; + import org.sufficientlysecure.keychain.Constants; public class KeychainContract { @@ -56,10 +57,15 @@ public class KeychainContract { interface ApiAppsColumns { String PACKAGE_NAME = "package_name"; String PACKAGE_SIGNATURE = "package_signature"; + } + + interface ApiAppsAccountsColumns { + String ACCOUNT_NAME = "account_name"; String KEY_ID = "key_id"; // not a database id String ENCRYPTION_ALGORITHM = "encryption_algorithm"; String HASH_ALORITHM = "hash_algorithm"; String COMPRESSION = "compression"; + String PACKAGE_NAME_FK = "package_name"; // foreign key to api_apps.package_name } public static final class KeyTypes { @@ -87,7 +93,7 @@ public class KeychainContract { public static final String PATH_KEYS = "keys"; public static final String BASE_API_APPS = "api_apps"; - public static final String PATH_BY_PACKAGE_NAME = "package_name"; + public static final String PATH_ACCOUNTS = "accounts"; public static class KeyRings implements KeyRingsColumns, BaseColumns { public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon() @@ -154,6 +160,7 @@ public class KeychainContract { } public static Uri buildSecretKeyRingsByEmailsUri(String emails) { + // TODO: encoded? return CONTENT_URI.buildUpon().appendPath(PATH_SECRET).appendPath(PATH_BY_EMAILS) .appendPath(emails).build(); } @@ -262,16 +269,36 @@ public class KeychainContract { /** * Use if a single item is returned */ - public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.api_apps"; + public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.api_app"; - public static Uri buildIdUri(String rowId) { - return CONTENT_URI.buildUpon().appendPath(rowId).build(); + public static Uri buildByPackageNameUri(String packageName) { + return CONTENT_URI.buildUpon().appendEncodedPath(packageName).build(); } + } - public static Uri buildByPackageNameUri(String packageName) { - return CONTENT_URI.buildUpon().appendPath(PATH_BY_PACKAGE_NAME).appendPath(packageName) + public static class ApiAccounts implements ApiAppsAccountsColumns, BaseColumns { + public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon() + .appendPath(BASE_API_APPS).build(); + + /** + * Use if multiple items get returned + */ + public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.thialfihar.apg.api_app.accounts"; + + /** + * Use if a single item is returned + */ + public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.api_app.account"; + + public static Uri buildBaseUri(String packageName) { + return CONTENT_URI.buildUpon().appendEncodedPath(packageName).appendPath(PATH_ACCOUNTS) .build(); } + + public static Uri buildByPackageAndAccountUri(String packageName, String accountName) { + return CONTENT_URI.buildUpon().appendEncodedPath(packageName).appendPath(PATH_ACCOUNTS) + .appendEncodedPath(accountName).build(); + } } public static class DataStream { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java index 031a7d5ae..ca1a47f0c 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java @@ -23,6 +23,7 @@ import android.database.sqlite.SQLiteOpenHelper; import android.provider.BaseColumns; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsColumns; +import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsAccountsColumns; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingsColumns; import org.sufficientlysecure.keychain.provider.KeychainContract.KeysColumns; import org.sufficientlysecure.keychain.provider.KeychainContract.UserIdsColumns; @@ -30,13 +31,14 @@ import org.sufficientlysecure.keychain.util.Log; public class KeychainDatabase extends SQLiteOpenHelper { private static final String DATABASE_NAME = "apg.db"; - private static final int DATABASE_VERSION = 7; + private static final int DATABASE_VERSION = 8; public interface Tables { String KEY_RINGS = "key_rings"; String KEYS = "keys"; String USER_IDS = "user_ids"; String API_APPS = "api_apps"; + String API_ACCOUNTS = "api_accounts"; } private static final String CREATE_KEY_RINGS = "CREATE TABLE IF NOT EXISTS " + Tables.KEY_RINGS @@ -76,11 +78,18 @@ public class KeychainDatabase extends SQLiteOpenHelper { private static final String CREATE_API_APPS = "CREATE TABLE IF NOT EXISTS " + Tables.API_APPS + " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + ApiAppsColumns.PACKAGE_NAME + " TEXT UNIQUE, " - + ApiAppsColumns.PACKAGE_SIGNATURE + " BLOB, " - + ApiAppsColumns.KEY_ID + " INT64, " - + ApiAppsColumns.ENCRYPTION_ALGORITHM + " INTEGER, " - + ApiAppsColumns.HASH_ALORITHM + " INTEGER, " - + ApiAppsColumns.COMPRESSION + " INTEGER)"; + + ApiAppsColumns.PACKAGE_SIGNATURE + " BLOB)"; + + private static final String CREATE_API_APPS_ACCOUNTS = "CREATE TABLE IF NOT EXISTS " + Tables.API_ACCOUNTS + + " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + + ApiAppsAccountsColumns.ACCOUNT_NAME + " TEXT UNIQUE, " + + ApiAppsAccountsColumns.KEY_ID + " INT64, " + + ApiAppsAccountsColumns.ENCRYPTION_ALGORITHM + " INTEGER, " + + ApiAppsAccountsColumns.HASH_ALORITHM + " INTEGER, " + + ApiAppsAccountsColumns.COMPRESSION + " INTEGER, " + + ApiAppsAccountsColumns.PACKAGE_NAME_FK + " TEXT NOT NULL, FOREIGN KEY(" + + ApiAppsAccountsColumns.PACKAGE_NAME_FK + ") REFERENCES " + Tables.API_APPS + "(" + + ApiAppsColumns.PACKAGE_NAME + ") ON DELETE CASCADE)"; KeychainDatabase(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); @@ -94,6 +103,7 @@ public class KeychainDatabase extends SQLiteOpenHelper { db.execSQL(CREATE_KEYS); db.execSQL(CREATE_USER_IDS); db.execSQL(CREATE_API_APPS); + db.execSQL(CREATE_API_APPS_ACCOUNTS); } @Override @@ -133,6 +143,12 @@ public class KeychainDatabase extends SQLiteOpenHelper { db.execSQL("ALTER TABLE " + Tables.KEYS + " ADD COLUMN " + KeysColumns.FINGERPRINT + " BLOB;"); break; + case 7: + // new db layout for api apps + db.execSQL("DROP TABLE IF EXISTS " + Tables.API_APPS); + db.execSQL(CREATE_API_APPS); + db.execSQL(CREATE_API_APPS_ACCOUNTS); + break; default: break; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java index 746449f7e..6e5515cab 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de> + * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de> * Copyright (C) 2010 Thialfihar <thi@thialfihar.org> * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -28,8 +28,17 @@ import android.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; import android.provider.BaseColumns; import android.text.TextUtils; + import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.provider.KeychainContract.*; +import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAccounts; +import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingsColumns; +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyTypes; +import org.sufficientlysecure.keychain.provider.KeychainContract.Keys; +import org.sufficientlysecure.keychain.provider.KeychainContract.KeysColumns; +import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds; +import org.sufficientlysecure.keychain.provider.KeychainContract.UserIdsColumns; import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables; import org.sufficientlysecure.keychain.util.Log; @@ -71,8 +80,9 @@ public class KeychainProvider extends ContentProvider { private static final int SECRET_KEY_RING_USER_ID_BY_ROW_ID = 222; private static final int API_APPS = 301; - private static final int API_APPS_BY_ROW_ID = 302; private static final int API_APPS_BY_PACKAGE_NAME = 303; + private static final int API_ACCOUNTS = 304; + private static final int API_ACCOUNTS_BY_ACCOUNT_NAME = 306; private static final int UNIFIED_KEY_RING = 401; @@ -229,11 +239,22 @@ public class KeychainProvider extends ContentProvider { /** * API apps + * + * <pre> + * api_apps + * api_apps/_ (package name) + * + * api_apps/_/accounts + * api_apps/_/accounts/_ (account name) + * </pre> */ matcher.addURI(authority, KeychainContract.BASE_API_APPS, API_APPS); - matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/#", API_APPS_BY_ROW_ID); - matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/" - + KeychainContract.PATH_BY_PACKAGE_NAME + "/*", API_APPS_BY_PACKAGE_NAME); + matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/*", API_APPS_BY_PACKAGE_NAME); + + matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/*/" + + KeychainContract.PATH_ACCOUNTS, API_ACCOUNTS); + matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/*/" + + KeychainContract.PATH_ACCOUNTS + "/*", API_ACCOUNTS_BY_ACCOUNT_NAME); /** * data stream @@ -302,10 +323,15 @@ public class KeychainProvider extends ContentProvider { case API_APPS: return ApiApps.CONTENT_TYPE; - case API_APPS_BY_ROW_ID: case API_APPS_BY_PACKAGE_NAME: return ApiApps.CONTENT_ITEM_TYPE; + case API_ACCOUNTS: + return ApiAccounts.CONTENT_TYPE; + + case API_ACCOUNTS_BY_ACCOUNT_NAME: + return ApiAccounts.CONTENT_ITEM_TYPE; + default: throw new UnsupportedOperationException("Unknown uri: " + uri); } @@ -506,7 +532,6 @@ public class KeychainProvider extends ContentProvider { } break; - case PUBLIC_KEY_RING: case SECRET_KEY_RING: qb = buildKeyRingQuery(qb, match); @@ -516,7 +541,6 @@ public class KeychainProvider extends ContentProvider { } break; - case PUBLIC_KEY_RING_BY_ROW_ID: case SECRET_KEY_RING_BY_ROW_ID: qb = buildKeyRingQuery(qb, match); @@ -529,7 +553,6 @@ public class KeychainProvider extends ContentProvider { } break; - case PUBLIC_KEY_RING_BY_MASTER_KEY_ID: case SECRET_KEY_RING_BY_MASTER_KEY_ID: qb = buildKeyRingQuery(qb, match); @@ -542,7 +565,6 @@ public class KeychainProvider extends ContentProvider { } break; - case SECRET_KEY_RING_BY_KEY_ID: case PUBLIC_KEY_RING_BY_KEY_ID: qb = buildKeyRingQueryWithSpecificKey(qb, match); @@ -555,7 +577,6 @@ public class KeychainProvider extends ContentProvider { } break; - case SECRET_KEY_RING_BY_EMAILS: case PUBLIC_KEY_RING_BY_EMAILS: qb = buildKeyRingQuery(qb, match); @@ -585,7 +606,6 @@ public class KeychainProvider extends ContentProvider { } break; - case SECRET_KEY_RING_BY_LIKE_EMAIL: case PUBLIC_KEY_RING_BY_LIKE_EMAIL: qb = buildKeyRingQuery(qb, match); @@ -601,7 +621,6 @@ public class KeychainProvider extends ContentProvider { + "))"); break; - case PUBLIC_KEY_RING_KEY: case SECRET_KEY_RING_KEY: qb.setTables(Tables.KEYS); @@ -614,7 +633,6 @@ public class KeychainProvider extends ContentProvider { qb.setProjectionMap(getProjectionMapForKeys()); break; - case PUBLIC_KEY_RING_KEY_BY_ROW_ID: case SECRET_KEY_RING_KEY_BY_ROW_ID: qb.setTables(Tables.KEYS); @@ -630,7 +648,6 @@ public class KeychainProvider extends ContentProvider { qb.setProjectionMap(getProjectionMapForKeys()); break; - case PUBLIC_KEY_RING_BY_MASTER_KEY_ID_USER_ID: qb.setTables(Tables.USER_IDS + " INNER JOIN " + Tables.KEY_RINGS + " ON " + "(" + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.USER_IDS + "." @@ -641,7 +658,6 @@ public class KeychainProvider extends ContentProvider { qb.setProjectionMap(getProjectionMapForUserIds()); break; - case PUBLIC_KEY_RING_USER_ID: case SECRET_KEY_RING_USER_ID: qb.setTables(Tables.USER_IDS); @@ -649,7 +665,6 @@ public class KeychainProvider extends ContentProvider { qb.appendWhereEscapeString(uri.getPathSegments().get(2)); break; - case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID: case SECRET_KEY_RING_USER_ID_BY_ROW_ID: qb.setTables(Tables.USER_IDS); @@ -660,25 +675,31 @@ public class KeychainProvider extends ContentProvider { qb.appendWhereEscapeString(uri.getLastPathSegment()); break; - case API_APPS: qb.setTables(Tables.API_APPS); break; - case API_APPS_BY_ROW_ID: + case API_APPS_BY_PACKAGE_NAME: qb.setTables(Tables.API_APPS); - - qb.appendWhere(BaseColumns._ID + " = "); + qb.appendWhere(ApiApps.PACKAGE_NAME + " = "); qb.appendWhereEscapeString(uri.getLastPathSegment()); break; - case API_APPS_BY_PACKAGE_NAME: - qb.setTables(Tables.API_APPS); - qb.appendWhere(ApiApps.PACKAGE_NAME + " = "); - qb.appendWhereEscapeString(uri.getPathSegments().get(2)); + case API_ACCOUNTS: + qb.setTables(Tables.API_ACCOUNTS); break; + case API_ACCOUNTS_BY_ACCOUNT_NAME: + qb.setTables(Tables.API_ACCOUNTS + " INNER JOIN " + Tables.API_APPS + " ON " + "(" + + Tables.API_APPS + "." + ApiApps.PACKAGE_NAME + " = " + Tables.API_ACCOUNTS + "." + + ApiAccounts.PACKAGE_NAME_FK + " )"); + qb.appendWhere(Tables.API_APPS + "." + ApiApps.PACKAGE_NAME + " = "); + qb.appendWhereEscapeString(uri.getPathSegments().get(2)); + + qb.appendWhere(" AND " + Tables.API_ACCOUNTS + "." + ApiAccounts.ACCOUNT_NAME + " = "); + qb.appendWhereEscapeString(uri.getLastPathSegment()); + break; default: throw new IllegalArgumentException("Unknown URI " + uri); @@ -735,13 +756,15 @@ public class KeychainProvider extends ContentProvider { values.put(Keys.TYPE, KeyTypes.PUBLIC); rowId = db.insertOrThrow(Tables.KEYS, null, values); - rowUri = Keys.buildPublicKeysUri(Long.toString(rowId)); + // TODO: this is wrong: +// rowUri = Keys.buildPublicKeysUri(Long.toString(rowId)); sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); break; case PUBLIC_KEY_RING_USER_ID: rowId = db.insertOrThrow(Tables.USER_IDS, null, values); - rowUri = UserIds.buildPublicUserIdsUri(Long.toString(rowId)); + // TODO: this is wrong: +// rowUri = UserIds.buildPublicUserIdsUri(Long.toString(rowId)); sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); break; @@ -757,18 +780,26 @@ public class KeychainProvider extends ContentProvider { values.put(Keys.TYPE, KeyTypes.SECRET); rowId = db.insertOrThrow(Tables.KEYS, null, values); - rowUri = Keys.buildSecretKeysUri(Long.toString(rowId)); + // TODO: this is wrong: +// rowUri = Keys.buildSecretKeysUri(Long.toString(rowId)); sendBroadcastDatabaseChange(getKeyType(match), getType(uri)); break; case SECRET_KEY_RING_USER_ID: rowId = db.insertOrThrow(Tables.USER_IDS, null, values); - rowUri = UserIds.buildSecretUserIdsUri(Long.toString(rowId)); + // TODO: this is wrong: +// rowUri = UserIds.buildSecretUserIdsUri(Long.toString(rowId)); break; case API_APPS: rowId = db.insertOrThrow(Tables.API_APPS, null, values); - rowUri = ApiApps.buildIdUri(Long.toString(rowId)); +// rowUri = ApiApps.buildIdUri(Long.toString(rowId)); + + break; + case API_ACCOUNTS: + rowId = db.insertOrThrow(Tables.API_ACCOUNTS, null, values); + // TODO: this is wrong: +// rowUri = ApiAccounts.buildIdUri(Long.toString(rowId)); break; default: @@ -828,12 +859,12 @@ public class KeychainProvider extends ContentProvider { count = db.delete(Tables.KEYS, buildDefaultUserIdsSelection(uri, selection), selectionArgs); break; - case API_APPS_BY_ROW_ID: - count = db.delete(Tables.API_APPS, buildDefaultApiAppsSelection(uri, false, selection), + case API_APPS_BY_PACKAGE_NAME: + count = db.delete(Tables.API_APPS, buildDefaultApiAppsSelection(uri, selection), selectionArgs); break; - case API_APPS_BY_PACKAGE_NAME: - count = db.delete(Tables.API_APPS, buildDefaultApiAppsSelection(uri, true, selection), + case API_ACCOUNTS_BY_ACCOUNT_NAME: + count = db.delete(Tables.API_ACCOUNTS, buildDefaultApiAccountsSelection(uri, selection), selectionArgs); break; default: @@ -898,13 +929,13 @@ public class KeychainProvider extends ContentProvider { count = db.update(Tables.USER_IDS, values, buildDefaultUserIdsSelection(uri, selection), selectionArgs); break; - case API_APPS_BY_ROW_ID: - count = db.update(Tables.API_APPS, values, - buildDefaultApiAppsSelection(uri, false, selection), selectionArgs); - break; case API_APPS_BY_PACKAGE_NAME: count = db.update(Tables.API_APPS, values, - buildDefaultApiAppsSelection(uri, true, selection), selectionArgs); + buildDefaultApiAppsSelection(uri, selection), selectionArgs); + break; + case API_ACCOUNTS_BY_ACCOUNT_NAME: + count = db.update(Tables.API_ACCOUNTS, values, + buildDefaultApiAccountsSelection(uri, selection), selectionArgs); break; default: throw new UnsupportedOperationException("Unknown uri: " + uri); @@ -1003,19 +1034,29 @@ public class KeychainProvider extends ContentProvider { * @param selection * @return */ - private String buildDefaultApiAppsSelection(Uri uri, boolean packageSelection, String selection) { - String lastPathSegment = uri.getLastPathSegment(); + private String buildDefaultApiAppsSelection(Uri uri, String selection) { + String packageName = DatabaseUtils.sqlEscapeString(uri.getLastPathSegment()); String andSelection = ""; if (!TextUtils.isEmpty(selection)) { andSelection = " AND (" + selection + ")"; } - if (packageSelection) { - return ApiApps.PACKAGE_NAME + "=" + lastPathSegment + andSelection; - } else { - return BaseColumns._ID + "=" + lastPathSegment + andSelection; + return ApiApps.PACKAGE_NAME + "=" + packageName + andSelection; + } + + private String buildDefaultApiAccountsSelection(Uri uri, String selection) { + String packageName = DatabaseUtils.sqlEscapeString(uri.getPathSegments().get(2)); + String accountName = DatabaseUtils.sqlEscapeString(uri.getLastPathSegment()); + + String andSelection = ""; + if (!TextUtils.isEmpty(selection)) { + andSelection = " AND (" + selection + ")"; } + + return ApiAccounts.PACKAGE_NAME_FK + "=" + packageName + " AND " + + ApiAccounts.ACCOUNT_NAME + "=" + accountName + + andSelection; } // @Override diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainServiceBlobProvider.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainServiceBlobProvider.java index 6ac61e157..aa30e845d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainServiceBlobProvider.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainServiceBlobProvider.java @@ -38,7 +38,7 @@ import java.util.List; import java.util.UUID; public class KeychainServiceBlobProvider extends ContentProvider { - private static final String STORE_PATH = Constants.Path.APP_DIR + "/ApgBlobs"; + private static final String STORE_PATH = Constants.Path.APP_DIR + "/KeychainBlobs"; private KeychainServiceBlobDatabase mBlobDatabase = null; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index 2fa903fe2..e3727b2f8 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -22,6 +22,7 @@ import android.database.Cursor; import android.database.DatabaseUtils; import android.net.Uri; import android.os.RemoteException; + import org.spongycastle.bcpg.ArmoredOutputStream; import org.spongycastle.openpgp.*; import org.sufficientlysecure.keychain.Constants; @@ -33,7 +34,8 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainContract.Keys; import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds; import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables; -import org.sufficientlysecure.keychain.service.remote.AppSettings; +import org.sufficientlysecure.keychain.remote.AccountSettings; +import org.sufficientlysecure.keychain.remote.AppSettings; import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.Log; @@ -469,11 +471,11 @@ public class ProviderHelper { cr.delete(KeyRings.buildSecretKeyRingsUri(Long.toString(rowId)), null, null); } - public static void deleteUnifiedKeyRing(Context context,String masterKeyId,boolean isSecretKey){ - ContentResolver cr= context.getContentResolver(); - cr.delete(KeyRings.buildPublicKeyRingsByMasterKeyIdUri(masterKeyId),null,null); - if(isSecretKey){ - cr.delete(KeyRings.buildSecretKeyRingsByMasterKeyIdUri(masterKeyId),null,null); + public static void deleteUnifiedKeyRing(Context context, String masterKeyId, boolean isSecretKey) { + ContentResolver cr = context.getContentResolver(); + cr.delete(KeyRings.buildPublicKeyRingsByMasterKeyIdUri(masterKeyId), null, null); + if (isSecretKey) { + cr.delete(KeyRings.buildSecretKeyRingsByMasterKeyIdUri(masterKeyId), null, null); } } @@ -504,7 +506,7 @@ public class ProviderHelper { + " AS sign_keys WHERE sign_keys." + Keys.KEY_RING_ROW_ID + " = " + KeychainDatabase.Tables.KEY_RINGS + "." + KeyRings._ID + " AND sign_keys." + Keys.CAN_SIGN + " = '1' AND " + Keys.IS_MASTER_KEY - + " = 1) AS sign", }; + + " = 1) AS sign",}; ContentResolver cr = context.getContentResolver(); Cursor cursor = cr.query(queryUri, projection, null, null, null); @@ -801,19 +803,30 @@ public class ProviderHelper { ContentValues values = new ContentValues(); values.put(ApiApps.PACKAGE_NAME, appSettings.getPackageName()); values.put(ApiApps.PACKAGE_SIGNATURE, appSettings.getPackageSignature()); - values.put(ApiApps.KEY_ID, appSettings.getKeyId()); - values.put(ApiApps.COMPRESSION, appSettings.getCompression()); - values.put(ApiApps.ENCRYPTION_ALGORITHM, appSettings.getEncryptionAlgorithm()); - values.put(ApiApps.HASH_ALORITHM, appSettings.getHashAlgorithm()); + return values; + } + private static ContentValues contentValueForApiAccounts(AccountSettings accSettings) { + ContentValues values = new ContentValues(); + values.put(KeychainContract.ApiAccounts.ACCOUNT_NAME, accSettings.getAccountName()); + values.put(KeychainContract.ApiAccounts.KEY_ID, accSettings.getKeyId()); + values.put(KeychainContract.ApiAccounts.COMPRESSION, accSettings.getCompression()); + values.put(KeychainContract.ApiAccounts.ENCRYPTION_ALGORITHM, accSettings.getEncryptionAlgorithm()); + values.put(KeychainContract.ApiAccounts.HASH_ALORITHM, accSettings.getHashAlgorithm()); +// values.put(KeychainContract.ApiAccounts.PACKAGE_NAME_FK, accSettings.getPackageName()); return values; } public static void insertApiApp(Context context, AppSettings appSettings) { - context.getContentResolver().insert(ApiApps.CONTENT_URI, + context.getContentResolver().insert(KeychainContract.ApiApps.CONTENT_URI, contentValueForApiApps(appSettings)); } + public static void insertApiAccount(Context context, Uri uri, AccountSettings accSettings) { + context.getContentResolver().insert(uri, + contentValueForApiAccounts(accSettings)); + } + public static void updateApiApp(Context context, AppSettings appSettings, Uri uri) { if (context.getContentResolver().update(uri, contentValueForApiApps(appSettings), null, null) <= 0) { @@ -821,30 +834,60 @@ public class ProviderHelper { } } + public static void updateApiAccount(Context context, AccountSettings accSettings, Uri uri) { + if (context.getContentResolver().update(uri, contentValueForApiAccounts(accSettings), null, + null) <= 0) { + throw new RuntimeException(); + } + } + + + /** + * Must be an uri pointing to an account + * + * @param context + * @param uri + * @return + */ public static AppSettings getApiAppSettings(Context context, Uri uri) { AppSettings settings = null; Cursor cur = context.getContentResolver().query(uri, null, null, null, null); if (cur != null && cur.moveToFirst()) { settings = new AppSettings(); - settings.setPackageName(cur.getString(cur - .getColumnIndex(KeychainContract.ApiApps.PACKAGE_NAME))); - settings.setPackageSignature(cur.getBlob(cur - .getColumnIndex(KeychainContract.ApiApps.PACKAGE_SIGNATURE))); - settings.setKeyId(cur.getLong(cur.getColumnIndex(KeychainContract.ApiApps.KEY_ID))); - settings.setCompression(cur.getInt(cur - .getColumnIndexOrThrow(KeychainContract.ApiApps.COMPRESSION))); - settings.setHashAlgorithm(cur.getInt(cur - .getColumnIndexOrThrow(KeychainContract.ApiApps.HASH_ALORITHM))); - settings.setEncryptionAlgorithm(cur.getInt(cur - .getColumnIndexOrThrow(KeychainContract.ApiApps.ENCRYPTION_ALGORITHM))); + settings.setPackageName(cur.getString( + cur.getColumnIndex(KeychainContract.ApiApps.PACKAGE_NAME))); + settings.setPackageSignature(cur.getBlob( + cur.getColumnIndex(KeychainContract.ApiApps.PACKAGE_SIGNATURE))); + } + + return settings; + } + + public static AccountSettings getApiAccountSettings(Context context, Uri uri) { + AccountSettings settings = null; + + Cursor cur = context.getContentResolver().query(uri, null, null, null, null); + if (cur != null && cur.moveToFirst()) { + settings = new AccountSettings(); + + settings.setAccountName(cur.getString( + cur.getColumnIndex(KeychainContract.ApiAccounts.ACCOUNT_NAME))); + settings.setKeyId(cur.getLong( + cur.getColumnIndex(KeychainContract.ApiAccounts.KEY_ID))); + settings.setCompression(cur.getInt( + cur.getColumnIndexOrThrow(KeychainContract.ApiAccounts.COMPRESSION))); + settings.setHashAlgorithm(cur.getInt( + cur.getColumnIndexOrThrow(KeychainContract.ApiAccounts.HASH_ALORITHM))); + settings.setEncryptionAlgorithm(cur.getInt( + cur.getColumnIndexOrThrow(KeychainContract.ApiAccounts.ENCRYPTION_ALGORITHM))); } return settings; } - public static byte[] getApiAppSignature(Context context, String packageName) { - Uri queryUri = KeychainContract.ApiApps.buildByPackageNameUri(packageName); + public static byte[] getApiSignature(Context context, String packageName) { + Uri queryUri = ApiApps.buildByPackageNameUri(packageName); String[] projection = new String[]{ApiApps.PACKAGE_SIGNATURE}; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettings.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AccountSettings.java index 6f2d67efb..832cbc752 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettings.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AccountSettings.java @@ -15,48 +15,39 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -package org.sufficientlysecure.keychain.service.remote; +package org.sufficientlysecure.keychain.remote; import org.spongycastle.bcpg.HashAlgorithmTags; import org.spongycastle.openpgp.PGPEncryptedData; import org.sufficientlysecure.keychain.Id; -public class AppSettings { - private String mPackageName; - private byte[] mPackageSignature; +public class AccountSettings { + private String mAccountName; private long mKeyId = Id.key.none; private int mEncryptionAlgorithm; private int mHashAlgorithm; private int mCompression; - public AppSettings() { + public AccountSettings() { } - public AppSettings(String packageName, byte[] packageSignature) { + public AccountSettings(String accountName) { super(); - this.mPackageName = packageName; - this.mPackageSignature = packageSignature; + this.mAccountName = accountName; + // defaults: this.mEncryptionAlgorithm = PGPEncryptedData.AES_256; this.mHashAlgorithm = HashAlgorithmTags.SHA512; this.mCompression = Id.choice.compression.zlib; } - public String getPackageName() { - return mPackageName; - } - - public void setPackageName(String packageName) { - this.mPackageName = packageName; - } - - public byte[] getPackageSignature() { - return mPackageSignature; + public String getAccountName() { + return mAccountName; } - public void setPackageSignature(byte[] packageSignature) { - this.mPackageSignature = packageSignature; + public void setAccountName(String mAccountName) { + this.mAccountName = mAccountName; } public long getKeyId() { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AppSettings.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AppSettings.java new file mode 100644 index 000000000..6c7e51bf0 --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AppSettings.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package org.sufficientlysecure.keychain.remote; + +import org.spongycastle.bcpg.HashAlgorithmTags; +import org.spongycastle.openpgp.PGPEncryptedData; +import org.sufficientlysecure.keychain.Id; + +public class AppSettings { + private String mPackageName; + private byte[] mPackageSignature; + + public AppSettings() { + + } + + public AppSettings(String packageName, byte[] packageSignature) { + super(); + this.mPackageName = packageName; + this.mPackageSignature = packageSignature; + } + + public String getPackageName() { + return mPackageName; + } + + public void setPackageName(String packageName) { + this.mPackageName = packageName; + } + + public byte[] getPackageSignature() { + return mPackageSignature; + } + + public void setPackageSignature(byte[] packageSignature) { + this.mPackageSignature = packageSignature; + } + +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index 95dc897f0..fa6ccf63b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -15,7 +15,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -package org.sufficientlysecure.keychain.service.remote; +package org.sufficientlysecure.keychain.remote; import android.app.PendingIntent; import android.content.Intent; @@ -36,6 +36,7 @@ import org.sufficientlysecure.keychain.pgp.PgpSignEncrypt; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.remote.ui.RemoteServiceActivity; import org.sufficientlysecure.keychain.service.PassphraseCacheService; import org.sufficientlysecure.keychain.util.InputData; import org.sufficientlysecure.keychain.util.Log; @@ -137,7 +138,7 @@ public class OpenPgpService extends RemoteService { } private Intent signImpl(Intent data, ParcelFileDescriptor input, - ParcelFileDescriptor output, AppSettings appSettings) { + ParcelFileDescriptor output, AccountSettings accSettings) { try { boolean asciiArmor = data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true); @@ -146,11 +147,11 @@ public class OpenPgpService extends RemoteService { if (data.hasExtra(OpenPgpApi.EXTRA_PASSPHRASE)) { passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE); } else { - passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), appSettings.getKeyId()); + passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), accSettings.getKeyId()); } if (passphrase == null) { // get PendingIntent for passphrase input, add it to given params and return to client - Intent passphraseBundle = getPassphraseBundleIntent(data, appSettings.getKeyId()); + Intent passphraseBundle = getPassphraseBundleIntent(data, accSettings.getKeyId()); return passphraseBundle; } @@ -164,9 +165,9 @@ public class OpenPgpService extends RemoteService { // sign-only PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder(getContext(), inputData, os); builder.enableAsciiArmorOutput(asciiArmor) - .signatureHashAlgorithm(appSettings.getHashAlgorithm()) + .signatureHashAlgorithm(accSettings.getHashAlgorithm()) .signatureForceV3(false) - .signatureKeyId(appSettings.getKeyId()) + .signatureKeyId(accSettings.getKeyId()) .signaturePassphrase(passphrase); builder.build().execute(); } finally { @@ -187,7 +188,7 @@ public class OpenPgpService extends RemoteService { } private Intent encryptAndSignImpl(Intent data, ParcelFileDescriptor input, - ParcelFileDescriptor output, AppSettings appSettings, boolean sign) { + ParcelFileDescriptor output, AccountSettings accSettings, boolean sign) { try { boolean asciiArmor = data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true); @@ -217,7 +218,7 @@ public class OpenPgpService extends RemoteService { // add own key for encryption keyIds = Arrays.copyOf(keyIds, keyIds.length + 1); - keyIds[keyIds.length - 1] = appSettings.getKeyId(); + keyIds[keyIds.length - 1] = accSettings.getKeyId(); // build InputData and write into OutputStream // Get Input- and OutputStream from ParcelFileDescriptor @@ -229,8 +230,8 @@ public class OpenPgpService extends RemoteService { PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder(getContext(), inputData, os); builder.enableAsciiArmorOutput(asciiArmor) - .compressionId(appSettings.getCompression()) - .symmetricEncryptionAlgorithm(appSettings.getEncryptionAlgorithm()) + .compressionId(accSettings.getCompression()) + .symmetricEncryptionAlgorithm(accSettings.getEncryptionAlgorithm()) .encryptionKeyIds(keyIds); if (sign) { @@ -239,18 +240,18 @@ public class OpenPgpService extends RemoteService { passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE); } else { passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), - appSettings.getKeyId()); + accSettings.getKeyId()); } if (passphrase == null) { // get PendingIntent for passphrase input, add it to given params and return to client - Intent passphraseBundle = getPassphraseBundleIntent(data, appSettings.getKeyId()); + Intent passphraseBundle = getPassphraseBundleIntent(data, accSettings.getKeyId()); return passphraseBundle; } // sign and encrypt - builder.signatureHashAlgorithm(appSettings.getHashAlgorithm()) + builder.signatureHashAlgorithm(accSettings.getHashAlgorithm()) .signatureForceV3(false) - .signatureKeyId(appSettings.getKeyId()) + .signatureKeyId(accSettings.getKeyId()) .signaturePassphrase(passphrase); } else { // encrypt only @@ -276,7 +277,7 @@ public class OpenPgpService extends RemoteService { } private Intent decryptAndVerifyImpl(Intent data, ParcelFileDescriptor input, - ParcelFileDescriptor output, AppSettings appSettings) { + ParcelFileDescriptor output, AccountSettings accSettings) { try { // Get Input- and OutputStream from ParcelFileDescriptor InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input); @@ -292,7 +293,7 @@ public class OpenPgpService extends RemoteService { PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(this, inputData, os); builder.assumeSymmetric(false) // no support for symmetric encryption // allow only the private key for this app for decryption - .enforcedKeyId(appSettings.getKeyId()) + .enforcedKeyId(accSettings.getKeyId()) .passphrase(passphrase); // TODO: currently does not support binary signed-only content @@ -300,7 +301,7 @@ public class OpenPgpService extends RemoteService { if (decryptVerifyResult.isKeyPassphraseNeeded()) { // get PendingIntent for passphrase input, add it to given params and return to client - Intent passphraseBundle = getPassphraseBundleIntent(data, appSettings.getKeyId()); + Intent passphraseBundle = getPassphraseBundleIntent(data, accSettings.getKeyId()); return passphraseBundle; } else if (decryptVerifyResult.isSymmetricPassphraseNeeded()) { throw new PgpGeneralException("Decryption of symmetric content not supported by API!"); @@ -432,17 +433,26 @@ public class OpenPgpService extends RemoteService { return errorResult; } - final AppSettings appSettings = getAppSettings(); + String accName; + if (data.getStringExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME) != null) { + accName = data.getStringExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME); + } else { + accName = "default"; + } + final AccountSettings accSettings = getAccSettings(accName); + if (accSettings == null) { + return getCreateAccountIntent(data, accName); + } String action = data.getAction(); if (OpenPgpApi.ACTION_SIGN.equals(action)) { - return signImpl(data, input, output, appSettings); + return signImpl(data, input, output, accSettings); } else if (OpenPgpApi.ACTION_ENCRYPT.equals(action)) { - return encryptAndSignImpl(data, input, output, appSettings, false); + return encryptAndSignImpl(data, input, output, accSettings, false); } else if (OpenPgpApi.ACTION_SIGN_AND_ENCRYPT.equals(action)) { - return encryptAndSignImpl(data, input, output, appSettings, true); + return encryptAndSignImpl(data, input, output, accSettings, true); } else if (OpenPgpApi.ACTION_DECRYPT_VERIFY.equals(action)) { - return decryptAndVerifyImpl(data, input, output, appSettings); + return decryptAndVerifyImpl(data, input, output, accSettings); } else if (OpenPgpApi.ACTION_GET_KEY.equals(action)) { return getKeyImpl(data); } else if (OpenPgpApi.ACTION_GET_KEY_IDS.equals(action)) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java index 6a883316a..0fd9ee7df 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java @@ -15,7 +15,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -package org.sufficientlysecure.keychain.service.remote; +package org.sufficientlysecure.keychain.remote; import android.app.PendingIntent; import android.app.Service; @@ -27,12 +27,14 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.Signature; import android.net.Uri; import android.os.Binder; + import org.openintents.openpgp.OpenPgpError; import org.openintents.openpgp.util.OpenPgpApi; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.remote.ui.RemoteServiceActivity; import org.sufficientlysecure.keychain.util.Log; import java.util.ArrayList; @@ -47,7 +49,6 @@ public abstract class RemoteService extends Service { private static final int PRIVATE_REQUEST_CODE_REGISTER = 651; private static final int PRIVATE_REQUEST_CODE_ERROR = 652; - public Context getContext() { return mContext; } @@ -55,13 +56,9 @@ public abstract class RemoteService extends Service { protected Intent isAllowed(Intent data) { try { if (isCallerAllowed(false)) { - return null; } else { - String[] callingPackages = getPackageManager().getPackagesForUid( - Binder.getCallingUid()); - // TODO: currently simply uses first entry - String packageName = callingPackages[0]; + String packageName = getCurrentCallingPackage(); byte[] packageSignature; try { @@ -84,7 +81,7 @@ public abstract class RemoteService extends Service { intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); PendingIntent pi = PendingIntent.getActivity(getBaseContext(), - PRIVATE_REQUEST_CODE_REGISTER, intent, 0); + PRIVATE_REQUEST_CODE_REGISTER, intent, 0); // return PendingIntent to be executed by client Intent result = new Intent(); @@ -99,11 +96,11 @@ public abstract class RemoteService extends Service { Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); intent.setAction(RemoteServiceActivity.ACTION_ERROR_MESSAGE); intent.putExtra(RemoteServiceActivity.EXTRA_ERROR_MESSAGE, - getString(R.string.api_error_wrong_signature)); + getString(R.string.api_error_wrong_signature)); intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); PendingIntent pi = PendingIntent.getActivity(getBaseContext(), - PRIVATE_REQUEST_CODE_ERROR, intent, 0); + PRIVATE_REQUEST_CODE_ERROR, intent, 0); // return PendingIntent to be executed by client Intent result = new Intent(); @@ -125,27 +122,56 @@ public abstract class RemoteService extends Service { } /** - * Retrieves AppSettings from database for the application calling this remote service + * Returns package name associated with the UID, which is assigned to the process that sent you the + * current transaction that is being processed :) * - * @return + * @return package name */ - protected AppSettings getAppSettings() { + private String getCurrentCallingPackage() { + // TODO: + // callingPackages contains more than one entry when sharedUserId has been used... String[] callingPackages = getPackageManager().getPackagesForUid(Binder.getCallingUid()); + String currentPkg = callingPackages[0]; + Log.d(Constants.TAG, "currentPkg: " + currentPkg); - // get app settings for this package - for (int i = 0; i < callingPackages.length; i++) { - String currentPkg = callingPackages[i]; + return currentPkg; + } - Uri uri = KeychainContract.ApiApps.buildByPackageNameUri(currentPkg); + /** + * Retrieves AccountSettings from database for the application calling this remote service + * + * @return + */ + protected AccountSettings getAccSettings(String accountName) { + String currentPkg = getCurrentCallingPackage(); + Log.d(Constants.TAG, "accountName: " + accountName); - AppSettings settings = ProviderHelper.getApiAppSettings(this, uri); + Uri uri = KeychainContract.ApiAccounts.buildByPackageAndAccountUri(currentPkg, accountName); - if (settings != null) { - return settings; - } - } + AccountSettings settings = ProviderHelper.getApiAccountSettings(this, uri); + + return settings; // can be null! + } + + protected Intent getCreateAccountIntent(Intent data, String accountName) { + String packageName = getCurrentCallingPackage(); + Log.d(Constants.TAG, "accountName: " + accountName); + + Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); + intent.setAction(RemoteServiceActivity.ACTION_CREATE_ACCOUNT); + intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_NAME, packageName); + intent.putExtra(RemoteServiceActivity.EXTRA_ACC_NAME, accountName); + intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); + + PendingIntent pi = PendingIntent.getActivity(getBaseContext(), + PRIVATE_REQUEST_CODE_REGISTER, intent, 0); + + // return PendingIntent to be executed by client + Intent result = new Intent(); + result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED); + result.putExtra(OpenPgpApi.RESULT_INTENT, pi); - return null; + return result; } /** @@ -209,14 +235,14 @@ public abstract class RemoteService extends Service { throw new WrongPackageSignatureException(e.getMessage()); } - byte[] storedSig = ProviderHelper.getApiAppSignature(this, packageName); + byte[] storedSig = ProviderHelper.getApiSignature(this, packageName); if (Arrays.equals(currentSig, storedSig)) { Log.d(Constants.TAG, "Package signature is correct! (equals signature from database)"); return true; } else { throw new WrongPackageSignatureException( - "PACKAGE NOT ALLOWED! Signature wrong! (Signature not equals signature from database)"); + "PACKAGE NOT ALLOWED! Signature wrong! (Signature not equals signature from database)"); } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/WrongPackageSignatureException.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/WrongPackageSignatureException.java index 0b642086a..6f44a65e9 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/WrongPackageSignatureException.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/WrongPackageSignatureException.java @@ -15,7 +15,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -package org.sufficientlysecure.keychain.service.remote; +package org.sufficientlysecure.keychain.remote; public class WrongPackageSignatureException extends Exception { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java index 52b06a2ae..3d88d216e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java @@ -15,7 +15,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -package org.sufficientlysecure.keychain.service.remote; +package org.sufficientlysecure.keychain.remote.ui; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; @@ -35,6 +35,8 @@ import android.widget.TextView; import org.spongycastle.util.encoders.Hex; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.remote.AccountSettings; +import org.sufficientlysecure.keychain.remote.AppSettings; import org.sufficientlysecure.keychain.ui.SelectSecretKeyLayoutFragment; import org.sufficientlysecure.keychain.ui.adapter.KeyValueSpinnerAdapter; import org.sufficientlysecure.keychain.util.AlgorithmNames; @@ -43,11 +45,11 @@ import org.sufficientlysecure.keychain.util.Log; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -public class AppSettingsFragment extends Fragment implements +public class AccountSettingsFragment extends Fragment implements SelectSecretKeyLayoutFragment.SelectSecretKeyCallback { // model - private AppSettings mAppSettings; + private AccountSettings mAccSettings; // view private TextView mAppNameView; @@ -64,25 +66,25 @@ public class AppSettingsFragment extends Fragment implements KeyValueSpinnerAdapter mHashAdapter; KeyValueSpinnerAdapter mCompressionAdapter; - public AppSettings getAppSettings() { - return mAppSettings; + public AccountSettings getAccSettings() { + return mAccSettings; } - public void setAppSettings(AppSettings appSettings) { - this.mAppSettings = appSettings; - setPackage(appSettings.getPackageName()); - mPackageName.setText(appSettings.getPackageName()); - - try { - MessageDigest md = MessageDigest.getInstance("SHA-256"); - md.update(appSettings.getPackageSignature()); - byte[] digest = md.digest(); - String signature = new String(Hex.encode(digest)); - - mPackageSignature.setText(signature); - } catch (NoSuchAlgorithmException e) { - Log.e(Constants.TAG, "Should not happen!", e); - } + public void setAccSettings(AccountSettings appSettings) { + this.mAccSettings = appSettings; +// setPackage(appSettings.getPackageName()); +// mPackageName.setText(appSettings.getPackageName()); + +// try { +// MessageDigest md = MessageDigest.getInstance("SHA-256"); +// md.update(appSettings.getPackageSignature()); +// byte[] digest = md.digest(); +// String signature = new String(Hex.encode(digest)); +// +// mPackageSignature.setText(signature); +// } catch (NoSuchAlgorithmException e) { +// Log.e(Constants.TAG, "Should not happen!", e); +// } mSelectKeyFragment.selectKey(appSettings.getKeyId()); mEncryptionAlgorithm.setSelection(mEncryptionAdapter.getPosition(appSettings @@ -96,7 +98,7 @@ public class AppSettingsFragment extends Fragment implements */ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.api_app_settings_fragment, container, false); + View view = inflater.inflate(R.layout.api_account_settings_fragment, container, false); initView(view); return view; } @@ -112,17 +114,17 @@ public class AppSettingsFragment extends Fragment implements private void initView(View view) { mSelectKeyFragment = (SelectSecretKeyLayoutFragment) getFragmentManager().findFragmentById( - R.id.api_app_settings_select_key_fragment); + R.id.api_account_settings_select_key_fragment); mSelectKeyFragment.setCallback(this); - mAppNameView = (TextView) view.findViewById(R.id.api_app_settings_app_name); - mAppIconView = (ImageView) view.findViewById(R.id.api_app_settings_app_icon); + mAppNameView = (TextView) view.findViewById(R.id.api_account_settings_app_name); + mAppIconView = (ImageView) view.findViewById(R.id.api_account_settings_app_icon); mEncryptionAlgorithm = (Spinner) view - .findViewById(R.id.api_app_settings_encryption_algorithm); - mHashAlgorithm = (Spinner) view.findViewById(R.id.api_app_settings_hash_algorithm); - mCompression = (Spinner) view.findViewById(R.id.api_app_settings_compression); - mPackageName = (TextView) view.findViewById(R.id.api_app_settings_package_name); - mPackageSignature = (TextView) view.findViewById(R.id.api_app_settings_package_signature); + .findViewById(R.id.api_account_settings_encryption_algorithm); + mHashAlgorithm = (Spinner) view.findViewById(R.id.api_account_settings_hash_algorithm); + mCompression = (Spinner) view.findViewById(R.id.api_account_settings_compression); + mPackageName = (TextView) view.findViewById(R.id.api_account_settings_package_name); + mPackageSignature = (TextView) view.findViewById(R.id.api_account_settings_package_signature); AlgorithmNames algorithmNames = new AlgorithmNames(getActivity()); @@ -133,7 +135,7 @@ public class AppSettingsFragment extends Fragment implements @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { - mAppSettings.setEncryptionAlgorithm((int) id); + mAccSettings.setEncryptionAlgorithm((int) id); } @Override @@ -147,7 +149,7 @@ public class AppSettingsFragment extends Fragment implements @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { - mAppSettings.setHashAlgorithm((int) id); + mAccSettings.setHashAlgorithm((int) id); } @Override @@ -162,7 +164,7 @@ public class AppSettingsFragment extends Fragment implements @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { - mAppSettings.setCompression((int) id); + mAccSettings.setCompression((int) id); } @Override @@ -170,32 +172,32 @@ public class AppSettingsFragment extends Fragment implements } }); } - - private void setPackage(String packageName) { - PackageManager pm = getActivity().getApplicationContext().getPackageManager(); - - // get application name and icon from package manager - String appName = null; - Drawable appIcon = null; - try { - ApplicationInfo ai = pm.getApplicationInfo(packageName, 0); - - appName = (String) pm.getApplicationLabel(ai); - appIcon = pm.getApplicationIcon(ai); - } catch (final NameNotFoundException e) { - // fallback - appName = packageName; - } - mAppNameView.setText(appName); - mAppIconView.setImageDrawable(appIcon); - } +// +// private void setPackage(String packageName) { +// PackageManager pm = getActivity().getApplicationContext().getPackageManager(); +// +// // get application name and icon from package manager +// String appName = null; +// Drawable appIcon = null; +// try { +// ApplicationInfo ai = pm.getApplicationInfo(packageName, 0); +// +// appName = (String) pm.getApplicationLabel(ai); +// appIcon = pm.getApplicationIcon(ai); +// } catch (final NameNotFoundException e) { +// // fallback +// appName = packageName; +// } +// mAppNameView.setText(appName); +// mAppIconView.setImageDrawable(appIcon); +// } /** * callback from select secret key fragment */ @Override public void onKeySelected(long secretKeyId) { - mAppSettings.setKeyId(secretKeyId); + mAccSettings.setKeyId(secretKeyId); } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java new file mode 100644 index 000000000..853dc2d3c --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package org.sufficientlysecure.keychain.remote.ui; + +import android.annotation.TargetApi; +import android.content.ContentUris; +import android.content.Intent; +import android.database.Cursor; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.support.v4.app.ListFragment; +import android.support.v4.app.LoaderManager; +import android.support.v4.content.CursorLoader; +import android.support.v4.content.Loader; +import android.view.View; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.SimpleCursorAdapter; + +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; + +// TODO: make compat with < 11 +@TargetApi(Build.VERSION_CODES.HONEYCOMB) +public class AccountsListFragment extends ListFragment implements + LoaderManager.LoaderCallbacks<Cursor> { + + private static final String ARG_DATA_URI = "uri"; + + // This is the Adapter being used to display the list's data. + SimpleCursorAdapter mAdapter; + + private Uri mDataUri; + + /** + * Creates new instance of this fragment + */ + public static AccountsListFragment newInstance(Uri dataUri) { + AccountsListFragment frag = new AccountsListFragment(); + + Bundle args = new Bundle(); + args.putParcelable(ARG_DATA_URI, dataUri); + + frag.setArguments(args); + + return frag; + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + mDataUri = getArguments().getParcelable(ARG_DATA_URI); + + getListView().setOnItemClickListener(new OnItemClickListener() { + @Override + public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) { +// // edit app settings +// Intent intent = new Intent(getActivity(), AppSettingsActivity.class); +// intent.setData(ContentUris.withAppendedId(ApiApps.CONTENT_URI, id)); +// startActivity(intent); + } + }); + + // Give some text to display if there is no data. In a real + // application this would come from a resource. + setEmptyText(getString(R.string.api_settings_accounts_empty)); + + // We have a menu item to show in action bar. + setHasOptionsMenu(true); + + // Create an empty adapter we will use to display the loaded data. + mAdapter = new SimpleCursorAdapter(getActivity(), + android.R.layout.simple_list_item_1, + null, + new String[]{KeychainContract.ApiAccounts.ACCOUNT_NAME}, + new int[]{android.R.id.text1}, + 0); + setListAdapter(mAdapter); + + // Prepare the loader. Either re-connect with an existing one, + // or start a new one. + getLoaderManager().initLoader(0, null, this); + } + + // These are the Contacts rows that we will retrieve. + static final String[] PROJECTION = new String[]{ + KeychainContract.ApiAccounts._ID, + KeychainContract.ApiAccounts.ACCOUNT_NAME}; + + public Loader<Cursor> onCreateLoader(int id, Bundle args) { + // This is called when a new Loader needs to be created. This + // sample only has one Loader, so we don't care about the ID. + // First, pick the base URI to use depending on whether we are + // currently filtering. +// Uri baseUri = KeychainContract.ApiAccounts.buildBaseUri(mPackageName); + + // Now create and return a CursorLoader that will take care of + // creating a Cursor for the data being displayed. + return new CursorLoader(getActivity(), mDataUri, PROJECTION, null, null, + KeychainContract.ApiAccounts.ACCOUNT_NAME + " COLLATE LOCALIZED ASC"); + } + + public void onLoadFinished(Loader<Cursor> loader, Cursor data) { + // Swap the new cursor in. (The framework will take care of closing the + // old cursor once we return.) + mAdapter.swapCursor(data); + } + + public void onLoaderReset(Loader<Cursor> loader) { + // This is called when the last Cursor provided to onLoadFinished() + // above is about to be closed. We need to make sure we are no + // longer using it. + mAdapter.swapCursor(null); + } + +// private class RegisteredAppsAdapter extends CursorAdapter { +// +// private LayoutInflater mInflater; +// private PackageManager mPM; +// +// public RegisteredAppsAdapter(Context context, Cursor c, int flags) { +// super(context, c, flags); +// +// mInflater = LayoutInflater.from(context); +// mPM = context.getApplicationContext().getPackageManager(); +// } +// +// @Override +// public void bindView(View view, Context context, Cursor cursor) { +// TextView text = (TextView) view.findViewById(R.id.api_apps_adapter_item_name); +// ImageView icon = (ImageView) view.findViewById(R.id.api_apps_adapter_item_icon); +// +// String packageName = cursor.getString(cursor.getColumnIndex(ApiApps.PACKAGE_NAME)); +// if (packageName != null) { +// // get application name +// try { +// ApplicationInfo ai = mPM.getApplicationInfo(packageName, 0); +// +// text.setText(mPM.getApplicationLabel(ai)); +// icon.setImageDrawable(mPM.getApplicationIcon(ai)); +// } catch (final PackageManager.NameNotFoundException e) { +// // fallback +// text.setText(packageName); +// } +// } else { +// // fallback +// text.setText(packageName); +// } +// +// } +// +// @Override +// public View newView(Context context, Cursor cursor, ViewGroup parent) { +// return mInflater.inflate(R.layout.api_apps_adapter_list_item, null); +// } +// } + +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java index 2ef170dec..33cde49ba 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java @@ -15,7 +15,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -package org.sufficientlysecure.keychain.service.remote; +package org.sufficientlysecure.keychain.remote.ui; import android.content.Intent; import android.net.Uri; @@ -24,16 +24,20 @@ import android.support.v7.app.ActionBarActivity; import android.view.Menu; import android.view.MenuItem; import android.view.View; + import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.helper.ActionBarHelper; +import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.remote.AppSettings; import org.sufficientlysecure.keychain.util.Log; public class AppSettingsActivity extends ActionBarActivity { private Uri mAppUri; private AppSettingsFragment mSettingsFragment; + private AccountsListFragment mAccountsListFragment; @Override protected void onCreate(Bundle savedInstanceState) { @@ -63,7 +67,7 @@ public class AppSettingsActivity extends ActionBarActivity { return; } else { Log.d(Constants.TAG, "uri: " + mAppUri); - loadData(mAppUri); + loadData(savedInstanceState, mAppUri); } } @@ -87,9 +91,34 @@ public class AppSettingsActivity extends ActionBarActivity { return super.onOptionsItemSelected(item); } - private void loadData(Uri appUri) { + private void loadData(Bundle savedInstanceState, Uri appUri) { + // TODO: load this also like other fragment with newInstance arguments? AppSettings settings = ProviderHelper.getApiAppSettings(this, appUri); mSettingsFragment.setAppSettings(settings); + + Uri accountsUri = appUri.buildUpon().appendPath(KeychainContract.PATH_ACCOUNTS).build(); + Log.d(Constants.TAG, "accountsUri: " + accountsUri); + startListFragment(savedInstanceState, accountsUri); + } + + private void startListFragment(Bundle savedInstanceState, Uri dataUri) { + // However, if we're being restored from a previous state, + // then we don't need to do anything and should return or else + // we could end up with overlapping fragments. + if (savedInstanceState != null) { + return; + } + + // Create an instance of the fragment + mAccountsListFragment = AccountsListFragment.newInstance(dataUri); + + // Add the fragment to the 'fragment_container' FrameLayout + // NOTE: We use commitAllowingStateLoss() to prevent weird crashes! + getSupportFragmentManager().beginTransaction() + .replace(R.id.api_accounts_list_fragment, mAccountsListFragment) + .commitAllowingStateLoss(); + // do it immediately! + getSupportFragmentManager().executePendingTransactions(); } private void revokeAccess() { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java new file mode 100644 index 000000000..8bcd83fc7 --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package org.sufficientlysecure.keychain.remote.ui; + +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemSelectedListener; +import android.widget.ImageView; +import android.widget.Spinner; +import android.widget.TextView; + +import org.spongycastle.util.encoders.Hex; +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.remote.AppSettings; +import org.sufficientlysecure.keychain.ui.SelectSecretKeyLayoutFragment; +import org.sufficientlysecure.keychain.ui.adapter.KeyValueSpinnerAdapter; +import org.sufficientlysecure.keychain.util.AlgorithmNames; +import org.sufficientlysecure.keychain.util.Log; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +public class AppSettingsFragment extends Fragment { + + // model + private AppSettings mAppSettings; + + // view + private TextView mAppNameView; + private ImageView mAppIconView; + private TextView mPackageName; + private TextView mPackageSignature; + + public AppSettings getAppSettings() { + return mAppSettings; + } + + public void setAppSettings(AppSettings appSettings) { + this.mAppSettings = appSettings; + setPackage(appSettings.getPackageName()); + mPackageName.setText(appSettings.getPackageName()); + + try { + MessageDigest md = MessageDigest.getInstance("SHA-256"); + md.update(appSettings.getPackageSignature()); + byte[] digest = md.digest(); + String signature = new String(Hex.encode(digest)); + + mPackageSignature.setText(signature); + } catch (NoSuchAlgorithmException e) { + Log.e(Constants.TAG, "Should not happen!", e); + } + + } + + /** + * Inflate the layout for this fragment + */ + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.api_app_settings_fragment, container, false); + initView(view); + return view; + } + + + private void initView(View view) { + mAppNameView = (TextView) view.findViewById(R.id.api_app_settings_app_name); + mAppIconView = (ImageView) view.findViewById(R.id.api_app_settings_app_icon); + + mPackageName = (TextView) view.findViewById(R.id.api_app_settings_package_name); + mPackageSignature = (TextView) view.findViewById(R.id.api_app_settings_package_signature); + } + + private void setPackage(String packageName) { + PackageManager pm = getActivity().getApplicationContext().getPackageManager(); + + // get application name and icon from package manager + String appName = null; + Drawable appIcon = null; + try { + ApplicationInfo ai = pm.getApplicationInfo(packageName, 0); + + appName = (String) pm.getApplicationLabel(ai); + appIcon = pm.getApplicationIcon(ai); + } catch (final NameNotFoundException e) { + // fallback + appName = packageName; + } + mAppNameView.setText(appName); + mAppIconView.setImageDrawable(appIcon); + } + + +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RegisteredAppsListActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListActivity.java index f6f216efd..f86d279f0 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RegisteredAppsListActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListActivity.java @@ -15,13 +15,13 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -package org.sufficientlysecure.keychain.service.remote; +package org.sufficientlysecure.keychain.remote.ui; import android.os.Bundle; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.ui.DrawerActivity; -public class RegisteredAppsListActivity extends DrawerActivity { +public class AppsListActivity extends DrawerActivity { @Override protected void onCreate(Bundle savedInstanceState) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RegisteredAppsListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java index 25d0c7593..f3fa6e7c6 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RegisteredAppsListFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java @@ -15,10 +15,12 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -package org.sufficientlysecure.keychain.service.remote; +package org.sufficientlysecure.keychain.remote.ui; -import android.content.ContentUris; +import android.content.Context; import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; @@ -26,14 +28,22 @@ import android.support.v4.app.ListFragment; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; +import android.support.v4.widget.CursorAdapter; +import android.view.LayoutInflater; import android.view.View; +import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; +import android.widget.ImageView; +import android.widget.TextView; + +import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; +import org.sufficientlysecure.keychain.util.Log; -public class RegisteredAppsListFragment extends ListFragment implements +public class AppsListFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor> { // This is the Adapter being used to display the list's data. @@ -46,9 +56,10 @@ public class RegisteredAppsListFragment extends ListFragment implements getListView().setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) { + String selectedPackageName = mAdapter.getItemPackageName(position); // edit app settings Intent intent = new Intent(getActivity(), AppSettingsActivity.class); - intent.setData(ContentUris.withAppendedId(KeychainContract.ApiApps.CONTENT_URI, id)); + intent.setData(KeychainContract.ApiApps.buildByPackageNameUri(selectedPackageName)); startActivity(intent); } }); @@ -70,7 +81,10 @@ public class RegisteredAppsListFragment extends ListFragment implements } // These are the Contacts rows that we will retrieve. - static final String[] PROJECTION = new String[]{ApiApps._ID, ApiApps.PACKAGE_NAME}; + static final String[] PROJECTION = new String[]{ + ApiApps._ID, // 0 + ApiApps.PACKAGE_NAME // 1 + }; public Loader<Cursor> onCreateLoader(int id, Bundle args) { // This is called when a new Loader needs to be created. This @@ -98,4 +112,65 @@ public class RegisteredAppsListFragment extends ListFragment implements mAdapter.swapCursor(null); } + private class RegisteredAppsAdapter extends CursorAdapter { + + private LayoutInflater mInflater; + private PackageManager mPM; + + public RegisteredAppsAdapter(Context context, Cursor c, int flags) { + super(context, c, flags); + + mInflater = LayoutInflater.from(context); + mPM = context.getApplicationContext().getPackageManager(); + } + + /** + * Similar to CursorAdapter.getItemId(). + * Required to build Uris for api app view, which is not based on row ids + * + * @param position + * @return + */ + public String getItemPackageName(int position) { + if (mDataValid && mCursor != null) { + if (mCursor.moveToPosition(position)) { + return mCursor.getString(1); + } else { + return null; + } + } else { + return null; + } + } + + @Override + public void bindView(View view, Context context, Cursor cursor) { + TextView text = (TextView) view.findViewById(R.id.api_apps_adapter_item_name); + ImageView icon = (ImageView) view.findViewById(R.id.api_apps_adapter_item_icon); + + String packageName = cursor.getString(cursor.getColumnIndex(ApiApps.PACKAGE_NAME)); + if (packageName != null) { + // get application name + try { + ApplicationInfo ai = mPM.getApplicationInfo(packageName, 0); + + text.setText(mPM.getApplicationLabel(ai)); + icon.setImageDrawable(mPM.getApplicationIcon(ai)); + } catch (final PackageManager.NameNotFoundException e) { + // fallback + text.setText(packageName); + } + } else { + // fallback + text.setText(packageName); + } + + } + + @Override + public View newView(Context context, Cursor cursor, ViewGroup parent) { + return mInflater.inflate(R.layout.api_apps_adapter_list_item, null); + } + } + } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java index e20114853..d3ac5cade 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java @@ -15,7 +15,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -package org.sufficientlysecure.keychain.service.remote; +package org.sufficientlysecure.keychain.remote.ui; import android.content.Intent; import android.os.Bundle; @@ -24,6 +24,7 @@ import android.os.Message; import android.os.Messenger; import android.support.v7.app.ActionBarActivity; import android.view.View; + import org.openintents.openpgp.util.OpenPgpApi; import org.sufficientlysecure.htmltextview.HtmlTextView; import org.sufficientlysecure.keychain.Constants; @@ -31,7 +32,10 @@ import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.helper.ActionBarHelper; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.remote.AccountSettings; +import org.sufficientlysecure.keychain.remote.AppSettings; import org.sufficientlysecure.keychain.ui.SelectPublicKeyFragment; import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; import org.sufficientlysecure.keychain.util.Log; @@ -41,6 +45,8 @@ import java.util.ArrayList; public class RemoteServiceActivity extends ActionBarActivity { public static final String ACTION_REGISTER = Constants.INTENT_PREFIX + "API_ACTIVITY_REGISTER"; + public static final String ACTION_CREATE_ACCOUNT = Constants.INTENT_PREFIX + + "API_ACTIVITY_CREATE_ACCOUNT"; public static final String ACTION_CACHE_PASSPHRASE = Constants.INTENT_PREFIX + "API_ACTIVITY_CACHE_PASSPHRASE"; public static final String ACTION_SELECT_PUB_KEYS = Constants.INTENT_PREFIX @@ -57,6 +63,8 @@ public class RemoteServiceActivity extends ActionBarActivity { // register action public static final String EXTRA_PACKAGE_NAME = "package_name"; public static final String EXTRA_PACKAGE_SIGNATURE = "package_signature"; + // create acc action + public static final String EXTRA_ACC_NAME = "acc_name"; // select pub keys action public static final String EXTRA_SELECTED_MASTER_KEY_IDS = "master_key_ids"; public static final String EXTRA_MISSING_USER_IDS = "missing_user_ids"; @@ -65,7 +73,9 @@ public class RemoteServiceActivity extends ActionBarActivity { public static final String EXTRA_ERROR_MESSAGE = "error_message"; // register view - private AppSettingsFragment mSettingsFragment; + private AppSettingsFragment mAppSettingsFragment; + // create acc view + private AccountSettingsFragment mAccSettingsFragment; // select pub keys view private SelectPublicKeyFragment mSelectFragment; @@ -94,13 +104,52 @@ public class RemoteServiceActivity extends ActionBarActivity { public void onClick(View v) { // Allow + ProviderHelper.insertApiApp(RemoteServiceActivity.this, + mAppSettingsFragment.getAppSettings()); + + // give data through for new service call + Intent resultData = extras.getParcelable(EXTRA_DATA); + RemoteServiceActivity.this.setResult(RESULT_OK, resultData); + RemoteServiceActivity.this.finish(); + } + }, R.string.api_register_disallow, R.drawable.ic_action_cancel, + new View.OnClickListener() { + @Override + public void onClick(View v) { + // Disallow + RemoteServiceActivity.this.setResult(RESULT_CANCELED); + RemoteServiceActivity.this.finish(); + } + } + ); + + setContentView(R.layout.api_app_register_activity); + + mAppSettingsFragment = (AppSettingsFragment) getSupportFragmentManager().findFragmentById( + R.id.api_app_settings_fragment); + + AppSettings settings = new AppSettings(packageName, packageSignature); + mAppSettingsFragment.setAppSettings(settings); + } else if (ACTION_CREATE_ACCOUNT.equals(action)) { + final String packageName = extras.getString(EXTRA_PACKAGE_NAME); + final String accName = extras.getString(EXTRA_ACC_NAME); + + // Inflate a "Done"/"Cancel" custom action bar view + ActionBarHelper.setTwoButtonView(getSupportActionBar(), + R.string.api_settings_save, R.drawable.ic_action_done, + new View.OnClickListener() { + @Override + public void onClick(View v) { + // Save + // user needs to select a key! - if (mSettingsFragment.getAppSettings().getKeyId() == Id.key.none) { - mSettingsFragment.setErrorOnSelectKeyFragment( + if (mAccSettingsFragment.getAccSettings().getKeyId() == Id.key.none) { + mAccSettingsFragment.setErrorOnSelectKeyFragment( getString(R.string.api_register_error_select_key)); } else { - ProviderHelper.insertApiApp(RemoteServiceActivity.this, - mSettingsFragment.getAppSettings()); + ProviderHelper.insertApiAccount(RemoteServiceActivity.this, + KeychainContract.ApiAccounts.buildBaseUri(packageName), + mAccSettingsFragment.getAccSettings()); // give data through for new service call Intent resultData = extras.getParcelable(EXTRA_DATA); @@ -108,24 +157,24 @@ public class RemoteServiceActivity extends ActionBarActivity { RemoteServiceActivity.this.finish(); } } - }, R.string.api_register_disallow, R.drawable.ic_action_cancel, - new View.OnClickListener() { - @Override - public void onClick(View v) { - // Disallow - RemoteServiceActivity.this.setResult(RESULT_CANCELED); - RemoteServiceActivity.this.finish(); - } + }, R.string.api_settings_cancel, R.drawable.ic_action_cancel, + new View.OnClickListener() { + @Override + public void onClick(View v) { + // Cancel + RemoteServiceActivity.this.setResult(RESULT_CANCELED); + RemoteServiceActivity.this.finish(); + } } ); - setContentView(R.layout.api_app_register_activity); + setContentView(R.layout.api_account_create_activity); - mSettingsFragment = (AppSettingsFragment) getSupportFragmentManager().findFragmentById( - R.id.api_app_settings_fragment); + mAccSettingsFragment = (AccountSettingsFragment) getSupportFragmentManager().findFragmentById( + R.id.api_account_settings_fragment); - AppSettings settings = new AppSettings(packageName, packageSignature); - mSettingsFragment.setAppSettings(settings); + AccountSettings settings = new AccountSettings(accName); + mAccSettingsFragment.setAccSettings(settings); } else if (ACTION_CACHE_PASSPHRASE.equals(action)) { long secretKeyId = extras.getLong(EXTRA_SECRET_KEY_ID); Intent resultData = extras.getParcelable(EXTRA_DATA); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index e26ee3c76..bd3a0421b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -855,7 +855,7 @@ public class KeychainIntentService extends IntentService if (this.mIsCanceled) { return; } - Log.e(Constants.TAG, "ApgService Exception: ", e); + Log.e(Constants.TAG, "KeychainIntentService Exception: ", e); e.printStackTrace(); Bundle data = new Bundle(); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RegisteredAppsAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RegisteredAppsAdapter.java deleted file mode 100644 index e0dc4162f..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RegisteredAppsAdapter.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -package org.sufficientlysecure.keychain.service.remote; - -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.database.Cursor; -import android.support.v4.widget.CursorAdapter; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.TextView; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; - -public class RegisteredAppsAdapter extends CursorAdapter { - - private LayoutInflater mInflater; - private PackageManager mPM; - - public RegisteredAppsAdapter(Context context, Cursor c, int flags) { - super(context, c, flags); - - mInflater = LayoutInflater.from(context); - mPM = context.getApplicationContext().getPackageManager(); - } - - @Override - public void bindView(View view, Context context, Cursor cursor) { - TextView text = (TextView) view.findViewById(R.id.api_apps_adapter_item_name); - ImageView icon = (ImageView) view.findViewById(R.id.api_apps_adapter_item_icon); - - String packageName = cursor.getString(cursor.getColumnIndex(ApiApps.PACKAGE_NAME)); - if (packageName != null) { - // get application name - try { - ApplicationInfo ai = mPM.getApplicationInfo(packageName, 0); - - text.setText(mPM.getApplicationLabel(ai)); - icon.setImageDrawable(mPM.getApplicationIcon(ai)); - } catch (final NameNotFoundException e) { - // fallback - text.setText(packageName); - } - } else { - // fallback - text.setText(packageName); - } - - } - - @Override - public View newView(Context context, Cursor cursor, ViewGroup parent) { - return mInflater.inflate(R.layout.api_apps_adapter_list_item, null); - } - -} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java index dff4e9d72..5dc06c16d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java @@ -327,11 +327,11 @@ public class CertifyKeyActivity extends ActionBarActivity implements intent.putExtra(KeychainIntentService.EXTRA_DATA, data); - // Message is received after signing is done in ApgService + // Message is received after signing is done in KeychainIntentService KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this, getString(R.string.progress_signing), ProgressDialog.STYLE_SPINNER) { public void handleMessage(Message message) { - // handle messages by standard ApgHandler first + // handle messages by standard KeychainIntentServiceHandler first super.handleMessage(message); if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { @@ -380,11 +380,11 @@ public class CertifyKeyActivity extends ActionBarActivity implements intent.putExtra(KeychainIntentService.EXTRA_DATA, data); - // Message is received after uploading is done in ApgService + // Message is received after uploading is done in KeychainIntentService KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this, getString(R.string.progress_exporting), ProgressDialog.STYLE_HORIZONTAL) { public void handleMessage(Message message) { - // handle messages by standard ApgHandler first + // handle messages by standard KeychainIntentServiceHandler first super.handleMessage(message); if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java index 3e389c034..9b3b00c19 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java @@ -443,8 +443,7 @@ public class DecryptActivity extends DrawerActivity { getDecryptionKeyFromInputStream(); // if we need a symmetric passphrase or a passphrase to use a secret key ask for it - if (mSecretKeyId == Id.key.symmetric - || PassphraseCacheService.getCachedPassphrase(this, mSecretKeyId) == null) { + if (mAssumeSymmetricEncryption || PassphraseCacheService.getCachedPassphrase(this, mSecretKeyId) == null) { showPassphraseDialog(); } else { if (mDecryptTarget == Id.target.file) { @@ -494,6 +493,7 @@ public class DecryptActivity extends DrawerActivity { * TODO: Rework function, remove global variables */ private void getDecryptionKeyFromInputStream() { + mAssumeSymmetricEncryption = false; InputStream inStream = null; if (mContentUri != null) { try { @@ -517,13 +517,6 @@ public class DecryptActivity extends DrawerActivity { Log.e(Constants.TAG, "File not found!", e); AppMsg.makeText(this, getString(R.string.error_file_not_found, e.getMessage()), AppMsg.STYLE_ALERT).show(); - } finally { - try { - if (inStream != null) { - inStream.close(); - } - } catch (Exception e) { - } } } else { inStream = new ByteArrayInputStream(mMessage.getText().toString().getBytes()); @@ -540,7 +533,6 @@ public class DecryptActivity extends DrawerActivity { if (mSecretKeyId == Id.key.none) { throw new PgpGeneralException(getString(R.string.error_no_secret_key_found)); } - mAssumeSymmetricEncryption = false; } catch (NoAsymmetricEncryptionException e) { if (inStream.markSupported()) { inStream.reset(); @@ -553,6 +545,7 @@ public class DecryptActivity extends DrawerActivity { mAssumeSymmetricEncryption = true; } } catch (Exception e) { + Log.e(Constants.TAG, "error while reading decryption key from input stream", e); AppMsg.makeText(this, getString(R.string.error_message, e.getMessage()), AppMsg.STYLE_ALERT).show(); } @@ -638,11 +631,11 @@ public class DecryptActivity extends DrawerActivity { intent.putExtra(KeychainIntentService.EXTRA_DATA, data); - // Message is received after encrypting is done in ApgService + // Message is received after encrypting is done in KeychainIntentService KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this, getString(R.string.progress_decrypting), ProgressDialog.STYLE_HORIZONTAL) { public void handleMessage(Message message) { - // handle messages by standard ApgHandler first + // handle messages by standard KeychainIntentServiceHandler first super.handleMessage(message); if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index 092a502e1..6eb5b9d2d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -180,7 +180,7 @@ public class EditKeyActivity extends ActionBarActivity { serviceIntent.putExtra(KeychainIntentService.EXTRA_DATA, data); - // Message is received after generating is done in ApgService + // Message is received after generating is done in KeychainIntentService KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler( this, getResources().getQuantityString(R.plurals.progress_generating, 1), ProgressDialog.STYLE_HORIZONTAL, true, @@ -197,7 +197,7 @@ public class EditKeyActivity extends ActionBarActivity { @Override public void handleMessage(Message message) { - // handle messages by standard ApgHandler first + // handle messages by standard KeychainIntentServiceHandler first super.handleMessage(message); if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { @@ -540,11 +540,11 @@ public class EditKeyActivity extends ActionBarActivity { intent.putExtra(KeychainIntentService.EXTRA_DATA, data); - // Message is received after saving is done in ApgService + // Message is received after saving is done in KeychainIntentService KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this, getString(R.string.progress_saving), ProgressDialog.STYLE_HORIZONTAL) { public void handleMessage(Message message) { - // handle messages by standard ApgHandler first + // handle messages by standard KeychainIntentServiceHandler first super.handleMessage(message); if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java index 4ccfd393f..4f18f69d7 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java @@ -597,11 +597,11 @@ public class EncryptActivity extends DrawerActivity { intent.putExtra(KeychainIntentService.EXTRA_DATA, data); - // Message is received after encrypting is done in ApgService + // Message is received after encrypting is done in KeychainIntentService KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this, getString(R.string.progress_encrypting), ProgressDialog.STYLE_HORIZONTAL) { public void handleMessage(Message message) { - // handle messages by standard ApgHandler first + // handle messages by standard KeychainIntentServiceHandler first super.handleMessage(message); if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index 05bfc613e..834509f53 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -363,7 +363,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa * Import keys with mImportData */ public void importKeys() { - // Message is received after importing is done in ApgService + // Message is received after importing is done in KeychainIntentService KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler( this, getString(R.string.progress_importing), diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java index 2c8f66488..0e231e6a8 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java @@ -98,11 +98,11 @@ public class UploadKeyActivity extends ActionBarActivity { intent.putExtra(KeychainIntentService.EXTRA_DATA, data); - // Message is received after uploading is done in ApgService + // Message is received after uploading is done in KeychainIntentService KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this, getString(R.string.progress_exporting), ProgressDialog.STYLE_HORIZONTAL) { public void handleMessage(Message message) { - // handle messages by standard ApgHandler first + // handle messages by standard KeychainIntentServiceHandler first super.handleMessage(message); if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java index b067010df..b4c38184c 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java @@ -87,11 +87,11 @@ public class DeleteFileDialogFragment extends DialogFragment { false, null); - // Message is received after deleting is done in ApgService + // Message is received after deleting is done in KeychainIntentService KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(activity, deletingDialog) { public void handleMessage(Message message) { - // handle messages by standard ApgHandler first + // handle messages by standard KeychainIntentHandler first super.handleMessage(message); if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java index e5b6003b1..1ef178f15 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java @@ -256,11 +256,11 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor } }); - // Message is received after generating is done in ApgService + // Message is received after generating is done in KeychainIntentService KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(mActivity, mGeneratingDialog) { public void handleMessage(Message message) { - // handle messages by standard ApgHandler first + // handle messages by standard KeychainIntentServiceHandler first super.handleMessage(message); if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { diff --git a/OpenPGP-Keychain/src/main/res/layout/api_account_create_activity.xml b/OpenPGP-Keychain/src/main/res/layout/api_account_create_activity.xml new file mode 100644 index 000000000..ead336dbb --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/layout/api_account_create_activity.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:padding="16dp" + android:orientation="vertical"> + + <fragment + android:id="@+id/api_account_settings_fragment" + android:name="org.sufficientlysecure.keychain.remote.ui.AccountSettingsFragment" + android:layout_width="match_parent" + android:layout_height="wrap_content" + tools:layout="@layout/api_app_settings_fragment" /> + + </LinearLayout> +</ScrollView> diff --git a/OpenPGP-Keychain/src/main/res/layout/api_account_settings_fragment.xml b/OpenPGP-Keychain/src/main/res/layout/api_account_settings_fragment.xml new file mode 100644 index 000000000..3284b5b0a --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/layout/api_account_settings_fragment.xml @@ -0,0 +1,115 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + xmlns:custom="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <RelativeLayout + android:layout_width="match_parent" + android:layout_height="?android:attr/listPreferredItemHeight" + android:layout_marginBottom="4dp" + android:layout_marginTop="4dp" + android:gravity="center_horizontal" + android:orientation="horizontal"> + + <ImageView + android:id="@+id/api_account_settings_app_icon" + android:layout_width="48dp" + android:layout_height="48dp" + android:layout_alignParentBottom="true" + android:layout_alignParentTop="true" + android:layout_marginRight="6dp" + android:src="@drawable/icon" /> + + <TextView + android:id="@+id/api_account_settings_app_name" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_centerVertical="true" + android:layout_toRightOf="@+id/api_app_settings_app_icon" + android:gravity="center_vertical" + android:orientation="vertical" + android:text="Name (set in-code)" + android:textAppearance="?android:attr/textAppearanceMedium" /> + </RelativeLayout> + + <fragment + android:id="@+id/api_account_settings_select_key_fragment" + android:name="org.sufficientlysecure.keychain.ui.SelectSecretKeyLayoutFragment" + android:layout_width="match_parent" + android:layout_height="wrap_content" + tools:layout="@layout/select_secret_key_layout_fragment" /> + + <org.sufficientlysecure.keychain.ui.widget.FoldableLinearLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + custom:foldedLabel="@string/api_settings_show_advanced" + custom:unFoldedLabel="@string/api_settings_hide_advanced" + custom:foldedIcon="fa-chevron-right" + custom:unFoldedIcon="fa-chevron-down"> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/label_encryption_algorithm" + android:textAppearance="?android:attr/textAppearanceMedium" /> + + <Spinner + android:id="@+id/api_account_settings_encryption_algorithm" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/label_hash_algorithm" + android:textAppearance="?android:attr/textAppearanceMedium" /> + + <Spinner + android:id="@+id/api_account_settings_hash_algorithm" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/label_message_compression" + android:textAppearance="?android:attr/textAppearanceMedium" /> + + <Spinner + android:id="@+id/api_account_settings_compression" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/api_settings_package_name" + android:textAppearance="?android:attr/textAppearanceMedium" /> + + <TextView + android:id="@+id/api_account_settings_package_name" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="com.example" + android:textAppearance="?android:attr/textAppearanceSmall" /> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/api_settings_package_signature" + android:textAppearance="?android:attr/textAppearanceMedium" /> + + <TextView + android:id="@+id/api_account_settings_package_signature" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="Base64 encoded signature" + android:textAppearance="?android:attr/textAppearanceSmall" /> + + </org.sufficientlysecure.keychain.ui.widget.FoldableLinearLayout> + +</LinearLayout>
\ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/res/layout/api_app_register_activity.xml b/OpenPGP-Keychain/src/main/res/layout/api_app_register_activity.xml index aa9d59004..f85f3b8f7 100644 --- a/OpenPGP-Keychain/src/main/res/layout/api_app_register_activity.xml +++ b/OpenPGP-Keychain/src/main/res/layout/api_app_register_activity.xml @@ -20,7 +20,7 @@ <fragment android:id="@+id/api_app_settings_fragment" - android:name="org.sufficientlysecure.keychain.service.remote.AppSettingsFragment" + android:name="org.sufficientlysecure.keychain.remote.ui.AppSettingsFragment" android:layout_width="match_parent" android:layout_height="wrap_content" tools:layout="@layout/api_app_settings_fragment" /> diff --git a/OpenPGP-Keychain/src/main/res/layout/api_app_settings_activity.xml b/OpenPGP-Keychain/src/main/res/layout/api_app_settings_activity.xml index d83c8e87d..d38567497 100644 --- a/OpenPGP-Keychain/src/main/res/layout/api_app_settings_activity.xml +++ b/OpenPGP-Keychain/src/main/res/layout/api_app_settings_activity.xml @@ -12,10 +12,24 @@ <fragment android:id="@+id/api_app_settings_fragment" - android:name="org.sufficientlysecure.keychain.service.remote.AppSettingsFragment" + android:name="org.sufficientlysecure.keychain.remote.ui.AppSettingsFragment" android:layout_width="match_parent" android:layout_height="wrap_content" tools:layout="@layout/api_app_settings_fragment" /> + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/api_settings_accounts" + android:textAppearance="?android:attr/textAppearanceMedium" /> + + <FrameLayout + android:id="@+id/api_accounts_list_fragment" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + android:paddingLeft="4dp" + android:paddingRight="4dp" /> + </LinearLayout> </ScrollView> diff --git a/OpenPGP-Keychain/src/main/res/layout/api_app_settings_fragment.xml b/OpenPGP-Keychain/src/main/res/layout/api_app_settings_fragment.xml index a7917ad4e..96271d418 100644 --- a/OpenPGP-Keychain/src/main/res/layout/api_app_settings_fragment.xml +++ b/OpenPGP-Keychain/src/main/res/layout/api_app_settings_fragment.xml @@ -36,57 +36,17 @@ android:textAppearance="?android:attr/textAppearanceMedium" /> </RelativeLayout> - <fragment - android:id="@+id/api_app_settings_select_key_fragment" - android:name="org.sufficientlysecure.keychain.ui.SelectSecretKeyLayoutFragment" - android:layout_width="match_parent" - android:layout_height="wrap_content" - tools:layout="@layout/select_secret_key_layout_fragment" /> - <org.sufficientlysecure.keychain.ui.widget.FoldableLinearLayout android:layout_width="match_parent" android:layout_height="match_parent" - custom:foldedLabel="@string/btn_encryption_advanced_settings_show" - custom:unFoldedLabel="@string/btn_encryption_advanced_settings_hide" + custom:foldedLabel="@string/api_settings_show_info" + custom:unFoldedLabel="@string/api_settings_hide_info" custom:foldedIcon="fa-chevron-right" custom:unFoldedIcon="fa-chevron-down"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" - android:text="@string/label_encryption_algorithm" - android:textAppearance="?android:attr/textAppearanceMedium" /> - - <Spinner - android:id="@+id/api_app_settings_encryption_algorithm" - android:layout_width="match_parent" - android:layout_height="wrap_content" /> - - <TextView - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:text="@string/label_hash_algorithm" - android:textAppearance="?android:attr/textAppearanceMedium" /> - - <Spinner - android:id="@+id/api_app_settings_hash_algorithm" - android:layout_width="match_parent" - android:layout_height="wrap_content" /> - - <TextView - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:text="@string/label_message_compression" - android:textAppearance="?android:attr/textAppearanceMedium" /> - - <Spinner - android:id="@+id/api_app_settings_compression" - android:layout_width="match_parent" - android:layout_height="wrap_content" /> - - <TextView - android:layout_width="match_parent" - android:layout_height="wrap_content" android:text="@string/api_settings_package_name" android:textAppearance="?android:attr/textAppearanceMedium" /> diff --git a/OpenPGP-Keychain/src/main/res/layout/api_apps_list_content.xml b/OpenPGP-Keychain/src/main/res/layout/api_apps_list_content.xml index b8606b929..9f9b99045 100644 --- a/OpenPGP-Keychain/src/main/res/layout/api_apps_list_content.xml +++ b/OpenPGP-Keychain/src/main/res/layout/api_apps_list_content.xml @@ -8,7 +8,7 @@ <fragment android:id="@+id/crypto_consumers_list_fragment" - android:name="org.sufficientlysecure.keychain.service.remote.RegisteredAppsListFragment" + android:name="org.sufficientlysecure.keychain.remote.ui.AppsListFragment" android:layout_width="match_parent" android:layout_height="match_parent"/> </FrameLayout>
\ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/res/layout/encrypt_content.xml b/OpenPGP-Keychain/src/main/res/layout/encrypt_content.xml index 03fe496c6..1dba66cfa 100644 --- a/OpenPGP-Keychain/src/main/res/layout/encrypt_content.xml +++ b/OpenPGP-Keychain/src/main/res/layout/encrypt_content.xml @@ -72,7 +72,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" - android:paddingLeft="16dp"> + android:paddingLeft="16dp" + android:paddingRight="4dip"> <TextView android:id="@+id/mainUserId" @@ -314,4 +315,4 @@ bootstrapbutton:bb_type="info"/> </LinearLayout> </LinearLayout> -</ScrollView>
\ No newline at end of file +</ScrollView> diff --git a/OpenPGP-Keychain/src/main/res/raw-cs-rCZ/help_about.html b/OpenPGP-Keychain/src/main/res/raw-cs-rCZ/help_about.html index 863aeee58..d9150a5e8 100644 --- a/OpenPGP-Keychain/src/main/res/raw-cs-rCZ/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-cs-rCZ/help_about.html @@ -11,13 +11,18 @@ <li>Ash Hughes (crypto patches)</li> <li>Brian C. Barnes</li> <li>Bahtiar 'kalkin' Gadimov (UI)</li> +<li>Daniel Hammann</li> +<li>Daniel Haß</li> +<li>Greg Witczak</li> +<li>Miroojin Bakshi</li> +<li>Paul Sarbinowski</li> +<li>Vincent Breitmoser</li> </ul> <h2>Developers APG 1.x</h2> <ul> -<li>'Thialfihar' (Lead developer)</li> +<li>Thialfihar (Lead developer)</li> <li>'Senecaso' (QRCode, sign key, upload key)</li> -<li>Oliver Runge</li> <li>Markus Doits</li> </ul> <h2>Libraries</h2> @@ -38,8 +43,6 @@ <a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache License v2)</li> <li> <a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Library</a> (Apache License v2)</li> -<li>Icons from <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Creative Commons Attribution Share-Alike licence 3.0)</li> -<li>Icons from <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (Public Domain)</li> </ul> </body> </html> diff --git a/OpenPGP-Keychain/src/main/res/raw-cs-rCZ/help_start.html b/OpenPGP-Keychain/src/main/res/raw-cs-rCZ/help_start.html index 3a6443a2f..0e60c17a7 100644 --- a/OpenPGP-Keychain/src/main/res/raw-cs-rCZ/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-cs-rCZ/help_start.html @@ -2,7 +2,7 @@ <head></head> <body> <h2>Getting started</h2> -<p>First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p> +<p>First you need a personal key pair. Create one via the option menus in "Contacts" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p> <p>It is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection and <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.</p> diff --git a/OpenPGP-Keychain/src/main/res/raw-de/help_about.html b/OpenPGP-Keychain/src/main/res/raw-de/help_about.html index 37d4193f7..676c2bdd2 100644 --- a/OpenPGP-Keychain/src/main/res/raw-de/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-de/help_about.html @@ -11,13 +11,18 @@ <li>Ash Hughes (crypto patches)</li> <li>Brian C. Barnes</li> <li>Bahtiar 'kalkin' Gadimov (UI)</li> +<li>Daniel Hammann</li> +<li>Daniel Haß</li> +<li>Greg Witczak</li> +<li>Miroojin Bakshi</li> +<li>Paul Sarbinowski</li> +<li>Vincent Breitmoser</li> </ul> <h2>Entwickler APG 1.x</h2> <ul> -<li>'Thialfihar' (Leitender Entwickler)</li> +<li>Thialfihar (Leitender Entwickler)</li> <li>'Senecaso' (QR-Code, Schlüssel signtieren, Schlüssel hochladen)</li> -<li>Oliver Runge</li> <li>Markus Doits</li> </ul> <h2>Bibliotheken</h2> @@ -38,8 +43,6 @@ <a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache Lizenz v2)</li> <li> <a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Bibliothek</a> (Apache Lizenz v2)</li> -<li>Icons von <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Creative Commons Attribution Share-Alike Lizenz 3.0)</li> -<li>Icons von <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (Public Domain)</li> </ul> </body> </html> diff --git a/OpenPGP-Keychain/src/main/res/raw-de/help_start.html b/OpenPGP-Keychain/src/main/res/raw-de/help_start.html index a7949dd64..7a652682e 100644 --- a/OpenPGP-Keychain/src/main/res/raw-de/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-de/help_start.html @@ -2,7 +2,7 @@ <head></head> <body> <h2>Los gehts</h2> -<p>First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p> +<p>First you need a personal key pair. Create one via the option menus in "Contacts" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p> <p>It is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection and <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.</p> diff --git a/OpenPGP-Keychain/src/main/res/raw-el/help_about.html b/OpenPGP-Keychain/src/main/res/raw-el/help_about.html index 863aeee58..d9150a5e8 100644 --- a/OpenPGP-Keychain/src/main/res/raw-el/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-el/help_about.html @@ -11,13 +11,18 @@ <li>Ash Hughes (crypto patches)</li> <li>Brian C. Barnes</li> <li>Bahtiar 'kalkin' Gadimov (UI)</li> +<li>Daniel Hammann</li> +<li>Daniel Haß</li> +<li>Greg Witczak</li> +<li>Miroojin Bakshi</li> +<li>Paul Sarbinowski</li> +<li>Vincent Breitmoser</li> </ul> <h2>Developers APG 1.x</h2> <ul> -<li>'Thialfihar' (Lead developer)</li> +<li>Thialfihar (Lead developer)</li> <li>'Senecaso' (QRCode, sign key, upload key)</li> -<li>Oliver Runge</li> <li>Markus Doits</li> </ul> <h2>Libraries</h2> @@ -38,8 +43,6 @@ <a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache License v2)</li> <li> <a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Library</a> (Apache License v2)</li> -<li>Icons from <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Creative Commons Attribution Share-Alike licence 3.0)</li> -<li>Icons from <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (Public Domain)</li> </ul> </body> </html> diff --git a/OpenPGP-Keychain/src/main/res/raw-el/help_start.html b/OpenPGP-Keychain/src/main/res/raw-el/help_start.html index 3a6443a2f..0e60c17a7 100644 --- a/OpenPGP-Keychain/src/main/res/raw-el/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-el/help_start.html @@ -2,7 +2,7 @@ <head></head> <body> <h2>Getting started</h2> -<p>First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p> +<p>First you need a personal key pair. Create one via the option menus in "Contacts" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p> <p>It is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection and <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.</p> diff --git a/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_about.html b/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_about.html index 863aeee58..d9150a5e8 100644 --- a/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_about.html @@ -11,13 +11,18 @@ <li>Ash Hughes (crypto patches)</li> <li>Brian C. Barnes</li> <li>Bahtiar 'kalkin' Gadimov (UI)</li> +<li>Daniel Hammann</li> +<li>Daniel Haß</li> +<li>Greg Witczak</li> +<li>Miroojin Bakshi</li> +<li>Paul Sarbinowski</li> +<li>Vincent Breitmoser</li> </ul> <h2>Developers APG 1.x</h2> <ul> -<li>'Thialfihar' (Lead developer)</li> +<li>Thialfihar (Lead developer)</li> <li>'Senecaso' (QRCode, sign key, upload key)</li> -<li>Oliver Runge</li> <li>Markus Doits</li> </ul> <h2>Libraries</h2> @@ -38,8 +43,6 @@ <a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache License v2)</li> <li> <a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Library</a> (Apache License v2)</li> -<li>Icons from <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Creative Commons Attribution Share-Alike licence 3.0)</li> -<li>Icons from <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (Public Domain)</li> </ul> </body> </html> diff --git a/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_start.html b/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_start.html index 3a6443a2f..0e60c17a7 100644 --- a/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_start.html @@ -2,7 +2,7 @@ <head></head> <body> <h2>Getting started</h2> -<p>First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p> +<p>First you need a personal key pair. Create one via the option menus in "Contacts" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p> <p>It is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection and <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.</p> diff --git a/OpenPGP-Keychain/src/main/res/raw-es/help_about.html b/OpenPGP-Keychain/src/main/res/raw-es/help_about.html index 95189425d..552155d68 100644 --- a/OpenPGP-Keychain/src/main/res/raw-es/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-es/help_about.html @@ -11,13 +11,18 @@ <li>Ash Hughes (Parches cryptográficos)</li> <li>Brian C. Barnes</li> <li>Bahtiar 'kalkin' Gadimov (UI)</li> +<li>Daniel Hammann</li> +<li>Daniel Haß</li> +<li>Greg Witczak</li> +<li>Miroojin Bakshi</li> +<li>Paul Sarbinowski</li> +<li>Vincent Breitmoser</li> </ul> <h2>Desarrolladores de APG 1.x</h2> <ul> -<li>'Thialfihar' (Desarrollador principal)</li> +<li>Thialfihar (Desarrollador principal)</li> <li>'Senecaso' (Código QR, clave de firma, carga de clave)</li> -<li>Oliver Runge</li> <li>Markus Doits</li> </ul> <h2>Librerías</h2> @@ -38,8 +43,6 @@ <a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Licencia Apache v2)</li> <li> <a href="https://github.com/johnkil/Android-AppMsg">Librería Android AppMsg</a> (Licencia Apache v2)</li> -<li>Icons de <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Creative Commons Attribution Compartir-Igual licencia 3.0)</li> -<li>Iconos de <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (Dominio Público)</li> </ul> </body> </html> diff --git a/OpenPGP-Keychain/src/main/res/raw-es/help_start.html b/OpenPGP-Keychain/src/main/res/raw-es/help_start.html index 2907bbc99..895b52469 100644 --- a/OpenPGP-Keychain/src/main/res/raw-es/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-es/help_start.html @@ -2,7 +2,7 @@ <head></head> <body> <h2>Primeros pasos</h2> -<p>Primero necesitas un par de claves personales. Crea una a través del menú "Mis claves" o importa un par de claves ya existentes a través de "Importar claves". Después, puedes descargar las claves de tus amigos o intercambiarlas a través de códigos QR o NFC.</p> +<p>Primero necesitas un par de claves personales. Crea una a través del menú "Contactos" o importa un par de claves ya existentes a través de "Importar claves". Después, puedes descargar las claves de tus amigos o intercambiarlas a través de códigos QR o NFC.</p> <p>Es recomendable que instales <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> para una mejor selección de archivos y <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> para escanear los códigos QR generados. Pulsando en los enlaces se abrirá Google Play o F-Droid.</p> diff --git a/OpenPGP-Keychain/src/main/res/raw-fa-rIR/help_about.html b/OpenPGP-Keychain/src/main/res/raw-fa-rIR/help_about.html index 863aeee58..d9150a5e8 100644 --- a/OpenPGP-Keychain/src/main/res/raw-fa-rIR/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-fa-rIR/help_about.html @@ -11,13 +11,18 @@ <li>Ash Hughes (crypto patches)</li> <li>Brian C. Barnes</li> <li>Bahtiar 'kalkin' Gadimov (UI)</li> +<li>Daniel Hammann</li> +<li>Daniel Haß</li> +<li>Greg Witczak</li> +<li>Miroojin Bakshi</li> +<li>Paul Sarbinowski</li> +<li>Vincent Breitmoser</li> </ul> <h2>Developers APG 1.x</h2> <ul> -<li>'Thialfihar' (Lead developer)</li> +<li>Thialfihar (Lead developer)</li> <li>'Senecaso' (QRCode, sign key, upload key)</li> -<li>Oliver Runge</li> <li>Markus Doits</li> </ul> <h2>Libraries</h2> @@ -38,8 +43,6 @@ <a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache License v2)</li> <li> <a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Library</a> (Apache License v2)</li> -<li>Icons from <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Creative Commons Attribution Share-Alike licence 3.0)</li> -<li>Icons from <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (Public Domain)</li> </ul> </body> </html> diff --git a/OpenPGP-Keychain/src/main/res/raw-fr/help_about.html b/OpenPGP-Keychain/src/main/res/raw-fr/help_about.html index 3cbbce4d5..43094ce9d 100644 --- a/OpenPGP-Keychain/src/main/res/raw-fr/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-fr/help_about.html @@ -11,13 +11,18 @@ <li>Ash Hughes (correctif crypto)</li> <li>Brian C. Barnes</li> <li>Bahtiar « kalkin » Gadimov (interface utilisateur)</li> +<li>Daniel Hammann</li> +<li>Daniel Haß</li> +<li>Greg Witczak</li> +<li>Miroojin Bakshi</li> +<li>Paul Sarbinowski</li> +<li>Vincent Breitmoser</li> </ul> <h2>Les développeurs d'APG 1.x</h2> <ul> -<li>« Thialfihar (développeur principal)</li> +<li>Thialfihar (développeur principal)</li> <li>« Senecaso » (Code QR, signer/téléverser la clef)</li> -<li>Oliver Runge</li> <li>Markus Doits</li> </ul> <h2>Bibliothèques</h2> @@ -38,8 +43,6 @@ <a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Licence Apache v2)</li> <li> <a href="https://github.com/johnkil/Android-AppMsg">Bibliothèque Android AppMsg</a> (Licence Apache v2)</li> -<li>Icônes du <a href="http://rrze-icon-set.berlios.de/">jeu d'icônes RRZE</a> (Licence Creative Commons Paternité - Partage des Conditions Initiales à l'Identique 3.0)</li> -<li>Icônes du <a href="http://tango.freedesktop.org/">jeu d'icônes Tango</a> (domaine public)</li> </ul> </body> </html> diff --git a/OpenPGP-Keychain/src/main/res/raw-fr/help_start.html b/OpenPGP-Keychain/src/main/res/raw-fr/help_start.html index 0c1610f0c..962c33d86 100644 --- a/OpenPGP-Keychain/src/main/res/raw-fr/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-fr/help_start.html @@ -2,7 +2,7 @@ <head></head> <body> <h2>Commencer</h2> -<p>Vous avez d'abord besoin d'une paire de clefs personelles. Créez-en une avec l'option du menu « Mes clefs » ou importez des paires de clefs existantes avec « Importer des clefs ». Ensuite vous pouvez télécharger les clefs de vos amis, ou les échanger par codes QR ou NFC.</p> +<p>Vous avez d'abord besoin d'une paire de clefs personelles. Créez-en une avec l'option du menu « Contacts » ou importez des paires de clefs existantes avec « Importer des clefs ». Ensuite vous pouvez télécharger les clefs de vos amis, ou les échanger par codes QR ou NFC.</p> <p>Il vous est recommendé d'installer le <a href="market://details?id=org.openintents.filemanager">gestionnaire de fichiers OI</a> pour sa fonction améliorée de séléction des fichiers et le <a href="market://details?id=com.google.zxing.client.android">lecteur de codes à barres</a> pour balayer les codes QR générés. Cliquer sur les liens ouvrira Google Play Store ou F-Droid pour l'installation.</p> diff --git a/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_about.html b/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_about.html index ba0676f3e..2d17e1882 100644 --- a/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_about.html @@ -11,13 +11,18 @@ <li>Ash Hughes (Patch crittografia)</li> <li>Brian C. Barnes</li> <li>Bahtiar 'kalkin' Gadimov (Interfaccia Utente)</li> +<li>Daniel Hammann</li> +<li>Daniel Haß</li> +<li>Greg Witczak</li> +<li>Miroojin Bakshi</li> +<li>Paul Sarbinowski</li> +<li>Vincent Breitmoser</li> </ul> <h2>Sviluppatori APG 1.x</h2> <ul> -<li>'Thialfihar' (Capo Sviluppatore)</li> +<li>Thialfihar (Capo Sviluppatore)</li> <li>'Senecaso' (QRCode, firma chiavi, caricamento chiavi)</li> -<li>Oliver Runge</li> <li>Markus Doits</li> </ul> <h2>Librerie</h2> @@ -38,8 +43,6 @@ <a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Licenza Apache v2)</li> <li> <a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Library</a> (Licenza Apache v2)</li> -<li>Icone da <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Licenza Creative Commons Attribution Share-Alike 3.0)</li> -<li>Icone da <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (Pubblico Dominio)</li> </ul> </body> </html> diff --git a/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_start.html b/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_start.html index 4eadd82fc..1a4a7303e 100644 --- a/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_start.html @@ -2,7 +2,7 @@ <head></head> <body> <h2>Per iniziare</h2> -<p>Per prima cosa hai bisogno di un paio di chiavi personali. Creane una tramite i menu di opzione sotto 'Mie Chiavi' o importane di esistenti attraverso "Importa Chiavi". Dopodiche' puoi scaricare le chiavi dei tuoi amici o scambiarle tramite Codici QR o NFC.</p> +<p>Per prima cosa hai bisogno di un paio di chiavi personali. Creane una tramite i menu di opzione sotto 'Contatti' o importane di esistenti attraverso "Importa Chiavi". Dopodiche' puoi scaricare le chiavi dei tuoi amici o scambiarle tramite Codici QR o NFC.</p> <p>Si raccomanda di installare <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> per una migliore selezione dei file e <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> per scansionare i codici QR. I collegamenti verranno aperti in Google Play Store o F-Droid per l'installazione.</p> diff --git a/OpenPGP-Keychain/src/main/res/raw-ja/help_about.html b/OpenPGP-Keychain/src/main/res/raw-ja/help_about.html index 206fc9f8d..3f630264c 100644 --- a/OpenPGP-Keychain/src/main/res/raw-ja/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-ja/help_about.html @@ -11,13 +11,18 @@ <li>Ash Hughes (暗号関係パッチ提供)</li> <li>Brian C. Barnes</li> <li>Bahtiar 'kalkin' Gadimov (UI)</li> +<li>Daniel Hammann</li> +<li>Daniel Haß</li> +<li>Greg Witczak</li> +<li>Miroojin Bakshi</li> +<li>Paul Sarbinowski</li> +<li>Vincent Breitmoser</li> </ul> <h2>APG 1.xの開発者達</h2> <ul> -<li>'Thialfihar' (主任開発者)</li> +<li>Thialfihar (主任開発者)</li> <li>'Senecaso' (QRコード, 鍵署名, 鍵アップロード関係)</li> -<li>Oliver Runge</li> <li>Markus Doits</li> </ul> <h2>ライブラリ</h2> @@ -38,8 +43,6 @@ <a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache License v2)</li> <li> <a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Library</a> (Apache License v2)</li> -<li>Icons from <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Creative Commons Attribution Share-Alike licence 3.0)</li> -<li>Icons from <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (パブリックドメイン)</li> </ul> </body> </html> diff --git a/OpenPGP-Keychain/src/main/res/raw-ja/help_start.html b/OpenPGP-Keychain/src/main/res/raw-ja/help_start.html index 9764e876a..04ad31352 100644 --- a/OpenPGP-Keychain/src/main/res/raw-ja/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-ja/help_start.html @@ -2,7 +2,7 @@ <head></head> <body> <h2>入門</h2> -<p>最初にあなたの個人用鍵ペアが必要になります。オプションメニューの"自分の鍵"で生成するか、"鍵のインポート"から既存の鍵ペアをインポートします。その後、あなたの友人の鍵をダウンロード、もしくはQRコードやNFCで交換します。</p> +<p>最初にあなたの個人用鍵ペアが必要になります。オプションメニューの"連絡先"で生成するか、"鍵のインポート"から既存の鍵ペアをインポートします。その後、あなたの友人の鍵をダウンロード、もしくはQRコードやNFCで交換します。</p> <p>ファイルの選択を拡張するには<a href="market://details?id=org.openintents.filemanager">OI File Manager</a>、<a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a>を生成したQRコードのスキャンのため、それぞれのインストールを必要とします。 リンクをクリックして、Google Play Store上かF-Droidからインストールしてください。</p> diff --git a/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_about.html b/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_about.html index 863aeee58..d9150a5e8 100644 --- a/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_about.html @@ -11,13 +11,18 @@ <li>Ash Hughes (crypto patches)</li> <li>Brian C. Barnes</li> <li>Bahtiar 'kalkin' Gadimov (UI)</li> +<li>Daniel Hammann</li> +<li>Daniel Haß</li> +<li>Greg Witczak</li> +<li>Miroojin Bakshi</li> +<li>Paul Sarbinowski</li> +<li>Vincent Breitmoser</li> </ul> <h2>Developers APG 1.x</h2> <ul> -<li>'Thialfihar' (Lead developer)</li> +<li>Thialfihar (Lead developer)</li> <li>'Senecaso' (QRCode, sign key, upload key)</li> -<li>Oliver Runge</li> <li>Markus Doits</li> </ul> <h2>Libraries</h2> @@ -38,8 +43,6 @@ <a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache License v2)</li> <li> <a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Library</a> (Apache License v2)</li> -<li>Icons from <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Creative Commons Attribution Share-Alike licence 3.0)</li> -<li>Icons from <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (Public Domain)</li> </ul> </body> </html> diff --git a/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_start.html b/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_start.html index 3a6443a2f..0e60c17a7 100644 --- a/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_start.html @@ -2,7 +2,7 @@ <head></head> <body> <h2>Getting started</h2> -<p>First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p> +<p>First you need a personal key pair. Create one via the option menus in "Contacts" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p> <p>It is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection and <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.</p> diff --git a/OpenPGP-Keychain/src/main/res/raw-pl/help_about.html b/OpenPGP-Keychain/src/main/res/raw-pl/help_about.html index de16d333f..c41859b60 100644 --- a/OpenPGP-Keychain/src/main/res/raw-pl/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-pl/help_about.html @@ -11,13 +11,18 @@ <li>Ash Hughes (łatki crypto)</li> <li>Brian C. Barnes</li> <li>Bahtiar 'kalkin' Gadimov (Interfejs Użytkownika)</li> +<li>Daniel Hammann</li> +<li>Daniel Haß</li> +<li>Greg Witczak</li> +<li>Miroojin Bakshi</li> +<li>Paul Sarbinowski</li> +<li>Vincent Breitmoser</li> </ul> <h2>Deweloperzy APG 1.x</h2> <ul> -<li>'Thialfihar' (Wiodacy deweloper)</li> +<li>Thialfihar (Wiodacy deweloper)</li> <li>'Senecaso' (kody QR, podpisy kluczy, wysyłanie kluczy)</li> -<li>Oliver Runge</li> <li>Markus Doits</li> </ul> <h2>Biblioteki</h2> @@ -38,8 +43,6 @@ <a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Licencja Apache v2)</li> <li> <a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Library</a> (Licencja Apache v2)</li> -<li>Icons from <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Licencja Uznanie autorstwa - Na tych samych warunkach 3.0 CC-BY-SA)</li> -<li>Icons from <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (Domena Publiczna)</li> </ul> </body> </html> diff --git a/OpenPGP-Keychain/src/main/res/raw-pl/help_start.html b/OpenPGP-Keychain/src/main/res/raw-pl/help_start.html index 539388789..d2faa2db9 100644 --- a/OpenPGP-Keychain/src/main/res/raw-pl/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-pl/help_start.html @@ -2,7 +2,7 @@ <head></head> <body> <h2>Pierwsze kroki</h2> -<p>Po pierwsze potrzebujesz swoją osobistą parę kluczy. Stwórz ją, korzystając z odpowiedniej opcji w sekcji "Moje klucze" lub też zaimportuj istniejącą parę korzystając z sekcji "Importuj klucze". Następnie możesz pobrać klucze Twoich znajomych lub wymieniać się z nimi za pośrednictwem kodów QR lub technologii NFC.</p> +<p>Po pierwsze potrzebujesz swoją osobistą parę kluczy. Stwórz ją, korzystając z odpowiedniej opcji w sekcji "Kontakty" lub też zaimportuj istniejącą parę korzystając z sekcji "Importuj klucze". Następnie możesz pobrać klucze Twoich znajomych lub wymieniać się z nimi za pośrednictwem kodów QR lub technologii NFC.</p> <p>Zalecana jest instalacja menadżera plików <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> w celu zapewnienia wygodniejszego wyboru plików oraz programu <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a>, który jest w stanie skanować wygenerowane kody QR. Kliknięcie na powyższe linki przekieruje Cię do sklepu Google Play / F-Droid.</p> diff --git a/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_about.html b/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_about.html index 863aeee58..d9150a5e8 100644 --- a/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_about.html @@ -11,13 +11,18 @@ <li>Ash Hughes (crypto patches)</li> <li>Brian C. Barnes</li> <li>Bahtiar 'kalkin' Gadimov (UI)</li> +<li>Daniel Hammann</li> +<li>Daniel Haß</li> +<li>Greg Witczak</li> +<li>Miroojin Bakshi</li> +<li>Paul Sarbinowski</li> +<li>Vincent Breitmoser</li> </ul> <h2>Developers APG 1.x</h2> <ul> -<li>'Thialfihar' (Lead developer)</li> +<li>Thialfihar (Lead developer)</li> <li>'Senecaso' (QRCode, sign key, upload key)</li> -<li>Oliver Runge</li> <li>Markus Doits</li> </ul> <h2>Libraries</h2> @@ -38,8 +43,6 @@ <a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache License v2)</li> <li> <a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Library</a> (Apache License v2)</li> -<li>Icons from <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Creative Commons Attribution Share-Alike licence 3.0)</li> -<li>Icons from <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (Public Domain)</li> </ul> </body> </html> diff --git a/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_start.html b/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_start.html index 3a6443a2f..0e60c17a7 100644 --- a/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_start.html @@ -2,7 +2,7 @@ <head></head> <body> <h2>Getting started</h2> -<p>First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p> +<p>First you need a personal key pair. Create one via the option menus in "Contacts" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p> <p>It is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection and <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.</p> diff --git a/OpenPGP-Keychain/src/main/res/raw-ru/help_about.html b/OpenPGP-Keychain/src/main/res/raw-ru/help_about.html index 655e98758..63335110e 100644 --- a/OpenPGP-Keychain/src/main/res/raw-ru/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-ru/help_about.html @@ -11,13 +11,18 @@ <li>Ash Hughes (патчи криптографии)</li> <li>Brian C. Barnes</li> <li>Bahtiar 'kalkin' Gadimov (UI)</li> +<li>Daniel Hammann</li> +<li>Daniel Haß</li> +<li>Greg Witczak</li> +<li>Miroojin Bakshi</li> +<li>Paul Sarbinowski</li> +<li>Vincent Breitmoser</li> </ul> <h2>Разработчики APG 1.x</h2> <ul> -<li>'Thialfihar' (главный разработчик)</li> +<li>Thialfihar (главный разработчик)</li> <li>'Senecaso' (QR коды, подписание и загрузка ключей)</li> -<li>Oliver Runge</li> <li>Markus Doits</li> </ul> <h2>Компоненты</h2> @@ -38,8 +43,6 @@ <a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache License v2)</li> <li> <a href="https://github.com/johnkil/Android-AppMsg">Библиотека Android AppMsg</a> (Apache License v2)</li> -<li>Иконки <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Creative Commons Attribution Share-Alike licence 3.0)</li> -<li>Иконки <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (Public Domain)</li> </ul> </body> </html> diff --git a/OpenPGP-Keychain/src/main/res/raw-ru/help_start.html b/OpenPGP-Keychain/src/main/res/raw-ru/help_start.html index 9b2b99e96..bc9dade67 100644 --- a/OpenPGP-Keychain/src/main/res/raw-ru/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-ru/help_start.html @@ -2,7 +2,7 @@ <head></head> <body> <h2>Приступая</h2> -<p>Для начала вам понадобится своя пара ключей. Воспользуйтесь меню в разделе "Мои ключи", что бы создать новую, или добавьте ранее созданную пару в разделе "Импорт ключей". После этого вы сможете скачать ключи ваших друзей или обменяться ключами посредством QR кодов или NFC.</p> +<p>Для начала вам понадобится своя пара ключей. Воспользуйтесь меню в разделе "Контакты", что бы создать новую, или добавьте ранее созданную пару в разделе "Импорт ключей". После этого вы сможете скачать ключи ваших друзей или обменяться ключами посредством QR кодов или NFC.</p> <p>Рекомендуется установить <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> для удобного выбора файлов и <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> для распознавания QR кодов. Перейдите по ссылкам на соответствующие страницы Google Play или F-Droid для дальнейшей установки.</p> diff --git a/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_about.html b/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_about.html index 863aeee58..d9150a5e8 100644 --- a/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_about.html @@ -11,13 +11,18 @@ <li>Ash Hughes (crypto patches)</li> <li>Brian C. Barnes</li> <li>Bahtiar 'kalkin' Gadimov (UI)</li> +<li>Daniel Hammann</li> +<li>Daniel Haß</li> +<li>Greg Witczak</li> +<li>Miroojin Bakshi</li> +<li>Paul Sarbinowski</li> +<li>Vincent Breitmoser</li> </ul> <h2>Developers APG 1.x</h2> <ul> -<li>'Thialfihar' (Lead developer)</li> +<li>Thialfihar (Lead developer)</li> <li>'Senecaso' (QRCode, sign key, upload key)</li> -<li>Oliver Runge</li> <li>Markus Doits</li> </ul> <h2>Libraries</h2> @@ -38,8 +43,6 @@ <a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache License v2)</li> <li> <a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Library</a> (Apache License v2)</li> -<li>Icons from <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Creative Commons Attribution Share-Alike licence 3.0)</li> -<li>Icons from <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (Public Domain)</li> </ul> </body> </html> diff --git a/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_start.html b/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_start.html index 3a6443a2f..0e60c17a7 100644 --- a/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_start.html @@ -2,7 +2,7 @@ <head></head> <body> <h2>Getting started</h2> -<p>First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p> +<p>First you need a personal key pair. Create one via the option menus in "Contacts" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p> <p>It is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection and <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.</p> diff --git a/OpenPGP-Keychain/src/main/res/raw-tr/help_about.html b/OpenPGP-Keychain/src/main/res/raw-tr/help_about.html index eb262b242..d50154765 100644 --- a/OpenPGP-Keychain/src/main/res/raw-tr/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-tr/help_about.html @@ -11,13 +11,18 @@ <li>Ash Hughes (kripto yamaları)</li> <li>Brian C. Barnes</li> <li>Bahtiar 'kalkin' Gadimov (Arayüz)</li> +<li>Daniel Hammann</li> +<li>Daniel Haß</li> +<li>Greg Witczak</li> +<li>Miroojin Bakshi</li> +<li>Paul Sarbinowski</li> +<li>Vincent Breitmoser</li> </ul> <h2>Geliştiriciler APG 1.x</h2> <ul> -<li>'Thialfihar' (Baş geliştirici)</li> +<li>Thialfihar (Baş geliştirici)</li> <li>'Senecaso' (QR Kodu, anahtar imzalama, anahtar yükleme)</li> -<li>Oliver Runge</li> <li>Markus Doits</li> </ul> <h2>Kütüphaneler</h2> @@ -38,8 +43,6 @@ <a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache License v2)</li> <li> <a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Library</a> (Apache License v2)</li> -<li>İkonlar <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Creative Commons Attribution Share-Alike licence 3.0)</li> -<li>İkonlar <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (Public Domain)</li> </ul> </body> </html> diff --git a/OpenPGP-Keychain/src/main/res/raw-tr/help_start.html b/OpenPGP-Keychain/src/main/res/raw-tr/help_start.html index 3a6443a2f..0e60c17a7 100644 --- a/OpenPGP-Keychain/src/main/res/raw-tr/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-tr/help_start.html @@ -2,7 +2,7 @@ <head></head> <body> <h2>Getting started</h2> -<p>First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p> +<p>First you need a personal key pair. Create one via the option menus in "Contacts" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p> <p>It is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection and <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.</p> diff --git a/OpenPGP-Keychain/src/main/res/raw-uk/help_about.html b/OpenPGP-Keychain/src/main/res/raw-uk/help_about.html index c8a5a82c5..4e6bb02dd 100644 --- a/OpenPGP-Keychain/src/main/res/raw-uk/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-uk/help_about.html @@ -11,13 +11,18 @@ <li>Аш Гюдж (латки шифрування)</li> <li>Браян С. Барнс</li> <li>Бахтіяр 'kalkin' Ґадімов (інтерфейс)</li> +<li>Daniel Hammann</li> +<li>Daniel Haß</li> +<li>Greg Witczak</li> +<li>Miroojin Bakshi</li> +<li>Paul Sarbinowski</li> +<li>Vincent Breitmoser</li> </ul> <h2>Розробники APG 1.x</h2> <ul> -<li>'Thialfihar' (основний розробник)</li> +<li>Thialfihar (основний розробник)</li> <li>'Senecaso' (штрих-код, підпис і завантаження ключів)</li> -<li>Олівер Ранж</li> <li>Маркус Дойтс</li> </ul> <h2>Бібліотеки</h2> @@ -38,8 +43,6 @@ <a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (ліцензія Apache в.2)</li> <li> <a href="https://github.com/johnkil/Android-AppMsg">Бібліотека Android AppMsg Library</a> (Ліцензія Apache в. 2)</li> -<li>Піктограми із <a href="http://rrze-icon-set.berlios.de/">набору піктограм RRZE</a> (ліцензія Creative Commons - Із зазначенням авторства - Розповсюдження на тих самих умовах - версія 3.0)</li> -<li>Піктограми із <a href="http://tango.freedesktop.org/">набору піктограм Tango</a> (відкритий домен)</li> </ul> </body> </html> diff --git a/OpenPGP-Keychain/src/main/res/raw-uk/help_start.html b/OpenPGP-Keychain/src/main/res/raw-uk/help_start.html index 3bfb40f8a..78443070d 100644 --- a/OpenPGP-Keychain/src/main/res/raw-uk/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-uk/help_start.html @@ -2,7 +2,7 @@ <head></head> <body> <h2>Приступаючи до роботи</h2> -<p>Спершу вам потрібна персональна в'язка ключів. Створіть одну через меню параметрів у "Мої Ключі" або імпортуйте наявні в'язки ключів через "Імпорт ключів". Після цього ви зможете завантажувати ключі ваших друзів чи обміняти їх через штрих-коди або NFC.</p> +<p>Спершу вам потрібна персональна в'язка ключів. Створіть одну через меню параметрів у "Контакти" або імпортуйте наявні в'язки ключів через "Імпорт ключів". Після цього ви зможете завантажувати ключі ваших друзів чи обміняти їх через штрих-коди або NFC.</p> <p>Рекомендуємо вам встановити <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> для поліпшеного виділення файлів та <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> для сканування згенерованих штрих-кодів. Натискання посилань відкриє Google Play або F-Droid для встановлення.</p> diff --git a/OpenPGP-Keychain/src/main/res/raw-zh-rTW/help_about.html b/OpenPGP-Keychain/src/main/res/raw-zh-rTW/help_about.html index 863aeee58..d9150a5e8 100644 --- a/OpenPGP-Keychain/src/main/res/raw-zh-rTW/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-zh-rTW/help_about.html @@ -11,13 +11,18 @@ <li>Ash Hughes (crypto patches)</li> <li>Brian C. Barnes</li> <li>Bahtiar 'kalkin' Gadimov (UI)</li> +<li>Daniel Hammann</li> +<li>Daniel Haß</li> +<li>Greg Witczak</li> +<li>Miroojin Bakshi</li> +<li>Paul Sarbinowski</li> +<li>Vincent Breitmoser</li> </ul> <h2>Developers APG 1.x</h2> <ul> -<li>'Thialfihar' (Lead developer)</li> +<li>Thialfihar (Lead developer)</li> <li>'Senecaso' (QRCode, sign key, upload key)</li> -<li>Oliver Runge</li> <li>Markus Doits</li> </ul> <h2>Libraries</h2> @@ -38,8 +43,6 @@ <a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache License v2)</li> <li> <a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Library</a> (Apache License v2)</li> -<li>Icons from <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Creative Commons Attribution Share-Alike licence 3.0)</li> -<li>Icons from <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (Public Domain)</li> </ul> </body> </html> diff --git a/OpenPGP-Keychain/src/main/res/raw-zh-rTW/help_start.html b/OpenPGP-Keychain/src/main/res/raw-zh-rTW/help_start.html index 3a6443a2f..0e60c17a7 100644 --- a/OpenPGP-Keychain/src/main/res/raw-zh-rTW/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-zh-rTW/help_start.html @@ -2,7 +2,7 @@ <head></head> <body> <h2>Getting started</h2> -<p>First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p> +<p>First you need a personal key pair. Create one via the option menus in "Contacts" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p> <p>It is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection and <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.</p> diff --git a/OpenPGP-Keychain/src/main/res/raw-zh/help_about.html b/OpenPGP-Keychain/src/main/res/raw-zh/help_about.html index 23b904995..1eec8bdbf 100644 --- a/OpenPGP-Keychain/src/main/res/raw-zh/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-zh/help_about.html @@ -11,13 +11,18 @@ <li>Ash Hughes (crypto patches)</li> <li>Brian C. Barnes</li> <li>Bahtiar 'kalkin' Gadimov (介面)</li> +<li>Daniel Hammann</li> +<li>Daniel Haß</li> +<li>Greg Witczak</li> +<li>Miroojin Bakshi</li> +<li>Paul Sarbinowski</li> +<li>Vincent Breitmoser</li> </ul> <h2>Developers APG 1.x</h2> <ul> -<li>'Thialfihar' (Lead developer)</li> +<li>Thialfihar (Lead developer)</li> <li>'Senecaso' (QRCode, sign key, upload key)</li> -<li>Oliver Runge</li> <li>Markus Doits</li> </ul> <h2>函式庫</h2> @@ -38,8 +43,6 @@ <a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache License v2)</li> <li> <a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Library</a> (Apache License v2)</li> -<li>Icons from <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Creative Commons Attribution Share-Alike licence 3.0)</li> -<li>Icons from <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (Public Domain)</li> </ul> </body> </html> diff --git a/OpenPGP-Keychain/src/main/res/raw/help_about.html b/OpenPGP-Keychain/src/main/res/raw/help_about.html index 51e3f1325..2ffbb47a6 100644 --- a/OpenPGP-Keychain/src/main/res/raw/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw/help_about.html @@ -15,13 +15,18 @@ And don't add newlines before or after p tags because of transifex --> <li>Ash Hughes (crypto patches)</li> <li>Brian C. Barnes</li> <li>Bahtiar 'kalkin' Gadimov (UI)</li> +<li>Daniel Hammann</li> +<li>Daniel Haß</li> +<li>Greg Witczak</li> +<li>Miroojin Bakshi</li> +<li>Paul Sarbinowski</li> +<li>Vincent Breitmoser</li> </ul> <h2>Developers APG 1.x</h2> <ul> -<li>'Thialfihar' (Lead developer)</li> +<li>Thialfihar (Lead developer)</li> <li>'Senecaso' (QRCode, sign key, upload key)</li> -<li>Oliver Runge</li> <li>Markus Doits</li> </ul> @@ -35,8 +40,6 @@ And don't add newlines before or after p tags because of transifex --> <li><a href="http://rtyley.github.com/spongycastle/">SpongyCastle</a> (MIT X11 License)</li> <li><a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache License v2)</li> <li><a href="https://github.com/johnkil/Android-AppMsg">Android AppMsg Library</a> (Apache License v2)</li> -<li>Icons from <a href="http://rrze-icon-set.berlios.de/">RRZE Icon Set</a> (Creative Commons Attribution Share-Alike licence 3.0)</li> -<li>Icons from <a href="http://tango.freedesktop.org/">Tango Icon Set</a> (Public Domain)</li> </ul> </body> </html> diff --git a/OpenPGP-Keychain/src/main/res/raw/help_start.html b/OpenPGP-Keychain/src/main/res/raw/help_start.html index 7afac0f08..56c02b1fd 100644 --- a/OpenPGP-Keychain/src/main/res/raw/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw/help_start.html @@ -6,7 +6,7 @@ And don't add newlines before or after p tags because of transifex --> </head> <body> <h2>Getting started</h2> -<p>First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p> +<p>First you need a personal key pair. Create one via the option menus in "Contacts" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p> <p>It is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection and <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.</p> diff --git a/OpenPGP-Keychain/src/main/res/values/strings.xml b/OpenPGP-Keychain/src/main/res/values/strings.xml index 11e3028f3..5bf7ca8ca 100644 --- a/OpenPGP-Keychain/src/main/res/values/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values/strings.xml @@ -412,6 +412,8 @@ <!-- Remote API --> <string name="api_no_apps">No registered applications!\n\nThird-party applications can request access to OpenKeychain. After granting access, they will be listed here.</string> + <string name="api_settings_show_info">Show advanced information</string> + <string name="api_settings_hide_info">Hide advanced information</string> <string name="api_settings_show_advanced">Show advanced settings</string> <string name="api_settings_hide_advanced">Hide advanced settings</string> <string name="api_settings_no_key">No key selected</string> @@ -421,6 +423,8 @@ <string name="api_settings_revoke">Revoke access</string> <string name="api_settings_package_name">Package Name</string> <string name="api_settings_package_signature">SHA-256 of Package Signature</string> + <string name="api_settings_accounts">Accounts</string> + <string name="api_settings_accounts_empty">No accounts attached to this application.</string> <string name="api_register_text">The displayed application requests access to OpenKeychain.\nAllow access?\n\nWARNING: If you do not know why this screen appeared, disallow access! You can revoke access later using the \'Registered Applications\' screen.</string> <string name="api_register_allow">Allow access</string> <string name="api_register_disallow">Disallow access</string> @@ -1,6 +1,6 @@ # OpenKeychain (for Android) -OpenKeychain is an OpenPGP implementation for Android. +OpenKeychain is an OpenPGP implementation for Android. For a more detailed description and installation instructions go to http://www.openkeychain.org . ### Travis CI Build Status @@ -31,9 +31,9 @@ Development mailinglist at http://groups.google.com/d/forum/openpgp-keychain-dev ### Build with Gradle 1. Have Android SDK "tools", "platform-tools", and "build-tools" directories in your PATH (http://developer.android.com/sdk/index.html) -2. Open the Android SDK Manager (shell command: ``android``). -Expand the Tools directory and select "Android SDK Build-tools (Version 19.0.3)". -Expand the Extras directory and install "Android Support Repository" +2. Open the Android SDK Manager (shell command: ``android``). +Expand the Tools directory and select "Android SDK Build-tools (Version 19.0.3)". +Expand the Extras directory and install "Android Support Repository" Select everything for the newest SDK (API-Level 19) 3. Export ANDROID_HOME pointing to your Android SDK 4. Execute ``./gradlew build`` @@ -59,11 +59,11 @@ I am using the newest [Android Studio](http://developer.android.com/sdk/installi OpenKeychain provides two APIs, namely the Intent API and the Remote OpenPGP API. The Intent API can be used without permissions to start OpenKeychain's activities for cryptographic operations, import of keys, etc. -However, it always requires user input, so that no malicious application can use this API without user intervention. +However, it always requires user input, so that no malicious application can use this API without user intervention. The Remote OpenPGP API is more sophisticated and allows to to operations without user interaction in the background. When utilizing this API, OpenKeychain asks the user on first use to grant access for the calling client application. -More technical information and examples about these APIs can be found in the project's wiki: +More technical information and examples about these APIs can be found in the project's wiki: * [Intent API](https://github.com/openpgp-keychain/openpgp-keychain/wiki/Intent-API) * [Remote OpenPGP API](https://github.com/openpgp-keychain/openpgp-keychain/wiki/OpenPGP-API) @@ -110,7 +110,7 @@ see ### Gradle Build System -We try to make our builds as [reproducible/deterministic](https://blog.torproject.org/blog/deterministic-builds-part-one-cyberwar-and-global-compromise) as possible. +We try to make our builds as [reproducible/deterministic](https://blog.torproject.org/blog/deterministic-builds-part-one-cyberwar-and-global-compromise) as possible. When changing build files or dependencies, respect the following requirements: * No precompiled libraries. All libraries should be provided as sourcecode in "libraries" folder (you never know what pre-compiled jar files really contain! The library files are currently directly commited, because git submodules/git subtree are too much of a hassle for new contributors. This could change in the future!) * No dependencies from Maven (also a soft requirement for inclusion in [F-Droid](https://f-droid.org)) @@ -180,59 +180,55 @@ Some parts (older parts and some libraries are Apache License v2, MIT X11 Licens > it under the terms of the GNU General Public License as published by > the Free Software Foundation, either version 3 of the License, or > (at your option) any later version. -> +> > This program is distributed in the hope that it will be useful, > but WITHOUT ANY WARRANTY; without even the implied warranty of > MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > GNU General Public License for more details. -> +> > You should have received a copy of the GNU General Public License > along with this program. If not, see <http://www.gnu.org/licenses/>. ### Libraries -* SpongyCastle - https://github.com/rtyley/spongycastle +* SpongyCastle + https://github.com/rtyley/spongycastle MIT X11 License -* Android Support Library v4 - http://developer.android.com/tools/support-library/index.html +* Android Support Library v4 + http://developer.android.com/tools/support-library/index.html Apache License v2 - -* Android Support Library v7 'appcompat' - http://developer.android.com/tools/support-library/index.html + +* Android Support Library v7 'appcompat' + http://developer.android.com/tools/support-library/index.html Apache License v2 -* HtmlTextView - https://github.com/dschuermann/html-textview +* HtmlTextView + https://github.com/dschuermann/html-textview Apache License v2 -* ZXing - https://github.com/zxing/zxing +* ZXing + https://github.com/zxing/zxing Apache License v2 - -* StickyListHeaders - https://github.com/emilsjolander/StickyListHeaders + +* StickyListHeaders + https://github.com/emilsjolander/StickyListHeaders Apache License v2 - -* Android-Bootstrap - https://github.com/Bearded-Hen/Android-Bootstrap + +* Android-Bootstrap + https://github.com/Bearded-Hen/Android-Bootstrap MIT License -* Android AppMsg - https://github.com/johnkil/Android-AppMsg +* Android AppMsg + https://github.com/johnkil/Android-AppMsg Apache License v2 ### Images -* icon.svg +* icon.svg modified version of kgpg_key2_kopete.svgz -* key.svg - http://rrze-icon-set.berlios.de/ - Creative Commons Attribution Share-Alike licence 3.0 - -* Menu icons +* Menu icons http://developer.android.com/design/downloads/index.html#action-bar-icon-pack diff --git a/Resources/graphics/icon/AUTHORS b/Resources/graphics/icon/AUTHORS new file mode 100644 index 000000000..dbfcfb4fc --- /dev/null +++ b/Resources/graphics/icon/AUTHORS @@ -0,0 +1,21 @@ +Oxygen for KDE3 +Oxygen Icon Theme has been developed by The Oxygen Team. + +Art Director: +David Vignoni <david@oxygen-icons.org> + +Designers: +David J. Miller <miller@oxygen-icons.org> +David Vignoni <david@oxygen-icons.org> +Johann Ollivier Lapeyre <johann@oxygen-icons.org> +Kenneth Wimer <ken@oxygen-icons.org> +Nuno F. Pinheiro <nuno@oxygen-icons.org> +Riccardo Iaconelli <riccardo@oxygen-icons.org> + +Thanks to: +Lee Olson: Contributed drawing used in application-x-bittorent icon. +Marco Aurélio "Coré": Improved audio-input-microphone icon. +Matthias Kretz: Contributed "audio-input-line" device icon. +Mauricio Piacentini <piacentini@kde.org> : game icons mashup + +Repackaged by Luke Channings <thefuzzball2005@gmail.com>
\ No newline at end of file diff --git a/Resources/graphics/icon/COPYING b/Resources/graphics/icon/COPYING new file mode 100644 index 000000000..2faa27568 --- /dev/null +++ b/Resources/graphics/icon/COPYING @@ -0,0 +1,48 @@ +The Oxygen Icon Theme for KDE3 + Copyright (C) 2007 David Vignoni <david@icon-king.com> + Copyright (C) 2007 Johann Ollivier Lapeyre <johann@oxygen-icons.org> + Copyright (C) 2007 Kenneth Wimer <kwwii@bootsplash.org> + Copyright (C) 2007 Nuno Fernades Pinheiro <nf.pinheiro@gmail.com> + Copyright (C) 2007 Riccardo Iaconelli <riccardo@oxygen-icons.org> + Copyright (C) 2007 David Miller <miller@oxygen-icons.org> + +and others + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library. If not, see <http://www.gnu.org/licenses/>. + +Clarification: + + The GNU Lesser General Public License or LGPL is written for + software libraries in the first place. We expressly want the LGPL to + be valid for this artwork library too. + + KDE Oxygen theme icons is a special kind of software library, it is an + artwork library, it's elements can be used in a Graphical User Interface, or + GUI. + + Source code, for this library means: + - where they exist, SVG; + - otherwise, if applicable, the multi-layered formats xcf or psd, or + otherwise png. + + The LGPL in some sections obliges you to make the files carry + notices. With images this is in some cases impossible or hardly useful. + + With this library a notice is placed at a prominent place in the directory + containing the elements. You may follow this practice. + + The exception in section 5 of the GNU Lesser General Public License covers + the use of elements of this art library in a GUI. + + kde-artists [at] kde.org diff --git a/Resources/graphics/kgpg_key2_kopete.svgz b/Resources/graphics/icon/kgpg_key2_kopete.svgz Binary files differindex 2d43afb83..2d43afb83 100644 --- a/Resources/graphics/kgpg_key2_kopete.svgz +++ b/Resources/graphics/icon/kgpg_key2_kopete.svgz |