aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui
diff options
context:
space:
mode:
authorAdithya Abraham Philip <adithyaphilip@gmail.com>2015-07-09 22:51:20 +0530
committerAdithya Abraham Philip <adithyaphilip@gmail.com>2015-07-13 23:34:06 +0530
commitfcd27d2600711ccd32c000c6d58da19cb816a9bf (patch)
tree52edb720432bcb168e090e124798650af7c61117 /OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui
parentbfe36019bd368bb434e77be433f6acb409953b93 (diff)
downloadopen-keychain-fcd27d2600711ccd32c000c6d58da19cb816a9bf.tar.gz
open-keychain-fcd27d2600711ccd32c000c6d58da19cb816a9bf.tar.bz2
open-keychain-fcd27d2600711ccd32c000c6d58da19cb816a9bf.zip
implemented revocation on deletion
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DeleteKeyDialogActivity.java231
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java1
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java70
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RevokeDeleteDialogActivity.java258
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java50
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java34
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java211
7 files changed, 570 insertions, 285 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DeleteKeyDialogActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DeleteKeyDialogActivity.java
new file mode 100644
index 000000000..064d34e38
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DeleteKeyDialogActivity.java
@@ -0,0 +1,231 @@
+package org.sufficientlysecure.keychain.ui;
+
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.support.v4.app.DialogFragment;
+import android.support.v4.app.FragmentActivity;
+import android.view.ContextThemeWrapper;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextView;
+
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.operations.results.DeleteResult;
+import org.sufficientlysecure.keychain.operations.results.OperationResult;
+import org.sufficientlysecure.keychain.pgp.KeyRing;
+import org.sufficientlysecure.keychain.provider.KeychainContract;
+import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.service.DeleteKeyringParcel;
+import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
+import org.sufficientlysecure.keychain.ui.dialog.CustomAlertDialogBuilder;
+import org.sufficientlysecure.keychain.util.Log;
+
+import java.util.HashMap;
+
+public class DeleteKeyDialogActivity extends FragmentActivity
+ implements CryptoOperationHelper.Callback<DeleteKeyringParcel, DeleteResult> {
+ public static final String EXTRA_DELETE_MASTER_KEY_IDS = "extra_delete_master_key_ids";
+
+ private CryptoOperationHelper<DeleteKeyringParcel, DeleteResult> mDeleteOpHelper;
+
+ private long[] mMasterKeyIds;
+ private boolean mHasSecret;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mDeleteOpHelper = new CryptoOperationHelper<>(DeleteKeyDialogActivity.this,
+ DeleteKeyDialogActivity.this, R.string.progress_deleting);
+ mDeleteOpHelper.onRestoreInstanceState(savedInstanceState);
+
+ mMasterKeyIds = getIntent().getLongArrayExtra(EXTRA_DELETE_MASTER_KEY_IDS);
+
+ Handler deleteDialogHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ if (msg.what == DeleteKeyDialogFragment.MESSAGE_PERFORM_DELETE) {
+ mHasSecret = msg.getData().getBoolean(DeleteKeyDialogFragment.MSG_HAS_SECRET);
+ mDeleteOpHelper.cryptoOperation();
+ }
+ }
+ };
+
+ Messenger messenger = new Messenger(deleteDialogHandler);
+
+ DeleteKeyDialogFragment deleteKeyDialogFragment
+ = DeleteKeyDialogFragment.newInstance(messenger, mMasterKeyIds);
+
+ deleteKeyDialogFragment.show(getSupportFragmentManager(), "deleteKeyDialog");
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ mDeleteOpHelper.handleActivityResult(requestCode, resultCode, data);
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mDeleteOpHelper.onSaveInstanceState(outState);
+ }
+
+ @Override
+ public DeleteKeyringParcel createOperationInput() {
+ return new DeleteKeyringParcel(mMasterKeyIds, mHasSecret);
+ }
+
+ @Override
+ public void onCryptoOperationSuccess(DeleteResult result) {
+ handleResult(result);
+ }
+
+ @Override
+ public void onCryptoOperationCancelled() {
+ setResult(RESULT_CANCELED);
+ finish();
+ }
+
+ @Override
+ public void onCryptoOperationError(DeleteResult result) {
+ handleResult(result);
+ }
+
+ @Override
+ public boolean onCryptoSetProgress(String msg, int progress, int max) {
+ return false;
+ }
+
+ public void handleResult(DeleteResult result) {
+ Intent intent = new Intent();
+ intent.putExtra(OperationResult.EXTRA_RESULT, result);
+ setResult(RESULT_OK, intent);
+ finish();
+ }
+
+ public static class DeleteKeyDialogFragment extends DialogFragment {
+
+ public static final String MSG_HAS_SECRET = "msg_has_secret";
+
+ private static final String ARG_MESSENGER = "messenger";
+ private static final String ARG_DELETE_MASTER_KEY_IDS = "delete_master_key_ids";
+
+ public static final int MESSAGE_PERFORM_DELETE = 1;
+
+ private TextView mMainMessage;
+ private View mInflateView;
+
+ private Messenger mMessenger;
+ /**
+ * Creates new instance of this delete file dialog fragment
+ */
+ 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_MASTER_KEY_IDS, masterKeyIds);
+
+ frag.setArguments(args);
+
+ return frag;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ final FragmentActivity activity = getActivity();
+ mMessenger = getArguments().getParcelable(ARG_MESSENGER);
+
+ final long[] masterKeyIds = getArguments().getLongArray(ARG_DELETE_MASTER_KEY_IDS);
+
+ ContextThemeWrapper theme = new ContextThemeWrapper(activity,
+ R.style.Theme_AppCompat_Light_Dialog);
+
+ CustomAlertDialogBuilder builder = new CustomAlertDialogBuilder(theme);
+
+ // Setup custom View to display in AlertDialog
+ LayoutInflater inflater = activity.getLayoutInflater();
+ mInflateView = inflater.inflate(R.layout.view_key_delete_fragment, null);
+ builder.setView(mInflateView);
+
+ mMainMessage = (TextView) mInflateView.findViewById(R.id.mainMessage);
+
+ final boolean hasSecret;
+
+ // If only a single key has been selected
+ if (masterKeyIds.length == 1) {
+ long masterKeyId = masterKeyIds[0];
+
+ try {
+ HashMap<String, Object> data = new ProviderHelper(activity).getUnifiedData(
+ masterKeyId, new String[]{
+ KeychainContract.KeyRings.USER_ID,
+ KeychainContract.KeyRings.HAS_ANY_SECRET
+ }, new int[]{
+ ProviderHelper.FIELD_TYPE_STRING,
+ ProviderHelper.FIELD_TYPE_INTEGER
+ }
+ );
+ String name;
+ KeyRing.UserId mainUserId = KeyRing.splitUserId((String) data.get(KeychainContract.KeyRings.USER_ID));
+ if (mainUserId.name != null) {
+ name = mainUserId.name;
+ } else {
+ name = getString(R.string.user_id_no_name);
+ }
+ hasSecret = ((Long) data.get(KeychainContract.KeyRings.HAS_ANY_SECRET)) == 1;
+
+ if (hasSecret) {
+ // show title only for secret key deletions,
+ // see http://www.google.com/design/spec/components/dialogs.html#dialogs-behavior
+ builder.setTitle(getString(R.string.title_delete_secret_key, name));
+ mMainMessage.setText(getString(R.string.secret_key_deletion_confirmation, name));
+ } else {
+ mMainMessage.setText(getString(R.string.public_key_deletetion_confirmation, name));
+ }
+ } catch (ProviderHelper.NotFoundException e) {
+ dismiss();
+ return null;
+ }
+ } else {
+ mMainMessage.setText(R.string.key_deletion_confirmation_multi);
+ hasSecret = false;
+ }
+
+ builder.setPositiveButton(R.string.btn_delete, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+
+ Bundle data = new Bundle();
+ data.putBoolean(MSG_HAS_SECRET, hasSecret);
+ Message msg = Message.obtain();
+ msg.setData(data);
+ msg.what = MESSAGE_PERFORM_DELETE;
+ try {
+ mMessenger.send(msg);
+ } catch (RemoteException e) {
+ Log.e(Constants.TAG, "messenger error", e);
+ }
+ }
+ });
+
+ builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int id) {
+ getActivity().finish();
+ }
+ });
+
+ return builder.show();
+ }
+ }
+
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java
index 4e9c5a836..f750c6d97 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java
@@ -410,6 +410,7 @@ public class EditKeyFragment extends QueueingCryptoOperationFragment<SaveKeyring
editSubkeyExpiry(position);
break;
case EditSubkeyDialogFragment.MESSAGE_REVOKE:
+ Log.e("PHILIP", "rev subkey " + keyId + " from " + mSaveKeyringParcel.mMasterKeyId);
// toggle
if (mSaveKeyringParcel.mRevokeSubKeys.contains(keyId)) {
mSaveKeyringParcel.mRevokeSubKeys.remove(keyId);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
index ee1c8460c..c53220d69 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
@@ -69,9 +69,9 @@ import org.sufficientlysecure.keychain.provider.KeychainDatabase;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.ConsolidateInputParcel;
import org.sufficientlysecure.keychain.service.ImportKeyringParcel;
+import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
import org.sufficientlysecure.keychain.ui.adapter.KeyAdapter;
import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
-import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.ui.util.Notify.Style;
@@ -91,6 +91,8 @@ public class KeyListFragment extends LoaderFragment
CryptoOperationHelper.Callback<ImportKeyringParcel, ImportKeyResult> {
static final int REQUEST_ACTION = 1;
+ private static final int REQUEST_DELETE = 2;
+ private static final int REQUEST_VIEW_KEY = 3;
private KeyListAdapter mAdapter;
private StickyListHeadersListView mStickyList;
@@ -336,7 +338,7 @@ public class KeyListFragment extends LoaderFragment
Intent viewIntent = new Intent(getActivity(), ViewKeyActivity.class);
viewIntent.setData(
KeyRings.buildGenericKeyRingUri(mAdapter.getMasterKeyId(position)));
- startActivity(viewIntent);
+ startActivityForResult(viewIntent, REQUEST_VIEW_KEY);
}
protected void encrypt(ActionMode mode, long[] masterKeyIds) {
@@ -362,30 +364,9 @@ public class KeyListFragment extends LoaderFragment
return;
}
- // Message is received after key is deleted
- Handler returnHandler = new Handler() {
- @Override
- public void handleMessage(Message message) {
- if (message.arg1 == DeleteKeyDialogFragment.MESSAGE_OKAY) {
- Bundle data = message.getData();
- if (data != null) {
- DeleteResult result = data.getParcelable(DeleteResult.EXTRA_RESULT);
- if (result != null) {
- result.createNotify(getActivity()).show();
- }
- }
- mode.finish();
- }
- }
- };
-
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(returnHandler);
-
- DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(messenger,
- masterKeyIds);
-
- deleteKeyDialog.show(getActivity().getSupportFragmentManager(), "deleteKeyDialog");
+ Intent intent = new Intent(getActivity(), DeleteKeyDialogActivity.class);
+ intent.putExtra(DeleteKeyDialogActivity.EXTRA_DELETE_MASTER_KEY_IDS, masterKeyIds);
+ startActivityForResult(intent, REQUEST_DELETE);
}
@@ -620,14 +601,35 @@ public class KeyListFragment extends LoaderFragment
mConsolidateOpHelper.handleActivityResult(requestCode, resultCode, data);
}
- if (requestCode == REQUEST_ACTION) {
- // if a result has been returned, display a notify
- if (data != null && data.hasExtra(OperationResult.EXTRA_RESULT)) {
- OperationResult result = data.getParcelableExtra(OperationResult.EXTRA_RESULT);
- result.createNotify(getActivity()).show();
- } else {
- super.onActivityResult(requestCode, resultCode, data);
- }
+ switch (requestCode) {
+ case REQUEST_DELETE:
+ mActionMode.finish();
+ if (data != null && data.hasExtra(OperationResult.EXTRA_RESULT)) {
+ OperationResult result = data.getParcelableExtra(OperationResult.EXTRA_RESULT);
+ result.createNotify(getActivity()).show();
+ } else {
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+ break;
+
+ case REQUEST_ACTION:
+ // if a result has been returned, display a notify
+ if (data != null && data.hasExtra(OperationResult.EXTRA_RESULT)) {
+ OperationResult result = data.getParcelableExtra(OperationResult.EXTRA_RESULT);
+ result.createNotify(getActivity()).show();
+ } else {
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+ break;
+
+ case REQUEST_VIEW_KEY:
+ if (data != null && data.hasExtra(OperationResult.EXTRA_RESULT)) {
+ OperationResult result = data.getParcelableExtra(OperationResult.EXTRA_RESULT);
+ result.createNotify(getActivity()).show();
+ } else {
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+ break;
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RevokeDeleteDialogActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RevokeDeleteDialogActivity.java
new file mode 100644
index 000000000..b60003419
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RevokeDeleteDialogActivity.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2015 Adithya Abraham Philip <adithyaphilip@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.ui;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.v4.app.DialogFragment;
+import android.support.v4.app.FragmentActivity;
+import android.view.ContextThemeWrapper;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.Spinner;
+
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.operations.results.DeleteResult;
+import org.sufficientlysecure.keychain.operations.results.OperationResult;
+import org.sufficientlysecure.keychain.operations.results.RevokeResult;
+import org.sufficientlysecure.keychain.service.DeleteKeyringParcel;
+import org.sufficientlysecure.keychain.service.RevokeKeyringParcel;
+import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
+import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
+import org.sufficientlysecure.keychain.ui.dialog.CustomAlertDialogBuilder;
+import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Preferences;
+
+public class RevokeDeleteDialogActivity extends FragmentActivity {
+
+ public static final String EXTRA_MASTER_KEY_ID = "extra_master_key_id";
+ public static final String EXTRA_KEYSERVER = "extra_keyserver";
+
+ private final int REVOKE_OP_ID = 1;
+ private final int DELETE_OP_ID = 2;
+ private CryptoOperationHelper<RevokeKeyringParcel, RevokeResult> mRevokeOpHelper;
+ private CryptoOperationHelper<DeleteKeyringParcel, DeleteResult> mDeleteOpHelper;
+
+ private long mMasterKeyId;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mRevokeOpHelper = new CryptoOperationHelper<>(this,
+ getRevocationCallback(), R.string.progress_revoking_uploading, REVOKE_OP_ID);
+ mRevokeOpHelper.onRestoreInstanceState(savedInstanceState);
+
+ mDeleteOpHelper = new CryptoOperationHelper<>(this,
+ getDeletionCallback(), R.string.progress_deleting, DELETE_OP_ID);
+ mDeleteOpHelper.onRestoreInstanceState(savedInstanceState);
+
+ mMasterKeyId = getIntent().getLongExtra(EXTRA_MASTER_KEY_ID, -1);
+
+ RevokeDeleteDialogFragment fragment = RevokeDeleteDialogFragment.newInstance();
+ fragment.show(getSupportFragmentManager(), "deleteRevokeDialog");
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ mDeleteOpHelper.handleActivityResult(requestCode, resultCode, data);
+ mRevokeOpHelper.handleActivityResult(requestCode, resultCode, data);
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mRevokeOpHelper.onSaveInstanceState(outState);
+ mDeleteOpHelper.onSaveInstanceState(outState);
+ }
+
+ private void returnResult(OperationResult result) {
+ Intent intent = new Intent();
+ intent.putExtra(OperationResult.EXTRA_RESULT, result);
+ setResult(RESULT_OK, intent);
+ finish();
+ }
+
+ private CryptoOperationHelper.Callback<RevokeKeyringParcel, RevokeResult> getRevocationCallback() {
+
+ CryptoOperationHelper.Callback<RevokeKeyringParcel, RevokeResult> callback
+ = new CryptoOperationHelper.Callback<RevokeKeyringParcel, RevokeResult>() {
+ @Override
+ public RevokeKeyringParcel createOperationInput() {
+ return new RevokeKeyringParcel(mMasterKeyId, true,
+ getIntent().getStringExtra(EXTRA_KEYSERVER));
+ }
+
+ @Override
+ public void onCryptoOperationSuccess(RevokeResult result) {
+ returnResult(result);
+ }
+
+ @Override
+ public void onCryptoOperationCancelled() {
+ setResult(RESULT_CANCELED);
+ finish();
+ }
+
+ @Override
+ public void onCryptoOperationError(RevokeResult result) {
+ returnResult(result);
+ }
+
+ @Override
+ public boolean onCryptoSetProgress(String msg, int progress, int max) {
+ return false;
+ }
+ };
+
+ return callback;
+ }
+
+ private CryptoOperationHelper.Callback<DeleteKeyringParcel, DeleteResult> getDeletionCallback() {
+
+ CryptoOperationHelper.Callback<DeleteKeyringParcel, DeleteResult> callback
+ = new CryptoOperationHelper.Callback<DeleteKeyringParcel, DeleteResult>() {
+ @Override
+ public DeleteKeyringParcel createOperationInput() {
+ return new DeleteKeyringParcel(new long[]{mMasterKeyId}, true);
+ }
+
+ @Override
+ public void onCryptoOperationSuccess(DeleteResult result) {
+ returnResult(result);
+ }
+
+ @Override
+ public void onCryptoOperationCancelled() {
+ setResult(RESULT_CANCELED);
+ finish();
+ }
+
+ @Override
+ public void onCryptoOperationError(DeleteResult result) {
+ returnResult(result);
+ }
+
+ @Override
+ public boolean onCryptoSetProgress(String msg, int progress, int max) {
+ return false;
+ }
+ };
+
+ return callback;
+ }
+
+ private void startRevocationOperation() {
+ mRevokeOpHelper.cryptoOperation();
+ }
+
+ private void startDeletionOperation() {
+ mDeleteOpHelper.cryptoOperation();
+ }
+
+ public static class RevokeDeleteDialogFragment extends DialogFragment {
+
+ public static RevokeDeleteDialogFragment newInstance() {
+ RevokeDeleteDialogFragment frag = new RevokeDeleteDialogFragment();
+ return frag;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ final Activity activity = getActivity();
+
+ final String CHOICE_REVOKE = getString(R.string.del_rev_dialog_choice_rev_upload);
+ final String CHOICE_DELETE = getString(R.string.del_rev_dialog_choice_delete);
+
+ // if the dialog is displayed from the application class, design is missing
+ // hack to get holo design (which is not automatically applied due to activity's Theme.NoDisplay
+ ContextThemeWrapper theme = new ContextThemeWrapper(activity,
+ R.style.Theme_AppCompat_Light_Dialog);
+
+ CustomAlertDialogBuilder alert = new CustomAlertDialogBuilder(theme);
+ alert.setTitle(R.string.del_rev_dialog_title);
+
+ LayoutInflater inflater = LayoutInflater.from(theme);
+ View view = inflater.inflate(R.layout.del_rev_dialog, null);
+ alert.setView(view);
+
+ final Spinner spinner = (Spinner) view.findViewById(R.id.spinner);
+
+ alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int id) {
+ dialog.cancel();
+ activity.setResult(RESULT_CANCELED);
+ activity.finish();
+ }
+ });
+
+ alert.setPositiveButton(R.string.del_rev_dialog_btn_revoke,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+
+ String choice = spinner.getSelectedItem().toString();
+ if (choice.equals(CHOICE_REVOKE)) {
+ ((RevokeDeleteDialogActivity) activity)
+ .startRevocationOperation();
+ } else if (choice.equals(CHOICE_DELETE)) {
+ ((RevokeDeleteDialogActivity) activity)
+ .startDeletionOperation();
+ } else {
+ throw new AssertionError(
+ "Unsupported delete type in RevokeDeleteDialogFragment");
+ }
+ }
+ });
+
+ final AlertDialog alertDialog = alert.show();
+
+ spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+ public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
+
+ String choice = parent.getItemAtPosition(pos).toString();
+
+ if (choice.equals(CHOICE_REVOKE)) {
+ alertDialog.getButton(AlertDialog.BUTTON_POSITIVE)
+ .setText(R.string.del_rev_dialog_btn_revoke);
+ } else if (choice.equals(CHOICE_DELETE)) {
+ alertDialog.getButton(AlertDialog.BUTTON_POSITIVE)
+ .setText(R.string.del_rev_dialog_btn_delete);
+ } else {
+ throw new AssertionError(
+ "Unsupported delete type in RevokeDeleteDialogFragment");
+ }
+ }
+
+ public void onNothingSelected(AdapterView<?> parent) {
+ }
+ });
+
+ return alertDialog;
+ }
+ }
+}
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 9ed46d517..32b5c76b7 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
@@ -68,7 +68,6 @@ import org.sufficientlysecure.keychain.service.ImportKeyringParcel;
import org.sufficientlysecure.keychain.service.ServiceProgressHandler.MessageStatus;
import org.sufficientlysecure.keychain.ui.base.BaseNfcActivity;
import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
-import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment;
import org.sufficientlysecure.keychain.ui.util.FormattingUtils;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
@@ -85,7 +84,6 @@ import org.sufficientlysecure.keychain.util.Preferences;
import java.io.IOException;
import java.util.ArrayList;
-
public class ViewKeyActivity extends BaseNfcActivity implements
LoaderManager.LoaderCallbacks<Cursor>,
CryptoOperationHelper.Callback<ImportKeyringParcel, ImportKeyResult> {
@@ -97,6 +95,8 @@ public class ViewKeyActivity extends BaseNfcActivity implements
static final int REQUEST_QR_FINGERPRINT = 1;
static final int REQUEST_BACKUP = 2;
static final int REQUEST_CERTIFY = 3;
+ static final int REQUEST_DELETE = 4;
+ static final int REQUEST_REVOKE_DELETE = 5;
public static final String EXTRA_DISPLAY_RESULT = "display_result";
@@ -419,27 +419,24 @@ public class ViewKeyActivity extends BaseNfcActivity implements
}
private void deleteKey() {
- new Handler().post(new Runnable() {
- @Override
- public void run() {
- // Message is received after key is deleted
- Handler returnHandler = new Handler() {
- @Override
- public void handleMessage(Message message) {
- if (message.arg1 == MessageStatus.OKAY.ordinal()) {
- setResult(RESULT_CANCELED);
- finish();
- }
- }
- };
-
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(returnHandler);
- DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(messenger,
- new long[]{ mMasterKeyId });
- deleteKeyDialog.show(getSupportFragmentManager(), "deleteKeyDialog");
- }
- });
+ if (mIsSecret && !mIsRevoked) {
+ Intent revokeDeleteIntent = new Intent(this, RevokeDeleteDialogActivity.class);
+
+ revokeDeleteIntent.putExtra(RevokeDeleteDialogActivity.EXTRA_MASTER_KEY_ID,
+ mMasterKeyId);
+ revokeDeleteIntent.putExtra(RevokeDeleteDialogActivity.EXTRA_KEYSERVER,
+ Preferences.getPreferences(this).getPreferredKeyserver());
+
+ startActivityForResult(revokeDeleteIntent, REQUEST_REVOKE_DELETE);
+
+ } else {
+ Intent deleteIntent = new Intent(this, DeleteKeyDialogActivity.class);
+
+ deleteIntent.putExtra(DeleteKeyDialogActivity.EXTRA_DELETE_MASTER_KEY_IDS,
+ new long[]{mMasterKeyId});
+
+ startActivityForResult(deleteIntent, REQUEST_DELETE);
+ }
}
@Override
@@ -487,6 +484,13 @@ public class ViewKeyActivity extends BaseNfcActivity implements
}
return;
}
+
+ case REQUEST_REVOKE_DELETE:
+ case REQUEST_DELETE: {
+ setResult(RESULT_OK, data);
+ finish();
+ return;
+ }
}
super.onActivityResult(requestCode, resultCode, data);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java
index 91ea969d7..c03c301a7 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java
@@ -40,6 +40,7 @@ import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
import org.sufficientlysecure.keychain.ui.NfcOperationActivity;
import org.sufficientlysecure.keychain.ui.OrbotRequiredDialogActivity;
import org.sufficientlysecure.keychain.ui.PassphraseDialogActivity;
+import org.sufficientlysecure.keychain.ui.RevokeDeleteDialogActivity;
import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
import org.sufficientlysecure.keychain.util.Log;
@@ -119,17 +120,13 @@ public class CryptoOperationHelper<T extends Parcelable, S extends OperationResu
switch (requiredInput.mType) {
// TODO: Verify that all started activities add to cryptoInputParcel if necessary (like OrbotRequiredDialogActivity)
- // don't forget to set mRequestedCode!
+ // always use CryptoOperationHelper.startActivityForResult!
case NFC_MOVE_KEY_TO_CARD:
case NFC_DECRYPT:
case NFC_SIGN: {
Intent intent = new Intent(activity, NfcOperationActivity.class);
intent.putExtra(NfcOperationActivity.EXTRA_REQUIRED_INPUT, requiredInput);
- if (mUseFragment) {
- mFragment.startActivityForResult(intent, mId + REQUEST_CODE_NFC);
- } else {
- activity.startActivityForResult(intent, mId + REQUEST_CODE_NFC);
- }
+ startActivityForResult(intent, REQUEST_CODE_NFC);
return;
}
@@ -137,22 +134,14 @@ public class CryptoOperationHelper<T extends Parcelable, S extends OperationResu
case PASSPHRASE_SYMMETRIC: {
Intent intent = new Intent(activity, PassphraseDialogActivity.class);
intent.putExtra(PassphraseDialogActivity.EXTRA_REQUIRED_INPUT, requiredInput);
- if (mUseFragment) {
- mFragment.startActivityForResult(intent, mId + REQUEST_CODE_PASSPHRASE);
- } else {
- activity.startActivityForResult(intent, mId + REQUEST_CODE_PASSPHRASE);
- }
+ startActivityForResult(intent, REQUEST_CODE_PASSPHRASE);
return;
}
case ENABLE_ORBOT: {
Intent intent = new Intent(activity, OrbotRequiredDialogActivity.class);
intent.putExtra(OrbotRequiredDialogActivity.EXTRA_CRYPTO_INPUT, cryptoInputParcel);
- if (mUseFragment) {
- mFragment.startActivityForResult(intent, mId + REQUEST_CODE_ENABLE_ORBOT);
- } else {
- activity.startActivityForResult(intent, mId + REQUEST_CODE_ENABLE_ORBOT);
- }
+ startActivityForResult(intent, REQUEST_CODE_ENABLE_ORBOT);
return;
}
@@ -162,13 +151,24 @@ public class CryptoOperationHelper<T extends Parcelable, S extends OperationResu
}
}
+ protected void startActivityForResult(Intent intent, int requestCode) {
+ mRequestedCode = requestCode;
+ if (mUseFragment) {
+ mFragment.startActivityForResult(intent, mRequestedCode);
+ } else {
+ mActivity.startActivityForResult(intent, mRequestedCode);
+ }
+ Log.e("PHILIP", "mRequestedCode: " + mRequestedCode);
+ }
+
/**
* Attempts the result of an activity started by this helper. Returns true if requestCode is
* recognized, false otherwise.
* @return true if requestCode was recognized, false otherwise
*/
public boolean handleActivityResult(int requestCode, int resultCode, Intent data) {
- Log.d(Constants.TAG, "received activity result in OperationHelper");
+ Log.d(Constants.TAG, "received activity result in OperationHelper with code: "
+ + requestCode + " while waiting for: " + mRequestedCode);
if ((requestCode & mId) != mId) {
// this wasn't meant for us to handle
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
deleted file mode 100644
index e92f9f78d..000000000
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui.dialog;
-
-import android.app.Dialog;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.support.v4.app.DialogFragment;
-import android.support.v4.app.FragmentActivity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.TextView;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.operations.results.DeleteResult;
-import org.sufficientlysecure.keychain.operations.results.OperationResult;
-import org.sufficientlysecure.keychain.pgp.KeyRing;
-import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.service.DeleteKeyringParcel;
-import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
-import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.util.HashMap;
-
-public class DeleteKeyDialogFragment extends DialogFragment
- implements CryptoOperationHelper.Callback<DeleteKeyringParcel, DeleteResult> {
- private static final String ARG_MESSENGER = "messenger";
- 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;
-
- private TextView mMainMessage;
- private View mInflateView;
-
- private Messenger mMessenger;
-
- // for CryptoOperationHelper.Callback
- private long[] mMasterKeyIds;
- private boolean mHasSecret;
- private CryptoOperationHelper<DeleteKeyringParcel, DeleteResult> mDeleteOpHelper;
-
- /**
- * Creates new instance of this delete file dialog fragment
- */
- 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_MASTER_KEY_IDS, masterKeyIds);
-
- frag.setArguments(args);
-
- return frag;
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (mDeleteOpHelper != null) {
- mDeleteOpHelper.handleActivityResult(requestCode, resultCode, data);
- }
- super.onActivityResult(requestCode, resultCode, data);
- }
-
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- final FragmentActivity activity = getActivity();
- mMessenger = getArguments().getParcelable(ARG_MESSENGER);
-
- final long[] masterKeyIds = getArguments().getLongArray(ARG_DELETE_MASTER_KEY_IDS);
-
- CustomAlertDialogBuilder builder = new CustomAlertDialogBuilder(activity);
-
- // Setup custom View to display in AlertDialog
- LayoutInflater inflater = activity.getLayoutInflater();
- mInflateView = inflater.inflate(R.layout.view_key_delete_fragment, null);
- builder.setView(mInflateView);
-
- mMainMessage = (TextView) mInflateView.findViewById(R.id.mainMessage);
-
- final boolean hasSecret;
-
- // If only a single key has been selected
- if (masterKeyIds.length == 1) {
- long masterKeyId = masterKeyIds[0];
-
- try {
- HashMap<String, Object> data = new ProviderHelper(activity).getUnifiedData(
- masterKeyId, new String[]{
- KeyRings.USER_ID,
- KeyRings.HAS_ANY_SECRET
- }, new int[]{
- ProviderHelper.FIELD_TYPE_STRING,
- ProviderHelper.FIELD_TYPE_INTEGER
- }
- );
- String name;
- KeyRing.UserId mainUserId = KeyRing.splitUserId((String) data.get(KeyRings.USER_ID));
- if (mainUserId.name != null) {
- name = mainUserId.name;
- } else {
- name = getString(R.string.user_id_no_name);
- }
- hasSecret = ((Long) data.get(KeyRings.HAS_ANY_SECRET)) == 1;
-
- if (hasSecret) {
- // show title only for secret key deletions,
- // see http://www.google.com/design/spec/components/dialogs.html#dialogs-behavior
- builder.setTitle(getString(R.string.title_delete_secret_key, name));
- mMainMessage.setText(getString(R.string.secret_key_deletion_confirmation, name));
- } else {
- mMainMessage.setText(getString(R.string.public_key_deletetion_confirmation, name));
- }
- } catch (ProviderHelper.NotFoundException e) {
- dismiss();
- return null;
- }
- } else {
- mMainMessage.setText(R.string.key_deletion_confirmation_multi);
- hasSecret = false;
- }
-
- builder.setPositiveButton(R.string.btn_delete, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
-
- mMasterKeyIds = masterKeyIds;
- mHasSecret = hasSecret;
-
- mDeleteOpHelper = new CryptoOperationHelper<>
- (1, DeleteKeyDialogFragment.this, DeleteKeyDialogFragment.this,
- R.string.progress_deleting);
- mDeleteOpHelper.cryptoOperation();
- // do NOT dismiss here, it'll give
- // OperationHelper a null fragmentManager
- // dismiss();
- }
- });
- builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
-
- @Override
- public void onClick(DialogInterface dialog, int id) {
- dismiss();
- }
- });
-
- return builder.show();
- }
-
- @Override
- public DeleteKeyringParcel createOperationInput() {
- return new DeleteKeyringParcel(mMasterKeyIds, mHasSecret);
- }
-
- @Override
- public void onCryptoOperationSuccess(DeleteResult result) {
- handleResult(result);
- }
-
- @Override
- public void onCryptoOperationCancelled() {
-
- }
-
- @Override
- public void onCryptoOperationError(DeleteResult result) {
- handleResult(result);
- }
-
- @Override
- public boolean onCryptoSetProgress(String msg, int progress, int max) {
- return false;
- }
-
- public void handleResult(DeleteResult result) {
- try {
- Bundle data = new Bundle();
- data.putParcelable(OperationResult.EXTRA_RESULT, result);
- Message msg = Message.obtain();
- msg.arg1 = ServiceProgressHandler.MessageStatus.OKAY.ordinal();
- msg.setData(data);
- mMessenger.send(msg);
- } catch (RemoteException e) {
- Log.e(Constants.TAG, "messenger error", e);
- }
- dismiss();
- }
-}