From dedcfd8a7243a8ff5740ad706bc749d57ee8b5e8 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Thu, 3 Apr 2014 17:09:26 +0200 Subject: [PATCH] more work on streamlining uris, and stripping ProviderHelper --- .../keychain/provider/KeychainProvider.java | 5 + .../keychain/provider/ProviderHelper.java | 134 +++++++----------- .../remote/ui/AccountSettingsFragment.java | 6 +- .../ui/EncryptAsymmetricFragment.java | 23 ++- .../keychain/ui/KeyListFragment.java | 27 +--- .../keychain/ui/ViewKeyActivity.java | 13 +- .../keychain/ui/ViewKeyActivityJB.java | 19 ++- .../keychain/ui/ViewKeyMainFragment.java | 4 - .../ui/dialog/DeleteKeyDialogFragment.java | 121 +++++----------- .../ui/dialog/ShareQrCodeDialogFragment.java | 15 +- 10 files changed, 146 insertions(+), 221 deletions(-) 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 39ea083fa..a4fd1130d 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 @@ -256,6 +256,9 @@ public class KeychainProvider extends ContentProvider { + Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC"; } + // uri to watch is all /key_rings/ + uri = KeyRings.CONTENT_URI; + break; } /*case SECRET_KEY_RING_BY_EMAILS: @@ -503,6 +506,7 @@ public class KeychainProvider extends ContentProvider { } // corresponding keys and userIds are deleted by ON DELETE CASCADE count = db.delete(Tables.KEY_RINGS_PUBLIC, selection, selectionArgs); + uri = KeyRings.buildGenericKeyRingUri(uri.getPathSegments().get(1)); break; } case KEY_RING_SECRET: { @@ -512,6 +516,7 @@ public class KeychainProvider extends ContentProvider { selection += " AND (" + additionalSelection + ")"; } count = db.delete(Tables.KEY_RINGS_SECRET, selection, selectionArgs); + uri = KeyRings.buildGenericKeyRingUri(uri.getPathSegments().get(1)); break; } 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 3a0d910c5..18eaa375a 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 @@ -23,7 +23,10 @@ import android.content.ContentValues; import android.content.Context; import android.content.OperationApplicationException; import android.database.Cursor; +import android.database.CursorWindow; +import android.database.CursorWrapper; import android.database.DatabaseUtils; +import android.database.sqlite.SQLiteCursor; import android.net.Uri; import android.os.RemoteException; @@ -42,7 +45,6 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; 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.remote.AccountSettings; import org.sufficientlysecure.keychain.remote.AppSettings; import org.sufficientlysecure.keychain.util.IterableIterator; @@ -52,6 +54,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Date; +import java.util.HashMap; import java.util.HashSet; import java.util.Set; @@ -81,6 +84,57 @@ public class ProviderHelper { return keyRing; } + public static Object getUnifiedData(Context context, long masterKeyId, String column) { + return getUnifiedData(context, masterKeyId, new String[] { column }).get(column); + } + public static Object getUnifiedData(Context context, Uri uri, String column) { + return getUnifiedData(context, uri, new String[] { column }).get(column); + } + + public static HashMap getUnifiedData(Context context, long masterKeyId, String[] proj) { + return getUnifiedData(context, KeyRings.buildGenericKeyRingUri(Long.toString(masterKeyId)), proj); + } + + public static HashMap getUnifiedData(Context context, Uri uri, String[] proj) { + uri = KeyRings.buildUnifiedKeyRingUri(uri); + + Cursor cursor = context.getContentResolver().query(uri, proj, null, null, null); + + HashMap result = new HashMap(proj.length); + if (cursor != null && cursor.moveToFirst()) { + // this is a HACK because we don't have Cursor.getType (which is api level 11) + CursorWindow cursorWindow; + if(cursor instanceof CursorWrapper) { + cursorWindow = ((SQLiteCursor) ((CursorWrapper) cursor).getWrappedCursor()).getWindow(); + } else { + cursorWindow = ((SQLiteCursor) cursor).getWindow(); + } + + int pos = 0; + for(String p : proj) { + if (cursorWindow.isNull(0, pos)) { + result.put(p, cursor.isNull(pos)); + } else if (cursorWindow.isLong(0, pos)) { + result.put(p, cursor.getLong(pos)); + } else if (cursorWindow.isFloat(0, pos)) { + result.put(p, cursor.getFloat(pos)); + } else if (cursorWindow.isString(0, pos)) { + result.put(p, cursor.getString(pos)); + } else if (cursorWindow.isBlob(0, pos)) { + result.put(p, cursor.getBlob(pos)); + } + pos += 1; + } + } + + if (cursor != null) { + cursor.close(); + } + + return result; + } + + public static PGPPublicKey getPGPPublicKeyByKeyId(Context context, long keyId) { return getPGPPublicKeyRingWithKeyId(context, keyId).getPublicKey(keyId); } @@ -307,84 +361,6 @@ 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 - */ - public static byte[] getFingerprint(Context context, Uri queryUri) { - String[] projection = new String[]{Keys.FINGERPRINT}; - Cursor cursor = context.getContentResolver().query(queryUri, projection, null, null, null); - - byte[] fingerprint = null; - try { - if (cursor != null && cursor.moveToFirst()) { - int col = cursor.getColumnIndexOrThrow(Keys.FINGERPRINT); - - fingerprint = cursor.getBlob(col); - } - } finally { - if (cursor != null) { - cursor.close(); - } - } - - // FALLBACK: If fingerprint is not in database, get it from key blob! - // this could happen if the key was saved by a previous version of Keychain! - if (fingerprint == null) { - Log.d(Constants.TAG, "FALLBACK: fingerprint is not in database, get it from key blob!"); - - // get master key id - projection = new String[]{KeyRings.MASTER_KEY_ID}; - cursor = context.getContentResolver().query(queryUri, projection, null, null, null); - long masterKeyId = 0; - try { - if (cursor != null && cursor.moveToFirst()) { - int col = cursor.getColumnIndexOrThrow(KeyRings.MASTER_KEY_ID); - - masterKeyId = cursor.getLong(col); - } - } finally { - if (cursor != null) { - cursor.close(); - } - } - - PGPPublicKey key = ProviderHelper.getPGPPublicKeyRing(context, masterKeyId).getPublicKey(); - // if it is no public key get it from your own keys... - if (key == null) { - PGPSecretKey secretKey = ProviderHelper.getPGPSecretKeyRing(context, masterKeyId).getSecretKey(); - if (secretKey == null) { - Log.e(Constants.TAG, "Key could not be found!"); - return null; - } - key = secretKey.getPublicKey(); - } - - fingerprint = key.getFingerprint(); - } - - return fingerprint; - } - public static ArrayList getKeyRingsAsArmoredString(Context context, Uri uri, long[] masterKeyIds) { ArrayList output = new ArrayList(); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java index dee0dae95..992aa7c95 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java @@ -34,6 +34,7 @@ import com.beardedhen.androidbootstrap.BootstrapButton; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.remote.AccountSettings; import org.sufficientlysecure.keychain.ui.EditKeyActivity; import org.sufficientlysecure.keychain.ui.SelectSecretKeyLayoutFragment; @@ -176,9 +177,8 @@ public class AccountSettingsFragment extends Fragment implements case REQUEST_CODE_CREATE_KEY: { if (resultCode == Activity.RESULT_OK) { // select newly created key - Uri newKeyUri = data.getData(); - // TODO helper method for this? - mSelectKeyFragment.selectKey(Long.parseLong(newKeyUri.getPathSegments().get(1))); + long masterKeyId = ProviderHelper.getMasterKeyId(getActivity(), data.getData()); + mSelectKeyFragment.selectKey(masterKeyId); } break; } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java index a8de40c70..0b724d52c 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java @@ -37,8 +37,10 @@ import org.spongycastle.openpgp.PGPSecretKeyRing; import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; +import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.ProviderHelper; +import java.util.HashMap; import java.util.Vector; public class EncryptAsymmetricFragment extends Fragment { @@ -202,20 +204,17 @@ public class EncryptAsymmetricFragment extends Fragment { } else { String uid = getResources().getString(R.string.user_id_no_name); String uidExtra = ""; - // TODO: don't use bouncy castle objects! - PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingWithKeyId(getActivity(), - mSecretKeyId); - if (keyRing != null) { - PGPSecretKey key = PgpKeyHelper.getMasterKey(keyRing); - if (key != null) { - String userId = PgpKeyHelper.getMainUserIdSafe(getActivity(), key); - String chunks[] = userId.split(" <", 2); - uid = chunks[0]; - if (chunks.length > 1) { - uidExtra = "<" + chunks[1]; - } + // See if we can get a user_id from a unified query + Object data = ProviderHelper.getUnifiedData( + getActivity(), mSecretKeyId, KeychainContract.UserIds.USER_ID); + if(data instanceof String) { + String chunks[] = ((String) data).split(" <", 2); + uid = chunks[0]; + if (chunks.length > 1) { + uidExtra = "<" + chunks[1]; } } + mMainUserId.setText(uid); mMainUserIdRest.setText(uidExtra); mSign.setChecked(true); 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 6dec5e56e..cc0abe48a 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 @@ -193,28 +193,15 @@ public class KeyListFragment extends Fragment break; } case R.id.menu_key_list_multi_delete: { - ids = mStickyList.getWrappedList().getCheckedItemIds(); + ids = mAdapter.getCurrentSelectedMasterKeyIds(); showDeleteKeyDialog(mode, ids); break; } case R.id.menu_key_list_multi_export: { - ids = mStickyList.getWrappedList().getCheckedItemIds(); - long[] masterKeyIds = new long[2*ids.length]; - /* TODO! redo - ArrayList allPubRowIds = - ProviderHelper.getPublicKeyRingsRowIds(getActivity()); - for (int i = 0; i < ids.length; i++) { - if (allPubRowIds.contains(ids[i])) { - masterKeyIds[i] = - ProviderHelper.getPublicMasterKeyId(getActivity(), ids[i]); - } else { - masterKeyIds[i] = - ProviderHelper.getSecretMasterKeyId(getActivity(), ids[i]); - } - }*/ + ids = mAdapter.getCurrentSelectedMasterKeyIds(); ExportHelper mExportHelper = new ExportHelper((ActionBarActivity) getActivity()); mExportHelper - .showExportKeysDialog(masterKeyIds, Id.type.public_key, + .showExportKeysDialog(ids, Id.type.public_key, Constants.Path.APP_DIR_FILE_PUB, getString(R.string.also_export_secret_keys)); break; @@ -343,7 +330,7 @@ public class KeyListFragment extends Fragment } viewIntent.setData( KeychainContract - .KeyRings.buildPublicKeyRingUri( + .KeyRings.buildGenericKeyRingUri( Long.toString(mAdapter.getMasterKeyId(position)))); startActivity(viewIntent); } @@ -362,11 +349,11 @@ public class KeyListFragment extends Fragment /** * Show dialog to delete key * - * @param keyRingRowIds + * @param masterKeyIds */ @TargetApi(11) // TODO: this method needs an overhaul to handle both public and secret keys gracefully! - public void showDeleteKeyDialog(final ActionMode mode, long[] keyRingRowIds) { + public void showDeleteKeyDialog(final ActionMode mode, long[] masterKeyIds) { // Message is received after key is deleted Handler returnHandler = new Handler() { @Override @@ -381,7 +368,7 @@ public class KeyListFragment extends Fragment Messenger messenger = new Messenger(returnHandler); DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(messenger, - keyRingRowIds); + masterKeyIds); deleteKeyDialog.show(getActivity().getSupportFragmentManager(), "deleteKeyDialog"); } 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 54fd04b10..2437270e5 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 @@ -173,10 +173,15 @@ public class ViewKeyActivity extends ActionBarActivity { private void shareKey(Uri dataUri, boolean fingerprintOnly) { String content; if (fingerprintOnly) { - byte[] fingerprintBlob = ProviderHelper.getFingerprint(this, dataUri); - String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob); - - content = Constants.FINGERPRINT_SCHEME + ":" + fingerprint; + Object blob = ProviderHelper.getUnifiedData(this, dataUri, KeychainContract.Keys.FINGERPRINT); + if(blob instanceof byte[]) { + String fingerprint = PgpKeyHelper.convertFingerprintToHex((byte[]) blob); + content = Constants.FINGERPRINT_SCHEME + ":" + fingerprint; + } else { + Toast.makeText(getApplicationContext(), "Bad key selected!", + Toast.LENGTH_LONG).show(); + return; + } } else { // get public keyring as ascii armored string long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivityJB.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivityJB.java index 997ff9c7a..9bbbb6c7b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivityJB.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivityJB.java @@ -34,6 +34,9 @@ import android.widget.Toast; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.util.Log; + +import java.io.IOException; @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public class ViewKeyActivityJB extends ViewKeyActivity implements CreateNdefMessageCallback, @@ -64,13 +67,17 @@ public class ViewKeyActivityJB extends ViewKeyActivity implements CreateNdefMess // get public keyring as byte array long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri); - mSharedKeyringBytes = ProviderHelper.getKeyRingsAsByteArray(this, dataUri, - new long[]{masterKeyId}); + try { + mSharedKeyringBytes = ProviderHelper.getPGPPublicKeyRing(this, masterKeyId).getEncoded(); - // Register callback to set NDEF message - mNfcAdapter.setNdefPushMessageCallback(this, this); - // Register callback to listen for message-sent success - mNfcAdapter.setOnNdefPushCompleteCallback(this, this); + // Register callback to set NDEF message + mNfcAdapter.setNdefPushMessageCallback(this, this); + // Register callback to listen for message-sent success + mNfcAdapter.setOnNdefPushCompleteCallback(this, this); + } catch(IOException e) { + // not much trouble, but leave a note + Log.e(Constants.TAG, "Error parsing keyring: ", e); + } } } } 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 703f7e861..75853ac2a 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 @@ -298,10 +298,6 @@ public class ViewKeyMainFragment extends Fragment implements mAlgorithm.setText(algorithmStr); byte[] fingerprintBlob = data.getBlob(KEYS_INDEX_FINGERPRINT); - if (fingerprintBlob == null) { - // FALLBACK for old database entries - fingerprintBlob = ProviderHelper.getFingerprint(getActivity(), mDataUri); - } String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob); mFingerprint.setText(PgpKeyHelper.colorizeFingerprint(fingerprint)); 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 9427ce0db..57dbb7794 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 @@ -43,10 +43,11 @@ 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 { private static final String ARG_MESSENGER = "messenger"; - private static final String ARG_DELETE_KEY_RING_ROW_IDS = "delete_key_ring_row_ids"; + private static final String ARG_DELETE_MASTER_KEY_IDS = "delete_master_key_ids"; public static final int MESSAGE_OKAY = 1; public static final int MESSAGE_ERROR = 0; @@ -63,13 +64,13 @@ public class DeleteKeyDialogFragment extends DialogFragment { /** * Creates new instance of this delete file dialog fragment */ - public static DeleteKeyDialogFragment newInstance(Messenger messenger, long[] keyRingRowIds - ) { + public static DeleteKeyDialogFragment newInstance(Messenger messenger, + long[] masterKeyIds) { DeleteKeyDialogFragment frag = new DeleteKeyDialogFragment(); Bundle args = new Bundle(); args.putParcelable(ARG_MESSENGER, messenger); - args.putLongArray(ARG_DELETE_KEY_RING_ROW_IDS, keyRingRowIds); + args.putLongArray(ARG_DELETE_MASTER_KEY_IDS, masterKeyIds); //We don't need the key type frag.setArguments(args); @@ -84,7 +85,7 @@ public class DeleteKeyDialogFragment extends DialogFragment { final FragmentActivity activity = getActivity(); mMessenger = getArguments().getParcelable(ARG_MESSENGER); - final long[] keyRingRowIds = getArguments().getLongArray(ARG_DELETE_KEY_RING_ROW_IDS); + final long[] masterKeyIds = getArguments().getLongArray(ARG_DELETE_MASTER_KEY_IDS); AlertDialog.Builder builder = new AlertDialog.Builder(activity); @@ -98,35 +99,29 @@ public class DeleteKeyDialogFragment extends DialogFragment { mCheckDeleteSecret = (CheckBox) mInflateView.findViewById(R.id.checkDeleteSecret); builder.setTitle(R.string.warning); - /* TODO! redo - //If only a single key has been selected - if (keyRingRowIds.length == 1) { - Uri dataUri; - ArrayList publicKeyRings; //Any one will do + // If only a single key has been selected + if (masterKeyIds.length == 1) { mIsSingleSelection = true; - long selectedRow = keyRingRowIds[0]; - long keyType; - publicKeyRings = ProviderHelper.getPublicKeyRingsRowIds(activity); + long masterKeyId = masterKeyIds[0]; - if (publicKeyRings.contains(selectedRow)) { - //TODO Should be a better method to do this other than getting all the KeyRings - dataUri = KeychainContract.KeyRings.buildPublicKeyRingsUri(String.valueOf(selectedRow)); - keyType = Id.type.public_key; - } else { - dataUri = KeychainContract.KeyRings.buildSecretKeyRingsUri(String.valueOf(selectedRow)); - keyType = Id.type.secret_key; - } + HashMap data = ProviderHelper.getUnifiedData(activity, masterKeyId, new String[]{ + KeychainContract.UserIds.USER_ID, + KeychainDatabase.Tables.KEY_RINGS_SECRET + "." + KeychainContract.KeyRings.MASTER_KEY_ID + }); + 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 = ProviderHelper.getUserId(activity, dataUri); - // Hide the Checkbox and TextView since this is a single selection, - // user will be notified thru message + // Hide the Checkbox and TextView since this is a single selection,user will be notified through message mDeleteSecretKeyView.setVisibility(View.GONE); // Set message depending on which key it is. - mMainMessage.setText(getString(keyType == Id.type.secret_key ? - R.string.secret_key_deletion_confirmation : - R.string.public_key_deletetion_confirmation, userId)); + mMainMessage.setText(getString( + hasSecret ? R.string.secret_key_deletion_confirmation + : R.string.public_key_deletetion_confirmation, + userId)); } else { mDeleteSecretKeyView.setVisibility(View.VISIBLE); mMainMessage.setText(R.string.key_deletion_confirmation_multi); @@ -137,75 +132,27 @@ public class DeleteKeyDialogFragment extends DialogFragment { builder.setPositiveButton(R.string.btn_delete, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - Uri queryUri = KeychainContract.KeyRings.buildUnifiedKeyRingsUri(); - String[] projection = new String[]{ - KeychainContract.KeyRings.MASTER_KEY_ID, // 0 - KeychainContract.KeyRings.TYPE// 1 - }; - // make selection with all entries where _ID is one of the given row ids - String selection = KeychainDatabase.Tables.KEY_RINGS + "." + - KeychainContract.KeyRings._ID + " IN("; - String selectionIDs = ""; - for (int i = 0; i < keyRingRowIds.length; i++) { - selectionIDs += "'" + String.valueOf(keyRingRowIds[i]) + "'"; - if (i + 1 < keyRingRowIds.length) { - selectionIDs += ","; - } - } - selection += selectionIDs + ")"; - - Cursor cursor = activity.getContentResolver().query(queryUri, projection, - selection, null, null); - - - long masterKeyId; - long keyType; - boolean isSuccessfullyDeleted; - try { - isSuccessfullyDeleted = false; - while (cursor != null && cursor.moveToNext()) { - masterKeyId = cursor.getLong(0); - keyType = cursor.getLong(1); - - Log.d(Constants.TAG, "masterKeyId: " + masterKeyId + - ", keyType:" + - (keyType == KeychainContract.KeyTypes.PUBLIC ? - "Public" : "Private")); - - if (keyType == KeychainContract.KeyTypes.SECRET) { - if (mCheckDeleteSecret.isChecked() || mIsSingleSelection) { - ProviderHelper.deleteUnifiedKeyRing(activity, - String.valueOf(masterKeyId), true); - } - } else { - ProviderHelper.deleteUnifiedKeyRing(activity, - String.valueOf(masterKeyId), false); - } - } - - //Check if the selected rows have actually been deleted - cursor = activity.getContentResolver().query( - queryUri, projection, selection, null, null); - if (cursor == null || cursor.getCount() == 0 || - !mCheckDeleteSecret.isChecked()) { - isSuccessfullyDeleted = true; - } - } finally { - if (cursor != null) { - cursor.close(); - } + boolean success = false; + for(long masterKeyId : masterKeyIds) { + int count = activity.getContentResolver().delete( + KeychainContract.KeyRings.buildPublicKeyRingUri(Long.toString(masterKeyId)), null, null + ); + if(count > 0) + success = true; } dismiss(); - if (isSuccessfullyDeleted) { + if (success) { sendMessageToHandler(MESSAGE_OKAY, null); } else { sendMessageToHandler(MESSAGE_ERROR, null); } } - }); + + } + ); builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { @Override @@ -213,7 +160,7 @@ public class DeleteKeyDialogFragment extends DialogFragment { dismiss(); } }); - */ + return builder.create(); } 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 18403837a..1b81c8b3b 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 @@ -31,6 +31,7 @@ import android.widget.TextView; 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.ProviderHelper; import org.sufficientlysecure.keychain.util.QrCodeUtils; @@ -89,22 +90,24 @@ public class ShareQrCodeDialogFragment extends DialogFragment { if (mFingerprintOnly) { alert.setPositiveButton(R.string.btn_okay, null); - byte[] fingerprintBlob = ProviderHelper.getFingerprint(getActivity(), dataUri); - String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob); + Object blob = ProviderHelper.getUnifiedData(getActivity(), dataUri, KeychainContract.Keys.FINGERPRINT); + if(!(blob instanceof byte[])) { + // TODO error handling?! + return null; + } + String fingerprint = PgpKeyHelper.convertFingerprintToHex((byte[]) blob); mText.setText(getString(R.string.share_qr_code_dialog_fingerprint_text) + " " + fingerprint); - content = Constants.FINGERPRINT_SCHEME + ":" + fingerprint; setQrCode(content); } else { mText.setText(R.string.share_qr_code_dialog_start); - // TODO + // TODO works, but long masterKeyId = ProviderHelper.getMasterKeyId(getActivity(), dataUri); - // get public keyring as ascii armored string ArrayList keyringArmored = ProviderHelper.getKeyRingsAsArmoredString( - getActivity(), dataUri, new long[]{masterKeyId}); + getActivity(), dataUri, new long[] { masterKeyId }); // TODO: binary?