save keyring in-place, fixes #228, #203

This commit is contained in:
Dominik Schürmann
2014-01-29 03:06:26 +01:00
parent ca9696ff34
commit f276455624
3 changed files with 235 additions and 201 deletions

View File

@@ -62,7 +62,7 @@ public class ProviderHelper {
*/ */
public static PGPKeyRing getPGPKeyRing(Context context, Uri queryUri) { public static PGPKeyRing getPGPKeyRing(Context context, Uri queryUri) {
Cursor cursor = context.getContentResolver().query(queryUri, Cursor cursor = context.getContentResolver().query(queryUri,
new String[] { KeyRings._ID, KeyRings.KEY_RING_DATA }, null, null, null); new String[]{KeyRings._ID, KeyRings.KEY_RING_DATA}, null, null, null);
PGPKeyRing keyRing = null; PGPKeyRing keyRing = null;
if (cursor != null && cursor.moveToFirst()) { if (cursor != null && cursor.moveToFirst()) {
@@ -101,7 +101,7 @@ public class ProviderHelper {
* @return * @return
*/ */
public static PGPPublicKeyRing getPGPPublicKeyRingByMasterKeyId(Context context, public static PGPPublicKeyRing getPGPPublicKeyRingByMasterKeyId(Context context,
long masterKeyId) { long masterKeyId) {
Uri queryUri = KeyRings.buildPublicKeyRingsByMasterKeyIdUri(Long.toString(masterKeyId)); Uri queryUri = KeyRings.buildPublicKeyRingsByMasterKeyIdUri(Long.toString(masterKeyId));
return (PGPPublicKeyRing) getPGPKeyRing(context, queryUri); return (PGPPublicKeyRing) getPGPKeyRing(context, queryUri);
} }
@@ -156,7 +156,7 @@ public class ProviderHelper {
* @return * @return
*/ */
public static PGPSecretKeyRing getPGPSecretKeyRingByMasterKeyId(Context context, public static PGPSecretKeyRing getPGPSecretKeyRingByMasterKeyId(Context context,
long masterKeyId) { long masterKeyId) {
Uri queryUri = KeyRings.buildSecretKeyRingsByMasterKeyIdUri(Long.toString(masterKeyId)); Uri queryUri = KeyRings.buildSecretKeyRingsByMasterKeyIdUri(Long.toString(masterKeyId));
return (PGPSecretKeyRing) getPGPKeyRing(context, queryUri); return (PGPSecretKeyRing) getPGPKeyRing(context, queryUri);
} }
@@ -205,9 +205,18 @@ public class ProviderHelper {
PGPPublicKey masterKey = keyRing.getPublicKey(); PGPPublicKey masterKey = keyRing.getPublicKey();
long masterKeyId = masterKey.getKeyID(); long masterKeyId = masterKey.getKeyID();
// delete old version of this keyRing, which also deletes all keys and userIds on cascade
Uri deleteUri = KeyRings.buildPublicKeyRingsByMasterKeyIdUri(Long.toString(masterKeyId)); Uri deleteUri = KeyRings.buildPublicKeyRingsByMasterKeyIdUri(Long.toString(masterKeyId));
// get current _ID of key
long currentRowId = -1;
Cursor oldQuery = context.getContentResolver().query(deleteUri, new String[]{KeyRings._ID}, null, null, null);
if (oldQuery != null && oldQuery.moveToFirst()) {
currentRowId = oldQuery.getLong(0);
} else {
Log.e(Constants.TAG, "Key could not be found! Something wrong is happening!");
}
// delete old version of this keyRing, which also deletes all keys and userIds on cascade
try { try {
context.getContentResolver().delete(deleteUri, null, null); context.getContentResolver().delete(deleteUri, null, null);
} catch (UnsupportedOperationException e) { } catch (UnsupportedOperationException e) {
@@ -215,6 +224,11 @@ public class ProviderHelper {
} }
ContentValues values = new ContentValues(); ContentValues values = new ContentValues();
// use exactly the same _ID again to replace key in-place.
// 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
if (currentRowId != -1)
values.put(KeyRings._ID, currentRowId);
values.put(KeyRings.MASTER_KEY_ID, masterKeyId); values.put(KeyRings.MASTER_KEY_ID, masterKeyId);
values.put(KeyRings.KEY_RING_DATA, keyRing.getEncoded()); values.put(KeyRings.KEY_RING_DATA, keyRing.getEncoded());
@@ -261,9 +275,18 @@ public class ProviderHelper {
PGPSecretKey masterKey = keyRing.getSecretKey(); PGPSecretKey masterKey = keyRing.getSecretKey();
long masterKeyId = masterKey.getKeyID(); long masterKeyId = masterKey.getKeyID();
// delete old version of this keyRing, which also deletes all keys and userIds on cascade
Uri deleteUri = KeyRings.buildSecretKeyRingsByMasterKeyIdUri(Long.toString(masterKeyId)); Uri deleteUri = KeyRings.buildSecretKeyRingsByMasterKeyIdUri(Long.toString(masterKeyId));
// get current _ID of key
long currentRowId = -1;
Cursor oldQuery = context.getContentResolver().query(deleteUri, new String[]{KeyRings._ID}, null, null, null);
if (oldQuery != null && oldQuery.moveToFirst()) {
currentRowId = oldQuery.getLong(0);
} else {
Log.e(Constants.TAG, "Key could not be found! Something wrong is happening!");
}
// delete old version of this keyRing, which also deletes all keys and userIds on cascade
try { try {
context.getContentResolver().delete(deleteUri, null, null); context.getContentResolver().delete(deleteUri, null, null);
} catch (UnsupportedOperationException e) { } catch (UnsupportedOperationException e) {
@@ -271,6 +294,11 @@ public class ProviderHelper {
} }
ContentValues values = new ContentValues(); ContentValues values = new ContentValues();
// use exactly the same _ID again to replace key in-place.
// 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
if (currentRowId != -1)
values.put(KeyRings._ID, currentRowId);
values.put(KeyRings.MASTER_KEY_ID, masterKeyId); values.put(KeyRings.MASTER_KEY_ID, masterKeyId);
values.put(KeyRings.KEY_RING_DATA, keyRing.getEncoded()); values.put(KeyRings.KEY_RING_DATA, keyRing.getEncoded());
@@ -314,7 +342,7 @@ public class ProviderHelper {
* @throws IOException * @throws IOException
*/ */
private static ContentProviderOperation buildPublicKeyOperations(Context context, private static ContentProviderOperation buildPublicKeyOperations(Context context,
long keyRingRowId, PGPPublicKey key, int rank) throws IOException { long keyRingRowId, PGPPublicKey key, int rank) throws IOException {
ContentValues values = new ContentValues(); ContentValues values = new ContentValues();
values.put(Keys.KEY_ID, key.getKeyID()); values.put(Keys.KEY_ID, key.getKeyID());
values.put(Keys.IS_MASTER_KEY, key.isMasterKey()); values.put(Keys.IS_MASTER_KEY, key.isMasterKey());
@@ -348,7 +376,7 @@ public class ProviderHelper {
* @throws IOException * @throws IOException
*/ */
private static ContentProviderOperation buildPublicUserIdOperations(Context context, private static ContentProviderOperation buildPublicUserIdOperations(Context context,
long keyRingRowId, String userId, int rank) { long keyRingRowId, String userId, int rank) {
ContentValues values = new ContentValues(); ContentValues values = new ContentValues();
values.put(UserIds.KEY_RING_ROW_ID, keyRingRowId); values.put(UserIds.KEY_RING_ROW_ID, keyRingRowId);
values.put(UserIds.USER_ID, userId); values.put(UserIds.USER_ID, userId);
@@ -370,7 +398,7 @@ public class ProviderHelper {
* @throws IOException * @throws IOException
*/ */
private static ContentProviderOperation buildSecretKeyOperations(Context context, private static ContentProviderOperation buildSecretKeyOperations(Context context,
long keyRingRowId, PGPSecretKey key, int rank) throws IOException { long keyRingRowId, PGPSecretKey key, int rank) throws IOException {
ContentValues values = new ContentValues(); ContentValues values = new ContentValues();
boolean has_private = true; boolean has_private = true;
@@ -413,7 +441,7 @@ public class ProviderHelper {
* @throws IOException * @throws IOException
*/ */
private static ContentProviderOperation buildSecretUserIdOperations(Context context, private static ContentProviderOperation buildSecretUserIdOperations(Context context,
long keyRingRowId, String userId, int rank) { long keyRingRowId, String userId, int rank) {
ContentValues values = new ContentValues(); ContentValues values = new ContentValues();
values.put(UserIds.KEY_RING_ROW_ID, keyRingRowId); values.put(UserIds.KEY_RING_ROW_ID, keyRingRowId);
values.put(UserIds.USER_ID, userId); values.put(UserIds.USER_ID, userId);
@@ -433,7 +461,7 @@ public class ProviderHelper {
*/ */
private static ArrayList<Long> getKeyRingsMasterKeyIds(Context context, Uri queryUri) { private static ArrayList<Long> getKeyRingsMasterKeyIds(Context context, Uri queryUri) {
Cursor cursor = context.getContentResolver().query(queryUri, Cursor cursor = context.getContentResolver().query(queryUri,
new String[] { KeyRings.MASTER_KEY_ID }, null, null, null); new String[]{KeyRings.MASTER_KEY_ID}, null, null, null);
ArrayList<Long> masterKeyIds = new ArrayList<Long>(); ArrayList<Long> masterKeyIds = new ArrayList<Long>();
if (cursor != null) { if (cursor != null) {
@@ -517,13 +545,13 @@ public class ProviderHelper {
* @return * @return
*/ */
private static boolean getMasterKeyCanSign(Context context, Uri queryUri, long keyRingRowId) { private static boolean getMasterKeyCanSign(Context context, Uri queryUri, long keyRingRowId) {
String[] projection = new String[] { String[] projection = new String[]{
KeyRings.MASTER_KEY_ID, KeyRings.MASTER_KEY_ID,
"(SELECT COUNT(sign_keys." + Keys._ID + ") FROM " + Tables.KEYS "(SELECT COUNT(sign_keys." + Keys._ID + ") FROM " + Tables.KEYS
+ " AS sign_keys WHERE sign_keys." + Keys.KEY_RING_ROW_ID + " = " + " AS sign_keys WHERE sign_keys." + Keys.KEY_RING_ROW_ID + " = "
+ KeychainDatabase.Tables.KEY_RINGS + "." + KeyRings._ID + KeychainDatabase.Tables.KEY_RINGS + "." + KeyRings._ID
+ " AND sign_keys." + Keys.CAN_SIGN + " = '1' AND " + Keys.IS_MASTER_KEY + " AND sign_keys." + Keys.CAN_SIGN + " = '1' AND " + Keys.IS_MASTER_KEY
+ " = 1) AS sign", }; + " = 1) AS sign",};
ContentResolver cr = context.getContentResolver(); ContentResolver cr = context.getContentResolver();
Cursor cursor = cr.query(queryUri, projection, null, null, null); Cursor cursor = cr.query(queryUri, projection, null, null, null);
@@ -563,7 +591,7 @@ public class ProviderHelper {
* @return * @return
*/ */
public static long getMasterKeyId(Context context, Uri queryUri) { public static long getMasterKeyId(Context context, Uri queryUri) {
String[] projection = new String[] { KeyRings.MASTER_KEY_ID }; String[] projection = new String[]{KeyRings.MASTER_KEY_ID};
ContentResolver cr = context.getContentResolver(); ContentResolver cr = context.getContentResolver();
Cursor cursor = cr.query(queryUri, projection, null, null, null); Cursor cursor = cr.query(queryUri, projection, null, null, null);
@@ -583,17 +611,17 @@ public class ProviderHelper {
} }
public static ArrayList<String> getPublicKeyRingsAsArmoredString(Context context, public static ArrayList<String> getPublicKeyRingsAsArmoredString(Context context,
long[] masterKeyIds) { long[] masterKeyIds) {
return getKeyRingsAsArmoredString(context, KeyRings.buildPublicKeyRingsUri(), masterKeyIds); return getKeyRingsAsArmoredString(context, KeyRings.buildPublicKeyRingsUri(), masterKeyIds);
} }
public static ArrayList<String> getSecretKeyRingsAsArmoredString(Context context, public static ArrayList<String> getSecretKeyRingsAsArmoredString(Context context,
long[] masterKeyIds) { long[] masterKeyIds) {
return getKeyRingsAsArmoredString(context, KeyRings.buildSecretKeyRingsUri(), masterKeyIds); return getKeyRingsAsArmoredString(context, KeyRings.buildSecretKeyRingsUri(), masterKeyIds);
} }
public static ArrayList<String> getKeyRingsAsArmoredString(Context context, Uri uri, public static ArrayList<String> getKeyRingsAsArmoredString(Context context, Uri uri,
long[] masterKeyIds) { long[] masterKeyIds) {
ArrayList<String> output = new ArrayList<String>(); ArrayList<String> output = new ArrayList<String>();
if (masterKeyIds != null && masterKeyIds.length > 0) { if (masterKeyIds != null && masterKeyIds.length > 0) {
@@ -697,7 +725,7 @@ public class ProviderHelper {
} }
private static Cursor getCursorWithSelectedKeyringMasterKeyIds(Context context, Uri baseUri, private static Cursor getCursorWithSelectedKeyringMasterKeyIds(Context context, Uri baseUri,
long[] masterKeyIds) { long[] masterKeyIds) {
Cursor cursor = null; Cursor cursor = null;
if (masterKeyIds != null && masterKeyIds.length > 0) { if (masterKeyIds != null && masterKeyIds.length > 0) {
@@ -711,7 +739,7 @@ public class ProviderHelper {
inMasterKeyList += ")"; inMasterKeyList += ")";
cursor = context.getContentResolver().query(baseUri, cursor = context.getContentResolver().query(baseUri,
new String[] { KeyRings._ID, KeyRings.MASTER_KEY_ID, KeyRings.KEY_RING_DATA }, new String[]{KeyRings._ID, KeyRings.MASTER_KEY_ID, KeyRings.KEY_RING_DATA},
inMasterKeyList, null, null); inMasterKeyList, null, null);
} }
@@ -788,7 +816,7 @@ public class ProviderHelper {
public static byte[] getApiAppSignature(Context context, String packageName) { public static byte[] getApiAppSignature(Context context, String packageName) {
Uri queryUri = KeychainContract.ApiApps.buildByPackageNameUri(packageName); Uri queryUri = KeychainContract.ApiApps.buildByPackageNameUri(packageName);
String[] projection = new String[] { ApiApps.PACKAGE_SIGNATURE }; String[] projection = new String[]{ApiApps.PACKAGE_SIGNATURE};
ContentResolver cr = context.getContentResolver(); ContentResolver cr = context.getContentResolver();
Cursor cursor = cr.query(queryUri, projection, null, null, null); Cursor cursor = cr.query(queryUri, projection, null, null, null);

View File

@@ -236,6 +236,7 @@ public class SignKeyActivity extends SherlockFragmentActivity implements
*/ */
uploadKey(); uploadKey();
} else { } else {
setResult(RESULT_OK);
finish(); finish();
} }
} }
@@ -278,10 +279,10 @@ public class SignKeyActivity extends SherlockFragmentActivity implements
super.handleMessage(message); super.handleMessage(message);
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
Toast.makeText(SignKeyActivity.this, R.string.key_send_success, Toast.makeText(SignKeyActivity.this, R.string.key_send_success,
Toast.LENGTH_SHORT).show(); Toast.LENGTH_SHORT).show();
setResult(RESULT_OK);
finish(); finish();
} }
}; };

View File

@@ -20,6 +20,7 @@ package org.sufficientlysecure.keychain.ui;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.Objects;
import org.spongycastle.openpgp.PGPPublicKey; import org.spongycastle.openpgp.PGPPublicKey;
import org.spongycastle.openpgp.PGPPublicKeyRing; import org.spongycastle.openpgp.PGPPublicKeyRing;
@@ -111,16 +112,7 @@ public class ViewKeyActivity extends SherlockFragmentActivity implements
mUserIds = (ListView) findViewById(R.id.user_ids); mUserIds = (ListView) findViewById(R.id.user_ids);
mKeys = (ListView) findViewById(R.id.keys); mKeys = (ListView) findViewById(R.id.keys);
Intent intent = getIntent(); loadData(getIntent());
mDataUri = intent.getData();
if (mDataUri == null) {
Log.e(Constants.TAG, "Intent data missing. Should be Uri of key!");
finish();
return;
} else {
Log.d(Constants.TAG, "uri: " + mDataUri);
loadData(mDataUri);
}
} }
@Override @Override
@@ -133,62 +125,76 @@ public class ViewKeyActivity extends SherlockFragmentActivity implements
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case android.R.id.home: case android.R.id.home:
Intent homeIntent = new Intent(this, KeyListPublicActivity.class); Intent homeIntent = new Intent(this, KeyListPublicActivity.class);
homeIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); homeIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(homeIntent); startActivity(homeIntent);
return true; return true;
case R.id.menu_key_view_update: case R.id.menu_key_view_update:
updateFromKeyserver(mDataUri); updateFromKeyserver(mDataUri);
return true; return true;
case R.id.menu_key_view_sign: case R.id.menu_key_view_sign:
signKey(mDataUri); signKey(mDataUri);
return true; return true;
case R.id.menu_key_view_export_keyserver: case R.id.menu_key_view_export_keyserver:
uploadToKeyserver(mDataUri); uploadToKeyserver(mDataUri);
return true; return true;
case R.id.menu_key_view_export_file: case R.id.menu_key_view_export_file:
mExportHelper.showExportKeysDialog(mDataUri, Id.type.public_key, Constants.path.APP_DIR mExportHelper.showExportKeysDialog(mDataUri, Id.type.public_key, Constants.path.APP_DIR
+ "/pubexport.asc"); + "/pubexport.asc");
return true; return true;
case R.id.menu_key_view_share_default_fingerprint: case R.id.menu_key_view_share_default_fingerprint:
shareKey(mDataUri, true); shareKey(mDataUri, true);
return true; return true;
case R.id.menu_key_view_share_default: case R.id.menu_key_view_share_default:
shareKey(mDataUri, false); shareKey(mDataUri, false);
return true; return true;
case R.id.menu_key_view_share_qr_code_fingerprint: case R.id.menu_key_view_share_qr_code_fingerprint:
shareKeyQrCode(mDataUri, true); shareKeyQrCode(mDataUri, true);
return true; return true;
case R.id.menu_key_view_share_qr_code: case R.id.menu_key_view_share_qr_code:
shareKeyQrCode(mDataUri, false); shareKeyQrCode(mDataUri, false);
return true; return true;
case R.id.menu_key_view_share_nfc: case R.id.menu_key_view_share_nfc:
shareNfc(); shareNfc();
return true; return true;
case R.id.menu_key_view_share_clipboard: case R.id.menu_key_view_share_clipboard:
copyToClipboard(mDataUri); copyToClipboard(mDataUri);
return true; return true;
case R.id.menu_key_view_delete: { case R.id.menu_key_view_delete: {
// Message is received after key is deleted // Message is received after key is deleted
Handler returnHandler = new Handler() { Handler returnHandler = new Handler() {
@Override @Override
public void handleMessage(Message message) { public void handleMessage(Message message) {
if (message.what == DeleteKeyDialogFragment.MESSAGE_OKAY) { if (message.what == DeleteKeyDialogFragment.MESSAGE_OKAY) {
setResult(RESULT_CANCELED); setResult(RESULT_CANCELED);
finish(); finish();
}
} }
} };
};
mExportHelper.deleteKey(mDataUri, Id.type.public_key, returnHandler); mExportHelper.deleteKey(mDataUri, Id.type.public_key, returnHandler);
return true; return true;
} }
} }
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
private void loadData(Uri dataUri) { private void loadData(Intent intent) {
if (intent.getData().equals(mDataUri)) {
Log.d(Constants.TAG, "Same URI, no need to load the data again!");
return;
}
mDataUri = intent.getData();
if (mDataUri == null) {
Log.e(Constants.TAG, "Intent data missing. Should be Uri of key!");
finish();
return;
}
Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString());
mActionEncrypt.setOnClickListener(new OnClickListener() { mActionEncrypt.setOnClickListener(new OnClickListener() {
@Override @Override
@@ -198,7 +204,7 @@ public class ViewKeyActivity extends SherlockFragmentActivity implements
ViewKeyActivity.this, mDataUri); ViewKeyActivity.this, mDataUri);
PGPPublicKey publicKey = ring.getPublicKey(); PGPPublicKey publicKey = ring.getPublicKey();
long[] encryptionKeyIds = new long[] { publicKey.getKeyID() }; long[] encryptionKeyIds = new long[]{publicKey.getKeyID()};
Intent intent = new Intent(ViewKeyActivity.this, EncryptActivity.class); Intent intent = new Intent(ViewKeyActivity.this, EncryptActivity.class);
intent.setAction(EncryptActivity.ACTION_ENCRYPT); intent.setAction(EncryptActivity.ACTION_ENCRYPT);
intent.putExtra(EncryptActivity.EXTRA_ENCRYPTION_KEY_IDS, encryptionKeyIds); intent.putExtra(EncryptActivity.EXTRA_ENCRYPTION_KEY_IDS, encryptionKeyIds);
@@ -229,21 +235,21 @@ public class ViewKeyActivity extends SherlockFragmentActivity implements
getSupportLoaderManager().initLoader(LOADER_ID_KEYS, null, this); getSupportLoaderManager().initLoader(LOADER_ID_KEYS, null, this);
} }
static final String[] KEYRING_PROJECTION = new String[] { KeyRings._ID, KeyRings.MASTER_KEY_ID, static final String[] KEYRING_PROJECTION = new String[]{KeyRings._ID, KeyRings.MASTER_KEY_ID,
UserIds.USER_ID }; UserIds.USER_ID};
static final int KEYRING_INDEX_ID = 0; static final int KEYRING_INDEX_ID = 0;
static final int KEYRING_INDEX_MASTER_KEY_ID = 1; static final int KEYRING_INDEX_MASTER_KEY_ID = 1;
static final int KEYRING_INDEX_USER_ID = 2; static final int KEYRING_INDEX_USER_ID = 2;
static final String[] USER_IDS_PROJECTION = new String[] { UserIds._ID, UserIds.USER_ID, static final String[] USER_IDS_PROJECTION = new String[]{UserIds._ID, UserIds.USER_ID,
UserIds.RANK, }; UserIds.RANK,};
// not the main user id // not the main user id
static final String USER_IDS_SELECTION = UserIds.RANK + " > 0 "; static final String USER_IDS_SELECTION = UserIds.RANK + " > 0 ";
static final String USER_IDS_SORT_ORDER = UserIds.USER_ID + " COLLATE LOCALIZED ASC"; static final String USER_IDS_SORT_ORDER = UserIds.USER_ID + " COLLATE LOCALIZED ASC";
static final String[] KEYS_PROJECTION = new String[] { Keys._ID, Keys.KEY_ID, static final String[] KEYS_PROJECTION = new String[]{Keys._ID, Keys.KEY_ID,
Keys.IS_MASTER_KEY, Keys.ALGORITHM, Keys.KEY_SIZE, Keys.CAN_CERTIFY, Keys.CAN_SIGN, Keys.IS_MASTER_KEY, Keys.ALGORITHM, Keys.KEY_SIZE, Keys.CAN_CERTIFY, Keys.CAN_SIGN,
Keys.CAN_ENCRYPT, Keys.CREATION, Keys.EXPIRY }; Keys.CAN_ENCRYPT, Keys.CREATION, Keys.EXPIRY};
static final String KEYS_SORT_ORDER = Keys.RANK + " ASC"; static final String KEYS_SORT_ORDER = Keys.RANK + " ASC";
static final int KEYS_INDEX_ID = 0; static final int KEYS_INDEX_ID = 0;
static final int KEYS_INDEX_KEY_ID = 1; static final int KEYS_INDEX_KEY_ID = 1;
@@ -258,31 +264,31 @@ public class ViewKeyActivity extends SherlockFragmentActivity implements
public Loader<Cursor> onCreateLoader(int id, Bundle args) { public Loader<Cursor> onCreateLoader(int id, Bundle args) {
switch (id) { switch (id) {
case LOADER_ID_KEYRING: { case LOADER_ID_KEYRING: {
Uri baseUri = mDataUri; Uri baseUri = mDataUri;
// Now create and return a CursorLoader that will take care of // Now create and return a CursorLoader that will take care of
// creating a Cursor for the data being displayed. // creating a Cursor for the data being displayed.
return new CursorLoader(this, baseUri, KEYRING_PROJECTION, null, null, null); return new CursorLoader(this, baseUri, KEYRING_PROJECTION, null, null, null);
} }
case LOADER_ID_USER_IDS: { case LOADER_ID_USER_IDS: {
Uri baseUri = UserIds.buildUserIdsUri(mDataUri); Uri baseUri = UserIds.buildUserIdsUri(mDataUri);
// Now create and return a CursorLoader that will take care of // Now create and return a CursorLoader that will take care of
// creating a Cursor for the data being displayed. // creating a Cursor for the data being displayed.
return new CursorLoader(this, baseUri, USER_IDS_PROJECTION, USER_IDS_SELECTION, null, return new CursorLoader(this, baseUri, USER_IDS_PROJECTION, USER_IDS_SELECTION, null,
USER_IDS_SORT_ORDER); USER_IDS_SORT_ORDER);
} }
case LOADER_ID_KEYS: { case LOADER_ID_KEYS: {
Uri baseUri = Keys.buildKeysUri(mDataUri); Uri baseUri = Keys.buildKeysUri(mDataUri);
// Now create and return a CursorLoader that will take care of // Now create and return a CursorLoader that will take care of
// creating a Cursor for the data being displayed. // creating a Cursor for the data being displayed.
return new CursorLoader(this, baseUri, KEYS_PROJECTION, null, null, KEYS_SORT_ORDER); return new CursorLoader(this, baseUri, KEYS_PROJECTION, null, null, KEYS_SORT_ORDER);
} }
default: default:
return null; return null;
} }
} }
@@ -290,69 +296,68 @@ public class ViewKeyActivity extends SherlockFragmentActivity implements
// Swap the new cursor in. (The framework will take care of closing the // Swap the new cursor in. (The framework will take care of closing the
// old cursor once we return.) // old cursor once we return.)
switch (loader.getId()) { switch (loader.getId()) {
case LOADER_ID_KEYRING: case LOADER_ID_KEYRING:
if (data.moveToFirst()) { if (data.moveToFirst()) {
// get name, email, and comment from USER_ID // get name, email, and comment from USER_ID
String[] mainUserId = PgpKeyHelper.splitUserId(data String[] mainUserId = PgpKeyHelper.splitUserId(data
.getString(KEYRING_INDEX_USER_ID)); .getString(KEYRING_INDEX_USER_ID));
setTitle(mainUserId[0]); setTitle(mainUserId[0]);
mName.setText(mainUserId[0]); mName.setText(mainUserId[0]);
mEmail.setText(mainUserId[1]); mEmail.setText(mainUserId[1]);
mComment.setText(mainUserId[2]); mComment.setText(mainUserId[2]);
}
break;
case LOADER_ID_USER_IDS:
mUserIdsAdapter.swapCursor(data);
break;
case LOADER_ID_KEYS:
// the first key here is our master key
if (data.moveToFirst()) {
// get key id from MASTER_KEY_ID
long keyId = data.getLong(KEYS_INDEX_KEY_ID);
String keyIdStr = "0x" + PgpKeyHelper.convertKeyIdToHex(keyId);
mKeyId.setText(keyIdStr);
// get creation date from CREATION
if (data.isNull(KEYS_INDEX_CREATION)) {
mCreation.setText(R.string.none);
} else {
Date creationDate = new Date(data.getLong(KEYS_INDEX_CREATION) * 1000);
mCreation.setText(DateFormat.getDateFormat(getApplicationContext()).format(
creationDate));
} }
// get creation date from EXPIRY break;
if (data.isNull(KEYS_INDEX_EXPIRY)) { case LOADER_ID_USER_IDS:
mExpiry.setText(R.string.none); mUserIdsAdapter.swapCursor(data);
} else { break;
Date expiryDate = new Date(data.getLong(KEYS_INDEX_EXPIRY) * 1000); case LOADER_ID_KEYS:
// the first key here is our master key
if (data.moveToFirst()) {
// get key id from MASTER_KEY_ID
long keyId = data.getLong(KEYS_INDEX_KEY_ID);
mExpiry.setText(DateFormat.getDateFormat(getApplicationContext()).format( String keyIdStr = "0x" + PgpKeyHelper.convertKeyIdToHex(keyId);
expiryDate)); mKeyId.setText(keyIdStr);
// get creation date from CREATION
if (data.isNull(KEYS_INDEX_CREATION)) {
mCreation.setText(R.string.none);
} else {
Date creationDate = new Date(data.getLong(KEYS_INDEX_CREATION) * 1000);
mCreation.setText(DateFormat.getDateFormat(getApplicationContext()).format(
creationDate));
}
// get creation date from EXPIRY
if (data.isNull(KEYS_INDEX_EXPIRY)) {
mExpiry.setText(R.string.none);
} else {
Date expiryDate = new Date(data.getLong(KEYS_INDEX_EXPIRY) * 1000);
mExpiry.setText(DateFormat.getDateFormat(getApplicationContext()).format(
expiryDate));
}
String algorithmStr = PgpKeyHelper.getAlgorithmInfo(
data.getInt(KEYS_INDEX_ALGORITHM), data.getInt(KEYS_INDEX_KEY_SIZE));
mAlgorithm.setText(algorithmStr);
// TODO: Can this be done better? fingerprint in db?
String fingerprint = PgpKeyHelper.getFingerPrint(this, keyId);
fingerprint = fingerprint.replace(" ", "\n");
mFingerprint.setText(fingerprint);
// TODO: get image with getUserAttributes() on key and then
// PGPUserAttributeSubpacketVector
} }
String algorithmStr = PgpKeyHelper.getAlgorithmInfo( mKeysAdapter.swapCursor(data);
data.getInt(KEYS_INDEX_ALGORITHM), data.getInt(KEYS_INDEX_KEY_SIZE)); break;
mAlgorithm.setText(algorithmStr);
// TODO: Can this be done better? fingerprint in db? default:
String fingerprint = PgpKeyHelper.getFingerPrint(this, keyId); break;
fingerprint = fingerprint.replace(" ", "\n");
mFingerprint.setText(fingerprint);
// TODO: get image with getUserAttributes() on key and then
// PGPUserAttributeSubpacketVector
}
mKeysAdapter.swapCursor(data);
break;
default:
break;
} }
} }
@@ -362,17 +367,17 @@ public class ViewKeyActivity extends SherlockFragmentActivity implements
*/ */
public void onLoaderReset(Loader<Cursor> loader) { public void onLoaderReset(Loader<Cursor> loader) {
switch (loader.getId()) { switch (loader.getId()) {
case LOADER_ID_KEYRING: case LOADER_ID_KEYRING:
// TODO? // TODO?
break; break;
case LOADER_ID_USER_IDS: case LOADER_ID_USER_IDS:
mUserIdsAdapter.swapCursor(null); mUserIdsAdapter.swapCursor(null);
break; break;
case LOADER_ID_KEYS: case LOADER_ID_KEYS:
mKeysAdapter.swapCursor(null); mKeysAdapter.swapCursor(null);
break; break;
default: default:
break; break;
} }
} }
@@ -438,7 +443,7 @@ public class ViewKeyActivity extends SherlockFragmentActivity implements
// get public keyring as ascii armored string // get public keyring as ascii armored string
long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri); long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri);
ArrayList<String> keyringArmored = ProviderHelper.getKeyRingsAsArmoredString(this, ArrayList<String> keyringArmored = ProviderHelper.getKeyRingsAsArmoredString(this,
dataUri, new long[] { masterKeyId }); dataUri, new long[]{masterKeyId});
content = keyringArmored.get(0); content = keyringArmored.get(0);
@@ -469,7 +474,7 @@ public class ViewKeyActivity extends SherlockFragmentActivity implements
// get public keyring as ascii armored string // get public keyring as ascii armored string
long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri); long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri);
ArrayList<String> keyringArmored = ProviderHelper.getKeyRingsAsArmoredString(this, dataUri, ArrayList<String> keyringArmored = ProviderHelper.getKeyRingsAsArmoredString(this, dataUri,
new long[] { masterKeyId }); new long[]{masterKeyId});
ClipboardReflection.copyToClipboard(this, keyringArmored.get(0)); ClipboardReflection.copyToClipboard(this, keyringArmored.get(0));
Toast.makeText(getApplicationContext(), R.string.key_copied_to_clipboard, Toast.LENGTH_LONG) Toast.makeText(getApplicationContext(), R.string.key_copied_to_clipboard, Toast.LENGTH_LONG)