Merge branch 'unified-keylist'

Conflicts:
	OpenPGP-Keychain/src/main/AndroidManifest.xml
	OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java
	OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java
	OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListSecretActivity.java
	OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListSecretFragment.java
	OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java
	OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListSecretAdapter.java
	OpenPGP-Keychain/src/main/res/layout/key_list_secret_item.xml
	OpenPGP-Keychain/src/main/res/menu/key_list.xml
	OpenPGP-Keychain/src/main/res/menu/key_list_multi.xml
	OpenPGP-Keychain/src/main/res/menu/key_list_secret_multi.xml
This commit is contained in:
Vincent Breitmoser
2014-03-12 18:05:28 +01:00
27 changed files with 600 additions and 876 deletions

View File

@@ -78,6 +78,7 @@ public class KeychainContract {
public static final String PATH_PUBLIC = "public";
public static final String PATH_SECRET = "secret";
public static final String PATH_UNIFIED = "unified";
public static final String PATH_BY_MASTER_KEY_ID = "master_key_id";
public static final String PATH_BY_KEY_ID = "key_id";
@@ -100,6 +101,10 @@ public class KeychainContract {
/** Use if a single item is returned */
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.key_ring";
public static Uri buildUnifiedKeyRingsUri() {
return CONTENT_URI.buildUpon().appendPath(PATH_UNIFIED).build();
}
public static Uri buildPublicKeyRingsUri() {
return CONTENT_URI.buildUpon().appendPath(PATH_PUBLIC).build();
}

View File

@@ -81,6 +81,8 @@ public class KeychainProvider extends ContentProvider {
private static final int API_APPS_BY_ROW_ID = 302;
private static final int API_APPS_BY_PACKAGE_NAME = 303;
private static final int UNIFIED_KEY_RING = 401;
// private static final int DATA_STREAM = 401;
protected UriMatcher mUriMatcher;
@@ -226,6 +228,16 @@ public class KeychainProvider extends ContentProvider {
matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/"
+ KeychainContract.PATH_BY_PACKAGE_NAME + "/*", API_APPS_BY_PACKAGE_NAME);
/**
* unified key rings
* <pre>
*
* key_rings/unified
*
*/
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
+ KeychainContract.PATH_UNIFIED, UNIFIED_KEY_RING);
/**
* data stream
*
@@ -455,6 +467,69 @@ public class KeychainProvider extends ContentProvider {
int match = mUriMatcher.match(uri);
// screw that switch
if(match == UNIFIED_KEY_RING) {
// join keyrings with keys and userIds
// Only get user id and key with rank 0 (main user id and main key)
qb.setTables(Tables.KEY_RINGS + " INNER JOIN " + Tables.KEYS + " ON " + "("
+ Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.KEYS + "."
+ KeysColumns.KEY_RING_ROW_ID + " AND " + Tables.KEYS + "."
+ KeysColumns.RANK + " = '0') " + " INNER JOIN " + Tables.USER_IDS + " ON "
+ "(" + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.USER_IDS + "."
+ UserIdsColumns.KEY_RING_ROW_ID + " AND " + Tables.USER_IDS + "."
+ UserIdsColumns.RANK + " = '0')");
{
HashMap<String, String> projectionMap = new HashMap<String, String>();
projectionMap.put(KeyRingsColumns.TYPE, "MAX(" + Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + ")");
projectionMap.put(BaseColumns._ID, Tables.KEY_RINGS + "." + BaseColumns._ID);
projectionMap.put(KeyRingsColumns.KEY_RING_DATA, Tables.KEY_RINGS + "."
+ KeyRingsColumns.KEY_RING_DATA);
projectionMap.put(KeyRingsColumns.MASTER_KEY_ID, Tables.KEY_RINGS + "." + KeyRingsColumns.MASTER_KEY_ID);
// TODO: deprecated master key id
//projectionMap.put(KeyRingsColumns.MASTER_KEY_ID, Tables.KEYS + "." + KeysColumns.KEY_ID);
projectionMap.put(KeysColumns.FINGERPRINT, Tables.KEYS + "." + KeysColumns.FINGERPRINT);
projectionMap.put(KeysColumns.IS_REVOKED, Tables.KEYS + "." + KeysColumns.IS_REVOKED);
projectionMap.put(UserIdsColumns.USER_ID, Tables.USER_IDS + "." + UserIdsColumns.USER_ID);
qb.setProjectionMap(projectionMap);
}
if (TextUtils.isEmpty(sortOrder)) {
sortOrder = Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC";
}
// If no sort order is specified use the default
String orderBy;
if (TextUtils.isEmpty(sortOrder)) {
orderBy = Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + " DESC";
} else {
orderBy = Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + " DESC, " + sortOrder;
}
Cursor c = qb.query(db, projection, selection, selectionArgs,
Tables.KEY_RINGS + "." + KeyRingsColumns.MASTER_KEY_ID,
null, orderBy);
// Tell the cursor what uri to watch, so it knows when its source data changes
c.setNotificationUri(getContext().getContentResolver(), uri);
if (Constants.DEBUG) {
Log.d(Constants.TAG,
"Query: "
+ qb.buildQuery(projection, selection, selectionArgs, Tables.KEY_RINGS + "." + KeyRingsColumns.MASTER_KEY_ID, null,
orderBy, null));
Log.d(Constants.TAG, "Cursor: " + DatabaseUtils.dumpCursorToString(c));
}
return c;
}
switch (match) {
case PUBLIC_KEY_RING:
case SECRET_KEY_RING:

View File

@@ -483,13 +483,13 @@ public class ProviderHelper {
*/
public static boolean getSecretMasterKeyCanSign(Context context, long keyRingRowId) {
Uri queryUri = KeyRings.buildSecretKeyRingsUri(String.valueOf(keyRingRowId));
return getMasterKeyCanSign(context, queryUri, keyRingRowId);
return getMasterKeyCanSign(context, queryUri);
}
/**
* Private helper method to get master key private empty status of keyring by its row id
*/
private static boolean getMasterKeyCanSign(Context context, Uri queryUri, long keyRingRowId) {
public static boolean getMasterKeyCanSign(Context context, Uri queryUri) {
String[] projection = new String[]{
KeyRings.MASTER_KEY_ID,
"(SELECT COUNT(sign_keys." + Keys._ID + ") FROM " + Tables.KEYS
@@ -515,6 +515,12 @@ public class ProviderHelper {
return (masterKeyId > 0);
}
public static boolean hasSecretKeyByMasterKeyId(Context context, long masterKeyId) {
Uri queryUri = KeyRings.buildSecretKeyRingsByMasterKeyIdUri(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 keyring by its row id
*/
@@ -546,6 +552,26 @@ public class ProviderHelper {
return masterKeyId;
}
public static long getRowId(Context context, Uri queryUri) {
String[] projection = new String[]{KeyRings._ID};
Cursor cursor = context.getContentResolver().query(queryUri, projection, null, null, null);
long rowId = 0;
try {
if (cursor != null && cursor.moveToFirst()) {
int idCol = cursor.getColumnIndexOrThrow(KeyRings._ID);
rowId = cursor.getLong(idCol);
}
} finally {
if (cursor != null) {
cursor.close();
}
}
return rowId;
}
/**
* Get fingerprint of key
*/