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 fcf8f7962..e6e106ba6 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 @@ -96,18 +96,14 @@ public class KeychainContract { public static final String BASE_API_APPS = "api_apps"; public static final String PATH_ACCOUNTS = "accounts"; - public static class KeyRings implements KeyRingsColumns, BaseColumns { + public static class KeyRings implements BaseColumns, KeysColumns, UserIdsColumns { + public static final String MASTER_KEY_ID = "master_key_id"; + public static final String HAS_SECRET = "has_secret"; + public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon() .appendPath(BASE_KEY_RINGS).build(); - /** - * Use if multiple items get returned - */ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.sufficientlysecure.openkeychain.key_ring"; - - /** - * Use if a single item is returned - */ public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.sufficientlysecure.openkeychain.key_ring"; public static Uri buildUnifiedKeyRingsUri() { @@ -121,6 +117,24 @@ public class KeychainContract { return CONTENT_URI.buildUpon().appendPath(masterKeyId).build(); } + public static Uri buildUnifiedKeyRingUri(String masterKeyId) { + return CONTENT_URI.buildUpon().appendPath(masterKeyId).appendPath(PATH_UNIFIED).build(); + } + public static Uri buildUnifiedKeyRingUri(Uri uri) { + return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1)).appendPath(PATH_UNIFIED).build(); + } + } + + public static class KeyRingData implements KeyRingsColumns, BaseColumns { + public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon() + .appendPath(BASE_KEY_RINGS).build(); + + public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.sufficientlysecure.openkeychain.key_ring_data"; + public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.sufficientlysecure.openkeychain.key_ring_data"; + + public static Uri buildPublicKeyRingUri() { + return CONTENT_URI.buildUpon().appendPath(PATH_PUBLIC).build(); + } public static Uri buildPublicKeyRingUri(String masterKeyId) { return CONTENT_URI.buildUpon().appendPath(masterKeyId).appendPath(PATH_PUBLIC).build(); } @@ -135,12 +149,6 @@ public class KeychainContract { return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1)).appendPath(PATH_SECRET).build(); } - public static Uri buildUnifiedKeyRingUri(String masterKeyId) { - return CONTENT_URI.buildUpon().appendPath(masterKeyId).appendPath(PATH_UNIFIED).build(); - } - public static Uri buildUnifiedKeyRingUri(Uri uri) { - return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1)).appendPath(PATH_UNIFIED).build(); - } } public static class Keys implements KeysColumns, BaseColumns { 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 a4fd1130d..8b1ee4886 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 @@ -26,19 +26,15 @@ import android.database.sqlite.SQLiteConstraintException; import android.database.sqlite.SQLiteDatabase; 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.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.KeyRingData; 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; @@ -46,13 +42,9 @@ import java.util.Arrays; import java.util.HashMap; public class KeychainProvider extends ContentProvider { - // public static final String ACTION_BROADCAST_DATABASE_CHANGE = Constants.PACKAGE_NAME - // + ".action.DATABASE_CHANGE"; - // - // public static final String EXTRA_BROADCAST_KEY_TYPE = "key_type"; - // public static final String EXTRA_BROADCAST_CONTENT_ITEM_TYPE = "contentItemType"; private static final int KEY_RINGS_UNIFIED = 101; + private static final int KEY_RINGS_PUBLIC = 102; private static final int KEY_RING_UNIFIED = 200; private static final int KEY_RING_KEYS = 201; @@ -79,18 +71,22 @@ public class KeychainProvider extends ContentProvider { String authority = KeychainContract.CONTENT_AUTHORITY; /** - * select from key_ring + * list key_rings * *
* key_rings/unified + * key_rings/public **/ matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_UNIFIED, KEY_RINGS_UNIFIED); + matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + + "/" + KeychainContract.PATH_PUBLIC, + KEY_RINGS_PUBLIC); /** - * select from key_ring + * list key_ring specifics * *
* key_rings/_/unified @@ -215,45 +211,44 @@ public class KeychainProvider extends ContentProvider { case KEY_RING_UNIFIED: case KEY_RINGS_UNIFIED: { HashMapprojectionMap = new HashMap (); - projectionMap.put(BaseColumns._ID, Tables.KEYS + ".oid AS _id"); - projectionMap.put(KeysColumns.MASTER_KEY_ID, Tables.KEYS + "." + KeysColumns.MASTER_KEY_ID); - projectionMap.put(KeysColumns.RANK, Tables.KEYS + "." + KeysColumns.RANK); - projectionMap.put(KeysColumns.KEY_ID, KeysColumns.KEY_ID); - projectionMap.put(KeysColumns.KEY_SIZE, KeysColumns.KEY_SIZE); - projectionMap.put(KeysColumns.IS_REVOKED, KeysColumns.IS_REVOKED); - projectionMap.put(KeysColumns.CAN_CERTIFY, KeysColumns.CAN_CERTIFY); - projectionMap.put(KeysColumns.CAN_ENCRYPT, KeysColumns.CAN_ENCRYPT); - projectionMap.put(KeysColumns.CAN_SIGN, KeysColumns.CAN_SIGN); - projectionMap.put(KeysColumns.CREATION, KeysColumns.CREATION); - projectionMap.put(KeysColumns.EXPIRY, KeysColumns.EXPIRY); - projectionMap.put(KeysColumns.ALGORITHM, KeysColumns.ALGORITHM); - projectionMap.put(KeysColumns.FINGERPRINT, KeysColumns.FINGERPRINT); - projectionMap.put(UserIdsColumns.USER_ID, UserIdsColumns.USER_ID); - projectionMap.put(Tables.KEY_RINGS_SECRET + "." + KeyRings.MASTER_KEY_ID, Tables.KEY_RINGS_SECRET + "." + KeyRingsColumns.MASTER_KEY_ID); + projectionMap.put(KeyRings._ID, Tables.KEYS + ".oid AS _id"); + projectionMap.put(KeyRings.MASTER_KEY_ID, Tables.KEYS + "." + Keys.MASTER_KEY_ID); + projectionMap.put(KeyRings.KEY_ID, Keys.KEY_ID); + projectionMap.put(KeyRings.KEY_SIZE, Keys.KEY_SIZE); + projectionMap.put(KeyRings.IS_REVOKED, Keys.IS_REVOKED); + projectionMap.put(KeyRings.CAN_CERTIFY, Keys.CAN_CERTIFY); + projectionMap.put(KeyRings.CAN_ENCRYPT, Keys.CAN_ENCRYPT); + projectionMap.put(KeyRings.CAN_SIGN, Keys.CAN_SIGN); + projectionMap.put(KeyRings.CREATION, Keys.CREATION); + projectionMap.put(KeyRings.EXPIRY, Keys.EXPIRY); + projectionMap.put(KeyRings.ALGORITHM, Keys.ALGORITHM); + projectionMap.put(KeyRings.FINGERPRINT, Keys.FINGERPRINT); + projectionMap.put(KeyRings.USER_ID, UserIds.USER_ID); + projectionMap.put(KeyRings.HAS_SECRET, "(" + Tables.KEY_RINGS_SECRET + "." + KeyRings.MASTER_KEY_ID + " IS NOT NULL) AS " + KeyRings.HAS_SECRET); qb.setProjectionMap(projectionMap); qb.setTables( Tables.KEYS + " INNER JOIN " + Tables.USER_IDS + " ON (" - + Tables.KEYS + "." + KeysColumns.MASTER_KEY_ID + + Tables.KEYS + "." + Keys.MASTER_KEY_ID + " = " - + Tables.USER_IDS + "." + UserIdsColumns.MASTER_KEY_ID - + " AND " + Tables.USER_IDS + "." + UserIdsColumns.RANK + " = 0" + + Tables.USER_IDS + "." + UserIds.MASTER_KEY_ID + + " AND " + Tables.USER_IDS + "." + UserIds.RANK + " = 0" + ") LEFT JOIN " + Tables.KEY_RINGS_SECRET + " ON (" - + Tables.KEYS + "." + KeysColumns.MASTER_KEY_ID + + Tables.KEYS + "." + Keys.MASTER_KEY_ID + " = " - + Tables.KEY_RINGS_SECRET + "." + KeyRingsColumns.MASTER_KEY_ID + + Tables.KEY_RINGS_SECRET + "." + KeyRings.MASTER_KEY_ID + ")" ); - qb.appendWhere(Tables.KEYS + "." + KeysColumns.RANK + " = 0"); + qb.appendWhere(Tables.KEYS + "." + Keys.RANK + " = 0"); if(match == KEY_RING_UNIFIED) { - qb.appendWhere(" AND " + Tables.KEYS + "." + KeysColumns.MASTER_KEY_ID + " = "); + qb.appendWhere(" AND " + Tables.KEYS + "." + Keys.MASTER_KEY_ID + " = "); qb.appendWhereEscapeString(uri.getPathSegments().get(1)); } else if (TextUtils.isEmpty(sortOrder)) { sortOrder = Tables.KEY_RINGS_SECRET + "." + KeyRings.MASTER_KEY_ID + " IS NULL DESC" - + Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC"; + + Tables.USER_IDS + "." + UserIds.USER_ID + " ASC"; } // uri to watch is all /key_rings/ @@ -276,38 +271,38 @@ public class KeychainProvider extends ContentProvider { if (i != 0) { emailWhere += " OR "; } - emailWhere += "tmp." + UserIdsColumns.USER_ID + " LIKE "; + emailWhere += "tmp." + UserIds.USER_ID + " LIKE "; // match '* ', so it has to be at the *end* of the user id emailWhere += DatabaseUtils.sqlEscapeString("%<" + chunks[i] + ">"); gotCondition = true; } if (gotCondition) { - qb.appendWhere(" AND EXISTS (SELECT tmp." + BaseColumns._ID + " FROM " - + Tables.USER_IDS + " AS tmp WHERE tmp." + UserIdsColumns.KEY_RING_ROW_ID - + " = " + Tables.KEY_RINGS + "." + BaseColumns._ID + " AND (" + emailWhere + qb.appendWhere(" AND EXISTS (SELECT tmp." + Base._ID + " FROM " + + Tables.USER_IDS + " AS tmp WHERE tmp." + UserIds.KEY_RING_ROW_ID + + " = " + Tables.KEY_RINGS + "." + Base._ID + " AND (" + emailWhere + "))"); }*/ case KEY_RING_KEYS: { HashMap projectionMap = new HashMap (); - projectionMap.put(BaseColumns._ID, Tables.KEYS + ".oid AS _id"); - projectionMap.put(KeysColumns.MASTER_KEY_ID, Tables.KEYS + "." + KeysColumns.MASTER_KEY_ID); - projectionMap.put(KeysColumns.RANK, Tables.KEYS + "." + KeysColumns.RANK); - projectionMap.put(KeysColumns.KEY_ID, KeysColumns.KEY_ID); - projectionMap.put(KeysColumns.KEY_SIZE, KeysColumns.KEY_SIZE); - projectionMap.put(KeysColumns.IS_REVOKED, KeysColumns.IS_REVOKED); - projectionMap.put(KeysColumns.CAN_CERTIFY, KeysColumns.CAN_CERTIFY); - projectionMap.put(KeysColumns.CAN_ENCRYPT, KeysColumns.CAN_ENCRYPT); - projectionMap.put(KeysColumns.CAN_SIGN, KeysColumns.CAN_SIGN); - projectionMap.put(KeysColumns.CREATION, KeysColumns.CREATION); - projectionMap.put(KeysColumns.EXPIRY, KeysColumns.EXPIRY); - projectionMap.put(KeysColumns.ALGORITHM, KeysColumns.ALGORITHM); - projectionMap.put(KeysColumns.FINGERPRINT, KeysColumns.FINGERPRINT); + projectionMap.put(Keys._ID, Tables.KEYS + ".oid AS _id"); + projectionMap.put(Keys.MASTER_KEY_ID, Tables.KEYS + "." + Keys.MASTER_KEY_ID); + projectionMap.put(Keys.RANK, Tables.KEYS + "." + Keys.RANK); + projectionMap.put(Keys.KEY_ID, Keys.KEY_ID); + projectionMap.put(Keys.KEY_SIZE, Keys.KEY_SIZE); + projectionMap.put(Keys.IS_REVOKED, Keys.IS_REVOKED); + projectionMap.put(Keys.CAN_CERTIFY, Keys.CAN_CERTIFY); + projectionMap.put(Keys.CAN_ENCRYPT, Keys.CAN_ENCRYPT); + projectionMap.put(Keys.CAN_SIGN, Keys.CAN_SIGN); + projectionMap.put(Keys.CREATION, Keys.CREATION); + projectionMap.put(Keys.EXPIRY, Keys.EXPIRY); + projectionMap.put(Keys.ALGORITHM, Keys.ALGORITHM); + projectionMap.put(Keys.FINGERPRINT, Keys.FINGERPRINT); qb.setProjectionMap(projectionMap); qb.setTables(Tables.KEYS); - qb.appendWhere(KeysColumns.MASTER_KEY_ID + " = "); + qb.appendWhere(Keys.MASTER_KEY_ID + " = "); qb.appendWhereEscapeString(uri.getPathSegments().get(1)); break; @@ -315,7 +310,7 @@ public class KeychainProvider extends ContentProvider { case KEY_RING_USER_IDS: { HashMap projectionMap = new HashMap (); - projectionMap.put(BaseColumns._ID, Tables.USER_IDS + ".oid AS _id"); + projectionMap.put(UserIds._ID, Tables.USER_IDS + ".oid AS _id"); projectionMap.put(UserIds.MASTER_KEY_ID, UserIds.MASTER_KEY_ID); projectionMap.put(UserIds.USER_ID, UserIds.USER_ID); projectionMap.put(UserIds.RANK, UserIds.RANK); @@ -323,36 +318,44 @@ public class KeychainProvider extends ContentProvider { qb.setProjectionMap(projectionMap); qb.setTables(Tables.USER_IDS); - qb.appendWhere(UserIdsColumns.MASTER_KEY_ID + " = "); + qb.appendWhere(UserIds.MASTER_KEY_ID + " = "); qb.appendWhereEscapeString(uri.getPathSegments().get(1)); + if (TextUtils.isEmpty(sortOrder)) { + sortOrder = UserIds.RANK + " ASC"; + } + break; } + case KEY_RINGS_PUBLIC: case KEY_RING_PUBLIC: { HashMap projectionMap = new HashMap (); - projectionMap.put(BaseColumns._ID, Tables.KEY_RINGS_PUBLIC + ".oid AS _id"); - projectionMap.put(KeyRings.MASTER_KEY_ID, KeyRings.MASTER_KEY_ID); - projectionMap.put(KeyRings.KEY_RING_DATA, KeyRings.KEY_RING_DATA); + projectionMap.put(KeyRingData._ID, Tables.KEY_RINGS_PUBLIC + ".oid AS _id"); + projectionMap.put(KeyRingData.MASTER_KEY_ID, KeyRingData.MASTER_KEY_ID); + projectionMap.put(KeyRingData.KEY_RING_DATA, KeyRingData.KEY_RING_DATA); qb.setProjectionMap(projectionMap); qb.setTables(Tables.KEY_RINGS_PUBLIC); - qb.appendWhere(KeyRingsColumns.MASTER_KEY_ID + " = "); - qb.appendWhereEscapeString(uri.getPathSegments().get(1)); + + if(match == KEY_RING_PUBLIC) { + qb.appendWhere(KeyRings.MASTER_KEY_ID + " = "); + qb.appendWhereEscapeString(uri.getPathSegments().get(1)); + } break; } case KEY_RING_SECRET: { HashMap projectionMap = new HashMap (); - projectionMap.put(BaseColumns._ID, Tables.KEY_RINGS_SECRET + ".oid AS _id"); - projectionMap.put(KeyRings.MASTER_KEY_ID, KeyRings.MASTER_KEY_ID); - projectionMap.put(KeyRings.KEY_RING_DATA, KeyRings.KEY_RING_DATA); + projectionMap.put(KeyRingData._ID, Tables.KEY_RINGS_SECRET + ".oid AS _id"); + projectionMap.put(KeyRingData.MASTER_KEY_ID, KeyRingData.MASTER_KEY_ID); + projectionMap.put(KeyRingData.KEY_RING_DATA, KeyRingData.KEY_RING_DATA); qb.setProjectionMap(projectionMap); qb.setTables(Tables.KEY_RINGS_SECRET); - qb.appendWhere(KeyRingsColumns.MASTER_KEY_ID + " = "); + qb.appendWhere(KeyRings.MASTER_KEY_ID + " = "); qb.appendWhereEscapeString(uri.getPathSegments().get(1)); break; @@ -429,23 +432,23 @@ public class KeychainProvider extends ContentProvider { switch (match) { case KEY_RING_PUBLIC: db.insertOrThrow(Tables.KEY_RINGS_PUBLIC, null, values); - keyId = values.getAsLong(KeyRingsColumns.MASTER_KEY_ID); + keyId = values.getAsLong(KeyRings.MASTER_KEY_ID); break; case KEY_RING_SECRET: db.insertOrThrow(Tables.KEY_RINGS_SECRET, null, values); - keyId = values.getAsLong(KeyRingsColumns.MASTER_KEY_ID); + keyId = values.getAsLong(KeyRings.MASTER_KEY_ID); break; case KEY_RING_KEYS: Log.d(Constants.TAG, "keys"); db.insertOrThrow(Tables.KEYS, null, values); - keyId = values.getAsLong(KeysColumns.MASTER_KEY_ID); + keyId = values.getAsLong(Keys.MASTER_KEY_ID); break; case KEY_RING_USER_IDS: db.insertOrThrow(Tables.USER_IDS, null, values); - keyId = values.getAsLong(UserIdsColumns.MASTER_KEY_ID); + keyId = values.getAsLong(UserIds.MASTER_KEY_ID); break; case API_APPS: 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 18eaa375a..339e6a069 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 @@ -43,6 +43,7 @@ import org.sufficientlysecure.keychain.pgp.PgpHelper; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData; import org.sufficientlysecure.keychain.provider.KeychainContract.Keys; import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds; import org.sufficientlysecure.keychain.remote.AccountSettings; @@ -65,11 +66,11 @@ public class ProviderHelper { */ public static PGPKeyRing getPGPKeyRing(Context context, Uri queryUri) { Cursor cursor = context.getContentResolver().query(queryUri, - new String[]{KeyRings._ID, KeyRings.KEY_RING_DATA}, null, null, null); + new String[]{KeyRings._ID, KeyRingData.KEY_RING_DATA}, null, null, null); PGPKeyRing keyRing = null; if (cursor != null && cursor.moveToFirst()) { - int keyRingDataCol = cursor.getColumnIndex(KeyRings.KEY_RING_DATA); + int keyRingDataCol = cursor.getColumnIndex(KeyRingData.KEY_RING_DATA); byte[] data = cursor.getBlob(keyRingDataCol); if (data != null) { @@ -156,7 +157,7 @@ public class ProviderHelper { */ public static PGPPublicKeyRing getPGPPublicKeyRing(Context context, long masterKeyId) { - Uri queryUri = KeyRings.buildPublicKeyRingUri(Long.toString(masterKeyId)); + Uri queryUri = KeyRingData.buildPublicKeyRingUri(Long.toString(masterKeyId)); return (PGPPublicKeyRing) getPGPKeyRing(context, queryUri); } @@ -165,7 +166,7 @@ public class ProviderHelper { */ public static PGPSecretKeyRing getPGPSecretKeyRing(Context context, long masterKeyId) { - Uri queryUri = KeyRings.buildSecretKeyRingUri(Long.toString(masterKeyId)); + Uri queryUri = KeyRingData.buildSecretKeyRingUri(Long.toString(masterKeyId)); return (PGPSecretKeyRing) getPGPKeyRing(context, queryUri); } @@ -178,12 +179,11 @@ public class ProviderHelper { long masterKeyId = masterKey.getKeyID(); // IF there is a secret key, preserve it! - // TODO This even necessary? - // PGPSecretKeyRing secretRing = ProviderHelper.getPGPSecretKeyRing(context, masterKeyId); + PGPSecretKeyRing secretRing = ProviderHelper.getPGPSecretKeyRing(context, masterKeyId); // delete old version of this keyRing, which also deletes all keys and userIds on cascade try { - context.getContentResolver().delete(KeyRings.buildPublicKeyRingUri(Long.toString(masterKeyId)), null, null); + context.getContentResolver().delete(KeyRingData.buildPublicKeyRingUri(Long.toString(masterKeyId)), null, null); } catch (UnsupportedOperationException e) { Log.e(Constants.TAG, "Key could not be deleted! Maybe we are creating a new one!", e); } @@ -193,11 +193,11 @@ public class ProviderHelper { // NOTE: If we would not use the same _ID again, // getting back to the ViewKeyActivity would result in Nullpointer, // because the currently loaded key would be gone from the database - values.put(KeyRings.MASTER_KEY_ID, masterKeyId); - values.put(KeyRings.KEY_RING_DATA, keyRing.getEncoded()); + values.put(KeyRingData.MASTER_KEY_ID, masterKeyId); + values.put(KeyRingData.KEY_RING_DATA, keyRing.getEncoded()); // insert new version of this keyRing - Uri uri = KeyRings.buildPublicKeyRingUri(Long.toString(masterKeyId)); + Uri uri = KeyRingData.buildPublicKeyRingUri(Long.toString(masterKeyId)); Uri insertedUri = context.getContentResolver().insert(uri, values); // save all keys and userIds included in keyRing object in database @@ -233,31 +233,43 @@ public class ProviderHelper { } // Save the saved keyring (if any) - // TODO this even necessary? see above... - // if(secretRing != null) - // saveKeyRing(context, secretRing); + if(secretRing != null) { + saveKeyRing(context, secretRing); + } } /** - * Saves PGPSecretKeyRing with its keys and userIds in DB + * Saves a PGPSecretKeyRing in the DB. This will only work if a corresponding public keyring + * is already in the database! */ @SuppressWarnings("unchecked") public static void saveKeyRing(Context context, PGPSecretKeyRing keyRing) throws IOException { - PGPSecretKey masterKey = keyRing.getSecretKey(); - long masterKeyId = masterKey.getKeyID(); + long masterKeyId = keyRing.getPublicKey().getKeyID(); - // TODO Make sure there is a public key for this secret key in the db (create one maybe) + // save secret keyring + ContentValues values = new ContentValues(); + values.put(KeyRingData.MASTER_KEY_ID, masterKeyId); + values.put(KeyRingData.KEY_RING_DATA, keyRing.getEncoded()); + // insert new version of this keyRing + Uri uri = KeyRingData.buildSecretKeyRingUri(Long.toString(masterKeyId)); + context.getContentResolver().insert(uri, values); - { - ContentValues values = new ContentValues(); - values.put(KeyRings.MASTER_KEY_ID, masterKeyId); - values.put(KeyRings.KEY_RING_DATA, keyRing.getEncoded()); - // insert new version of this keyRing - Uri uri = KeyRings.buildSecretKeyRingUri(Long.toString(masterKeyId)); - context.getContentResolver().insert(uri, values); - } + } + /** + * Saves (or updates) a pair of public and secret KeyRings in the database + */ + @SuppressWarnings("unchecked") + public static void saveKeyRing(Context context, PGPPublicKeyRing pubRing, PGPSecretKeyRing privRing) throws IOException { + long masterKeyId = pubRing.getPublicKey().getKeyID(); + + // delete secret keyring (so it isn't unnecessarily saved by public-saveKeyRing below) + context.getContentResolver().delete(KeyRingData.buildSecretKeyRingUri(Long.toString(masterKeyId)), null, null); + + // save public keyring + saveKeyRing(context, pubRing); + saveKeyRing(context, privRing); } /** @@ -314,24 +326,14 @@ public class ProviderHelper { return ContentProviderOperation.newInsert(uri).withValues(values).build(); } - public static void deletePublicKeyRing(Context context, long masterKeyId) { - ContentResolver cr = context.getContentResolver(); - cr.delete(KeyRings.buildPublicKeyRingUri(Long.toString(masterKeyId)), null, null); - } - - public static void deleteSecretKeyRing(Context context, long masterKeyId) { - ContentResolver cr = context.getContentResolver(); - cr.delete(KeyRings.buildSecretKeyRingUri(Long.toString(masterKeyId)), null, null); - } - public static boolean hasSecretKeyByMasterKeyId(Context context, long masterKeyId) { - Uri queryUri = KeyRings.buildSecretKeyRingUri(Long.toString(masterKeyId)); + Uri queryUri = KeyRingData.buildSecretKeyRingUri(Long.toString(masterKeyId)); // see if we can get our master key id back from the uri return getMasterKeyId(context, queryUri) == masterKeyId; } - /** - * Get master key id of key + /** Find the master key id related to a given query. The id will either be extracted from the + * query, which should work for all specific /key_rings/ queries, or will be queried if it can't. */ public static long getMasterKeyId(Context context, Uri queryUri) { // try extracting from the uri first @@ -339,39 +341,25 @@ public class ProviderHelper { return Long.parseLong(queryUri.getPathSegments().get(1)); } catch(NumberFormatException e) { // didn't work? oh well. + Log.d(Constants.TAG, "Couldn't get masterKeyId from URI, querying..."); } - - Cursor cursor = context.getContentResolver().query(queryUri, new String[] { - KeyRings.MASTER_KEY_ID - }, null, null, null); - - long masterKeyId = 0; - try { - if (cursor != null && cursor.moveToFirst()) { - int masterKeyIdCol = cursor.getColumnIndexOrThrow(KeyRings.MASTER_KEY_ID); - - masterKeyId = cursor.getLong(masterKeyIdCol); - } - } finally { - if (cursor != null) { - cursor.close(); - } - } - - return masterKeyId; + Object data = getUnifiedData(context, queryUri, KeyRings.MASTER_KEY_ID); + if(data instanceof Long) + return (Long) data; + // TODO better error handling? + return 0L; } - public static ArrayList getKeyRingsAsArmoredString(Context context, Uri uri, - long[] masterKeyIds) { + public static ArrayList getKeyRingsAsArmoredString(Context context, long[] masterKeyIds) { ArrayList output = new ArrayList (); if (masterKeyIds != null && masterKeyIds.length > 0) { - Cursor cursor = getCursorWithSelectedKeyringMasterKeyIds(context, uri, masterKeyIds); + Cursor cursor = getCursorWithSelectedKeyringMasterKeyIds(context, masterKeyIds); if (cursor != null) { - int masterIdCol = cursor.getColumnIndex(KeyRings.MASTER_KEY_ID); - int dataCol = cursor.getColumnIndex(KeyRings.KEY_RING_DATA); + int masterIdCol = cursor.getColumnIndex(KeyRingData.MASTER_KEY_ID); + int dataCol = cursor.getColumnIndex(KeyRingData.KEY_RING_DATA); if (cursor.moveToFirst()) { do { Log.d(Constants.TAG, "masterKeyId: " + cursor.getLong(masterIdCol)); @@ -421,48 +409,11 @@ public class ProviderHelper { return null; } } - - public static byte[] getKeyRingsAsByteArray(Context context, Uri uri, long[] masterKeyIds) { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - - if (masterKeyIds != null && masterKeyIds.length > 0) { - - Cursor cursor = getCursorWithSelectedKeyringMasterKeyIds(context, uri, masterKeyIds); - - if (cursor != null) { - int masterIdCol = cursor.getColumnIndex(KeyRings.MASTER_KEY_ID); - int dataCol = cursor.getColumnIndex(KeyRings.KEY_RING_DATA); - if (cursor.moveToFirst()) { - do { - Log.d(Constants.TAG, "masterKeyId: " + cursor.getLong(masterIdCol)); - - // get actual keyring data blob and write it to ByteArrayOutputStream - try { - bos.write(cursor.getBlob(dataCol)); - } catch (IOException e) { - Log.e(Constants.TAG, "IOException", e); - } - } while (cursor.moveToNext()); - } - } - - if (cursor != null) { - cursor.close(); - } - - } else { - Log.e(Constants.TAG, "No master keys given!"); - } - - return bos.toByteArray(); - } - - private static Cursor getCursorWithSelectedKeyringMasterKeyIds(Context context, Uri baseUri, - long[] masterKeyIds) { + private static Cursor getCursorWithSelectedKeyringMasterKeyIds(Context context, long[] masterKeyIds) { Cursor cursor = null; if (masterKeyIds != null && masterKeyIds.length > 0) { - String inMasterKeyList = KeyRings.MASTER_KEY_ID + " IN ("; + String inMasterKeyList = KeyRingData.MASTER_KEY_ID + " IN ("; for (int i = 0; i < masterKeyIds.length; ++i) { if (i != 0) { inMasterKeyList += ", "; @@ -471,9 +422,9 @@ public class ProviderHelper { } inMasterKeyList += ")"; - cursor = context.getContentResolver().query(baseUri, - new String[]{KeyRings._ID, KeyRings.MASTER_KEY_ID, KeyRings.KEY_RING_DATA}, - inMasterKeyList, null, null); + cursor = context.getContentResolver().query(KeyRingData.buildPublicKeyRingUri(), new String[] { + KeyRingData._ID, KeyRingData.MASTER_KEY_ID, KeyRingData.KEY_RING_DATA + }, inMasterKeyList, null, null); } return cursor; 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 f9e143d87..6ee209c5c 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 @@ -518,8 +518,8 @@ public class KeychainIntentService extends IntentService PgpKeyOperation.Pair pair = keyOperations.buildSecretKey(privkey, pubkey, saveParams); setProgress(R.string.progress_saving_key_ring, 90, 100); - ProviderHelper.saveKeyRing(this, pair.first); - ProviderHelper.saveKeyRing(this, pair.second); + // save the pair + ProviderHelper.saveKeyRing(this, pair.second, pair.first); setProgress(R.string.progress_done, 100, 100); } PassphraseCacheService.addCachedPassphrase(this, masterKeyId, newPassphrase); 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 0caf60aa1..e6fd59d55 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 @@ -57,6 +57,7 @@ import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; import org.sufficientlysecure.keychain.service.PassphraseCacheService; @@ -345,7 +346,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener } return true; case R.id.menu_key_edit_delete: - Uri convertUri = KeychainContract.KeyRings.buildSecretKeyRingUri(mDataUri); + Uri convertUri = KeyRingData.buildSecretKeyRingUri(mDataUri); // Message is received after key is deleted Handler returnHandler = new Handler() { @Override diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java index cc0abe48a..ecd742896 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -58,12 +58,9 @@ import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.helper.ExportHelper; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; -import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; -import org.sufficientlysecure.keychain.provider.KeychainContract.KeyTypes; +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData; import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds; -import org.sufficientlysecure.keychain.provider.KeychainDatabase; -import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.ui.adapter.HighlightQueryCursorAdapter; import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment; import org.sufficientlysecure.keychain.util.Log; @@ -257,11 +254,11 @@ public class KeyListFragment extends Fragment // These are the rows that we will retrieve. static final String[] PROJECTION = new String[]{ - KeychainContract.KeyRings._ID, - KeychainContract.Keys.MASTER_KEY_ID, - KeychainContract.UserIds.USER_ID, - KeychainContract.Keys.IS_REVOKED, - KeychainDatabase.Tables.KEY_RINGS_SECRET + "." + KeychainContract.KeyRings.MASTER_KEY_ID + KeyRings._ID, + KeyRings.MASTER_KEY_ID, + KeyRings.USER_ID, + KeyRings.IS_REVOKED, + KeyRings.HAS_SECRET }; static final int INDEX_MASTER_KEY_ID = 1; @@ -269,11 +266,8 @@ public class KeyListFragment extends Fragment static final int INDEX_IS_REVOKED = 3; static final int INDEX_HAS_SECRET = 4; - static final String SORT_ORDER = - // show secret before public key - KeychainDatabase.Tables.KEY_RINGS_SECRET + "." + KeychainContract.KeyRings.MASTER_KEY_ID + " IS NULL ASC, " + - // sort by user id otherwise - UserIds.USER_ID + " ASC"; + // show secret before public key, sort by user id otherwise + static final String SORT_ORDER = KeyRings.HAS_SECRET + " DESC, " + UserIds.USER_ID + " ASC"; @Override public Loader onCreateLoader(int id, Bundle args) { @@ -283,7 +277,7 @@ public class KeyListFragment extends Fragment String where = null; String whereArgs[] = null; if (mCurQuery != null) { - where = KeychainContract.UserIds.USER_ID + " LIKE ?"; + where = KeyRings.USER_ID + " LIKE ?"; whereArgs = new String[]{"%" + mCurQuery + "%"}; } // Now create and return a CursorLoader that will take care of @@ -329,17 +323,15 @@ public class KeyListFragment extends Fragment viewIntent = new Intent(getActivity(), ViewKeyActivityJB.class); } viewIntent.setData( - KeychainContract - .KeyRings.buildGenericKeyRingUri( - Long.toString(mAdapter.getMasterKeyId(position)))); + KeyRings.buildGenericKeyRingUri(Long.toString(mAdapter.getMasterKeyId(position)))); startActivity(viewIntent); } @TargetApi(11) - protected void encrypt(ActionMode mode, long[] keyRingMasterKeyIds) { + protected void encrypt(ActionMode mode, long[] masterKeyIds) { Intent intent = new Intent(getActivity(), EncryptActivity.class); intent.setAction(EncryptActivity.ACTION_ENCRYPT); - intent.putExtra(EncryptActivity.EXTRA_ENCRYPTION_KEY_IDS, keyRingMasterKeyIds); + intent.putExtra(EncryptActivity.EXTRA_ENCRYPTION_KEY_IDS, masterKeyIds); // used instead of startActivity set actionbar based on callingPackage startActivityForResult(intent, 0); @@ -507,7 +499,7 @@ public class KeyListFragment extends Fragment Button button = (Button) view.findViewById(R.id.edit); TextView revoked = (TextView) view.findViewById(R.id.revoked); - if (!cursor.isNull(KeyListFragment.INDEX_HAS_SECRET)) { + if (cursor.getInt(KeyListFragment.INDEX_HAS_SECRET) != 0) { // this is a secret key - show the edit button statusDivider.setVisibility(View.VISIBLE); statusLayout.setVisibility(View.VISIBLE); @@ -518,9 +510,7 @@ public class KeyListFragment extends Fragment button.setOnClickListener(new OnClickListener() { public void onClick(View view) { Intent editIntent = new Intent(getActivity(), EditKeyActivity.class); - editIntent.setData( - KeychainContract.KeyRings - .buildSecretKeyRingUri(Long.toString(id))); + editIntent.setData(KeyRingData.buildSecretKeyRingUri(Long.toString(id))); editIntent.setAction(EditKeyActivity.ACTION_EDIT_KEY); startActivityForResult(editIntent, 0); } @@ -581,7 +571,7 @@ public class KeyListFragment extends Fragment throw new IllegalStateException("couldn't move cursor to position " + position); } - if (!mCursor.isNull(KeyListFragment.INDEX_HAS_SECRET)) { + if (mCursor.getInt(KeyListFragment.INDEX_HAS_SECRET) != 0) { { // set contact count int num = mCursor.getCount(); String contactsTotal = getResources().getQuantityString(R.plurals.n_contacts, num, num); @@ -621,7 +611,7 @@ public class KeyListFragment extends Fragment } // early breakout: all secret keys are assigned id 0 - if (!mCursor.isNull(KeyListFragment.INDEX_HAS_SECRET)) { + if (mCursor.getInt(KeyListFragment.INDEX_HAS_SECRET) != 0) { return 1L; } // otherwise, return the first character of the name as ID diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index 2437270e5..b60e75fa9 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -185,8 +185,8 @@ public class ViewKeyActivity extends ActionBarActivity { } else { // get public keyring as ascii armored string long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri); - ArrayList keyringArmored = ProviderHelper.getKeyRingsAsArmoredString(this, - dataUri, new long[]{masterKeyId}); + ArrayList keyringArmored = ProviderHelper.getKeyRingsAsArmoredString( + this, new long[]{ masterKeyId }); content = keyringArmored.get(0); @@ -216,8 +216,8 @@ public class ViewKeyActivity extends ActionBarActivity { private void copyToClipboard(Uri dataUri) { // get public keyring as ascii armored string long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri); - ArrayList keyringArmored = ProviderHelper.getKeyRingsAsArmoredString(this, dataUri, - new long[]{masterKeyId}); + ArrayList keyringArmored = ProviderHelper.getKeyRingsAsArmoredString( + this, new long[]{ masterKeyId }); ClipboardReflection.copyToClipboard(this, keyringArmored.get(0)); Toast.makeText(getApplicationContext(), R.string.key_copied_to_clipboard, Toast.LENGTH_LONG) diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java index 75853ac2a..616200800 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java @@ -38,7 +38,10 @@ import com.beardedhen.androidbootstrap.BootstrapButton; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; -import org.sufficientlysecure.keychain.provider.KeychainContract; +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.KeychainContract.KeyRingData; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.ui.adapter.ViewKeyKeysAdapter; import org.sufficientlysecure.keychain.ui.adapter.ViewKeyUserIdsAdapter; @@ -124,6 +127,7 @@ public class ViewKeyMainFragment extends Fragment implements { // label whether secret key is available, and edit button if it is final long masterKeyId = ProviderHelper.getMasterKeyId(getActivity(), mDataUri); + // TODO do this some other way... if (ProviderHelper.hasSecretKeyByMasterKeyId(getActivity(), masterKeyId)) { // set this attribute. this is a LITTLE unclean, but we have the info available // right here, so why not. @@ -141,8 +145,7 @@ public class ViewKeyMainFragment extends Fragment implements public void onClick(View view) { Intent editIntent = new Intent(getActivity(), EditKeyActivity.class); editIntent.setData( - KeychainContract - .KeyRings.buildSecretKeyRingUri( + KeyRingData.buildSecretKeyRingUri( Long.toString(masterKeyId))); editIntent.setAction(EditKeyActivity.ACTION_EDIT_KEY); startActivityForResult(editIntent, 0); @@ -161,7 +164,7 @@ public class ViewKeyMainFragment extends Fragment implements // TODO see todo note above, doing this here for now mActionCertify.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { - certifyKey(KeychainContract.KeyRings.buildGenericKeyRingUri( + certifyKey(KeyRings.buildGenericKeyRingUri( Long.toString(masterKeyId) )); } @@ -190,31 +193,26 @@ public class ViewKeyMainFragment extends Fragment implements } static final String[] USER_IDS_PROJECTION = - new String[]{ - KeychainContract.UserIds._ID, - KeychainContract.UserIds.USER_ID, - KeychainContract.UserIds.RANK, + new String[] { + UserIds._ID, + UserIds.USER_ID, + UserIds.RANK, }; static final int INDEX_UID_UID = 1; - static final String USER_IDS_SORT_ORDER = - KeychainContract.UserIds.RANK + " COLLATE LOCALIZED ASC"; - static final String[] KEYS_PROJECTION = - new String[]{KeychainContract.Keys._ID, KeychainContract.Keys.KEY_ID, - KeychainContract.Keys.ALGORITHM, KeychainContract.Keys.RANK, - KeychainContract.Keys.KEY_SIZE, KeychainContract.Keys.CAN_CERTIFY, - KeychainContract.Keys.CAN_SIGN, KeychainContract.Keys.CAN_ENCRYPT, - KeychainContract.Keys.IS_REVOKED, KeychainContract.Keys.CREATION, - KeychainContract.Keys.EXPIRY, KeychainContract.Keys.FINGERPRINT}; - static final String KEYS_SORT_ORDER = KeychainContract.Keys.RANK + " ASC"; + static final String[] KEYS_PROJECTION = new String[] { + Keys._ID, + Keys.KEY_ID, Keys.RANK, + Keys.ALGORITHM, Keys.KEY_SIZE, + Keys.CAN_CERTIFY, Keys.CAN_ENCRYPT, + Keys.CAN_SIGN, Keys.IS_REVOKED, + Keys.CREATION, Keys.EXPIRY, + Keys.FINGERPRINT + }; static final int KEYS_INDEX_KEY_ID = 1; - static final int KEYS_INDEX_ALGORITHM = 2; - static final int KEYS_INDEX_RANK = 3; + static final int KEYS_INDEX_ALGORITHM = 3; static final int KEYS_INDEX_KEY_SIZE = 4; - static final int KEYS_INDEX_CAN_CERTIFY = 5; - static final int KEYS_INDEX_CAN_SIGN = 6; - static final int KEYS_INDEX_CAN_ENCRYPT = 7; - static final int KEYS_INDEX_IS_REVOKED = 8; + static final int KEYS_INDEX_CAN_ENCRYPT = 6; static final int KEYS_INDEX_CREATION = 9; static final int KEYS_INDEX_EXPIRY = 10; static final int KEYS_INDEX_FINGERPRINT = 11; @@ -222,19 +220,18 @@ public class ViewKeyMainFragment extends Fragment implements public Loader onCreateLoader(int id, Bundle args) { switch (id) { case LOADER_ID_USER_IDS: { - Uri baseUri = KeychainContract.UserIds.buildUserIdsUri(mDataUri); + Uri baseUri = UserIds.buildUserIdsUri(mDataUri); // Now create and return a CursorLoader that will take care of // creating a Cursor for the data being displayed. - return new CursorLoader(getActivity(), baseUri, USER_IDS_PROJECTION, null, null, - USER_IDS_SORT_ORDER); + return new CursorLoader(getActivity(), baseUri, USER_IDS_PROJECTION, null, null, null); } case LOADER_ID_KEYS: { - Uri baseUri = KeychainContract.Keys.buildKeysUri(mDataUri); + Uri baseUri = Keys.buildKeysUri(mDataUri); // Now create and return a CursorLoader that will take care of // creating a Cursor for the data being displayed. - return new CursorLoader(getActivity(), baseUri, KEYS_PROJECTION, null, null, KEYS_SORT_ORDER); + return new CursorLoader(getActivity(), baseUri, KEYS_PROJECTION, null, null, null); } default: @@ -343,7 +340,7 @@ public class ViewKeyMainFragment extends Fragment implements private void encryptToContact(Uri dataUri) { // TODO preselect from uri? should be feasible without trivial query - long keyId = Long.parseLong(dataUri.getPathSegments().get(1)); + long keyId = ProviderHelper.getMasterKeyId(getActivity(), dataUri); long[] encryptionKeyIds = new long[]{ keyId }; Intent intent = new Intent(getActivity(), EncryptActivity.class); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java index 57dbb7794..feaa0b4cd 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java @@ -20,8 +20,6 @@ package org.sufficientlysecure.keychain.ui.dialog; import android.app.AlertDialog; import android.app.Dialog; import android.content.DialogInterface; -import android.database.Cursor; -import android.net.Uri; import android.os.Bundle; import android.os.Message; import android.os.Messenger; @@ -35,14 +33,13 @@ import android.widget.LinearLayout; import android.widget.TextView; import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData; +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainDatabase; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.util.Log; -import java.util.ArrayList; import java.util.HashMap; public class DeleteKeyDialogFragment extends DialogFragment { @@ -107,13 +104,11 @@ public class DeleteKeyDialogFragment extends DialogFragment { long masterKeyId = masterKeyIds[0]; HashMap data = ProviderHelper.getUnifiedData(activity, masterKeyId, new String[]{ - KeychainContract.UserIds.USER_ID, - KeychainDatabase.Tables.KEY_RINGS_SECRET + "." + KeychainContract.KeyRings.MASTER_KEY_ID + KeyRings.USER_ID, + KeyRings.HAS_SECRET }); - String userId = (String) data.get(KeychainContract.UserIds.USER_ID); - boolean hasSecret = data.get( - KeychainDatabase.Tables.KEY_RINGS_SECRET + "." + KeychainContract.KeyRings.MASTER_KEY_ID - ) instanceof Long; + String userId = (String) data.get(KeyRings.USER_ID); + boolean hasSecret = ((Long) data.get(KeyRings.HAS_SECRET)) == 1; // Hide the Checkbox and TextView since this is a single selection,user will be notified through message mDeleteSecretKeyView.setVisibility(View.GONE); @@ -136,7 +131,7 @@ public class DeleteKeyDialogFragment extends DialogFragment { boolean success = false; for(long masterKeyId : masterKeyIds) { int count = activity.getContentResolver().delete( - KeychainContract.KeyRings.buildPublicKeyRingUri(Long.toString(masterKeyId)), null, null + KeyRingData.buildPublicKeyRingUri(Long.toString(masterKeyId)), null, null ); if(count > 0) success = true; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java index 1b81c8b3b..dc9fa6235 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java @@ -107,7 +107,7 @@ public class ShareQrCodeDialogFragment extends DialogFragment { long masterKeyId = ProviderHelper.getMasterKeyId(getActivity(), dataUri); // get public keyring as ascii armored string ArrayList keyringArmored = ProviderHelper.getKeyRingsAsArmoredString( - getActivity(), dataUri, new long[] { masterKeyId }); + getActivity(), new long[] { masterKeyId }); // TODO: binary?