From dcf268bcb2cbe433fdef8af4fd516a6482ac268a Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 20 Aug 2014 23:08:52 +0200 Subject: [PATCH] move key deletion into KeychainIntentHandler --- .../service/KeychainIntentService.java | 50 ++++++++++- .../keychain/ui/ViewKeyActivity.java | 8 +- .../ui/dialog/DeleteKeyDialogFragment.java | 85 +++++++++++-------- OpenKeychain/src/main/res/values/strings.xml | 1 + 4 files changed, 104 insertions(+), 40 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index d568df91a..4330a1c01 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -49,6 +49,7 @@ import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralMsgIdException; +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; @@ -104,6 +105,8 @@ public class KeychainIntentService extends IntentService public static final String ACTION_CERTIFY_KEYRING = Constants.INTENT_PREFIX + "SIGN_KEYRING"; + public static final String ACTION_DELETE = Constants.INTENT_PREFIX + "DELETE"; + public static final String ACTION_CONSOLIDATE = Constants.INTENT_PREFIX + "CONSOLIDATE"; /* keys for data bundle */ @@ -143,6 +146,10 @@ public class KeychainIntentService extends IntentService // delete file securely public static final String DELETE_FILE = "deleteFile"; + // delete keyring(s) + public static final String DELETE_KEY_LIST = "delete_list"; + public static final String DELETE_IS_SECRET = "delete_is_secret"; + // import key public static final String IMPORT_KEY_LIST = "import_key_list"; public static final String IMPORT_KEY_FILE = "import_key_file"; @@ -487,9 +494,14 @@ public class KeychainIntentService extends IntentService entries = cache.readCacheIntoList(); } - PgpImportExport pgpImportExport = new PgpImportExport(this, this); + ProviderHelper providerHelper = new ProviderHelper(this); + PgpImportExport pgpImportExport = new PgpImportExport(this, providerHelper, this); ImportKeyResult result = pgpImportExport.importKeyRings(entries); + if (result.mSecret > 0) { + providerHelper.consolidateDatabaseStep1(this); + } + sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, result); } catch (Exception e) { sendErrorToHandler(e); @@ -666,6 +678,42 @@ public class KeychainIntentService extends IntentService sendErrorToHandler(e); } + } else if (ACTION_DELETE.equals(action)) { + + try { + + long[] masterKeyIds = data.getLongArray(DELETE_KEY_LIST); + boolean isSecret = data.getBoolean(DELETE_IS_SECRET); + + if (masterKeyIds.length == 0) { + throw new PgpGeneralException("List of keys to delete is empty"); + } + + if (isSecret && masterKeyIds.length > 1) { + throw new PgpGeneralException("Secret keys can only be deleted individually!"); + } + + boolean success = false; + for (long masterKeyId : masterKeyIds) { + int count = getContentResolver().delete( + KeyRingData.buildPublicKeyRingUri(masterKeyId), null, null + ); + success |= count > 0; + } + + if (isSecret && success) { + ConsolidateResult result = + new ProviderHelper(this).consolidateDatabaseStep1(this); + } + + if (success) { + sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY); + } + + } catch (Exception e) { + sendErrorToHandler(e); + } + } else if (ACTION_CONSOLIDATE.equals(action)) { ConsolidateResult result; if (data.containsKey(CONSOLIDATE_RECOVERY) && data.getBoolean(CONSOLIDATE_RECOVERY)) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index c9db79740..2c0881ea4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -54,6 +54,8 @@ import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.service.KeychainIntentService; +import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; import org.sufficientlysecure.keychain.service.OperationResultParcel; import org.sufficientlysecure.keychain.ui.adapter.PagerTabStripAdapter; import org.sufficientlysecure.keychain.ui.widget.SlidingTabLayout; @@ -303,8 +305,10 @@ public class ViewKeyActivity extends ActionBarActivity implements Handler returnHandler = new Handler() { @Override public void handleMessage(Message message) { - setResult(RESULT_CANCELED); - finish(); + if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { + setResult(RESULT_CANCELED); + finish(); + } } }; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java index 4927a4d24..d0c9cea5b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java @@ -18,7 +18,9 @@ package org.sufficientlysecure.keychain.ui.dialog; import android.app.Dialog; +import android.app.ProgressDialog; import android.content.DialogInterface; +import android.content.Intent; import android.os.Bundle; import android.os.Message; import android.os.Messenger; @@ -31,9 +33,10 @@ import android.widget.TextView; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.service.KeychainIntentService; +import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; import org.sufficientlysecure.keychain.util.Log; import java.util.HashMap; @@ -48,8 +51,6 @@ public class DeleteKeyDialogFragment extends DialogFragment { private TextView mMainMessage; private View mInflateView; - private Messenger mMessenger; - /** * Creates new instance of this delete file dialog fragment */ @@ -68,7 +69,7 @@ public class DeleteKeyDialogFragment extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { final FragmentActivity activity = getActivity(); - mMessenger = getArguments().getParcelable(ARG_MESSENGER); + final Messenger messenger = getArguments().getParcelable(ARG_MESSENGER); final long[] masterKeyIds = getArguments().getLongArray(ARG_DELETE_MASTER_KEY_IDS); @@ -83,6 +84,8 @@ public class DeleteKeyDialogFragment extends DialogFragment { builder.setTitle(R.string.warning); + final boolean hasSecret; + // If only a single key has been selected if (masterKeyIds.length == 1) { long masterKeyId = masterKeyIds[0]; @@ -98,7 +101,7 @@ public class DeleteKeyDialogFragment extends DialogFragment { } ); String userId = (String) data.get(KeyRings.USER_ID); - boolean hasSecret = ((Long) data.get(KeyRings.HAS_ANY_SECRET)) == 1; + hasSecret = ((Long) data.get(KeyRings.HAS_ANY_SECRET)) == 1; // Set message depending on which key it is. mMainMessage.setText(getString( @@ -107,12 +110,12 @@ public class DeleteKeyDialogFragment extends DialogFragment { userId )); } catch (ProviderHelper.NotFoundException e) { - sendMessageToHandler(MESSAGE_ERROR, null); dismiss(); return null; } } else { mMainMessage.setText(R.string.key_deletion_confirmation_multi); + hasSecret = false; } builder.setIcon(R.drawable.ic_dialog_alert_holo_light); @@ -120,18 +123,45 @@ public class DeleteKeyDialogFragment extends DialogFragment { @Override public void onClick(DialogInterface dialog, int which) { - boolean success = false; - for (long masterKeyId : masterKeyIds) { - int count = activity.getContentResolver().delete( - KeyRingData.buildPublicKeyRingUri(masterKeyId), null, null - ); - success = count > 0; - } - if (success) { - sendMessageToHandler(MESSAGE_OKAY, null); - } else { - sendMessageToHandler(MESSAGE_ERROR, null); - } + // Send all information needed to service to import key in other thread + Intent intent = new Intent(getActivity(), KeychainIntentService.class); + + intent.setAction(KeychainIntentService.ACTION_DELETE); + + // Message is received after importing is done in KeychainIntentService + KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler( + getActivity(), + getString(R.string.progress_deleting), + ProgressDialog.STYLE_HORIZONTAL) { + public void handleMessage(Message message) { + // handle messages by standard KeychainIntentServiceHandler first + super.handleMessage(message); + try { + Message msg = Message.obtain(); + msg.copyFrom(message); + messenger.send(msg); + } catch (RemoteException e) { + Log.e(Constants.TAG, "messenger error", e); + } + } + }; + + // fill values for this action + Bundle data = new Bundle(); + data.putLongArray(KeychainIntentService.DELETE_KEY_LIST, masterKeyIds); + data.putBoolean(KeychainIntentService.DELETE_IS_SECRET, hasSecret); + intent.putExtra(KeychainIntentService.EXTRA_DATA, data); + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(saveHandler); + intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); + + // show progress dialog + saveHandler.showProgressDialog(getActivity()); + + // start service with intent + getActivity().startService(intent); + dismiss(); } }); @@ -146,23 +176,4 @@ public class DeleteKeyDialogFragment extends DialogFragment { return builder.show(); } - /** - * Send message back to handler which is initialized in a activity - * - * @param what Message integer you want to send - */ - private void sendMessageToHandler(Integer what, Bundle data) { - Message msg = Message.obtain(); - msg.what = what; - if (data != null) { - msg.setData(data); - } - try { - mMessenger.send(msg); - } catch (RemoteException e) { - Log.w(Constants.TAG, "Exception sending message, Is handler present?", e); - } catch (NullPointerException e) { - Log.w(Constants.TAG, "Messenger is null!", e); - } - } } diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index c4697cac3..fede86b1c 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -301,6 +301,7 @@ decompressing data… verifying integrity… deleting \'%s\' securely… + deleting keys… consolidate: saving to cache… consolidate: reimporting…