aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java9
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java9
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java50
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java7
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java12
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java8
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java85
-rw-r--r--OpenKeychain/src/main/res/values/strings.xml4
8 files changed, 133 insertions, 51 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java
index 067af3f7c..0bc3ac0ab 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java
@@ -135,10 +135,10 @@ public class PgpImportExport {
// If there aren't even any keys, do nothing here.
if (entries == null || !entries.hasNext()) {
return new ImportKeyResult(
- ImportKeyResult.RESULT_FAIL_NOTHING, mProviderHelper.getLog(), 0, 0, 0);
+ ImportKeyResult.RESULT_FAIL_NOTHING, mProviderHelper.getLog(), 0, 0, 0, 0);
}
- int newKeys = 0, oldKeys = 0, badKeys = 0;
+ int newKeys = 0, oldKeys = 0, badKeys = 0, secret = 0;
int position = 0;
double progSteps = 100.0 / num;
@@ -173,6 +173,9 @@ public class PgpImportExport {
oldKeys += 1;
} else {
newKeys += 1;
+ if (key.isSecret()) {
+ secret += 1;
+ }
}
} catch (IOException e) {
@@ -209,7 +212,7 @@ public class PgpImportExport {
}
}
- return new ImportKeyResult(resultType, log, newKeys, oldKeys, badKeys);
+ return new ImportKeyResult(resultType, log, newKeys, oldKeys, badKeys, secret);
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
index 8fd4bc7cf..6447a180c 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
@@ -832,6 +832,8 @@ public class ProviderHelper {
log(LogLevel.START, LogType.MSG_CON);
mIndent += 1;
+ progress.setProgress(R.string.progress_con_saving, 0, 100);
+
try {
log(LogLevel.DEBUG, LogType.MSG_CON_SAVE_SECRET);
@@ -891,6 +893,8 @@ public class ProviderHelper {
mIndent -= 1;
}
+ progress.setProgress(R.string.progress_con_saving, 3, 100);
+
// 1b. fetch all public keyrings into a cache file
try {
@@ -998,11 +1002,6 @@ public class ProviderHelper {
log(LogLevel.DEBUG, LogType.MSG_CON_DB_CLEAR);
mContentResolver.delete(KeyRings.buildUnifiedKeyRingsUri(), null, null);
- // debug: break if this isn't recovery
- if (!recovery) {
- return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog);
- }
-
FileImportCache<ParcelableKeyRing> cacheSecret =
new FileImportCache<ParcelableKeyRing>(mContext, "consolidate_secret.pcl");
FileImportCache<ParcelableKeyRing> cachePublic =
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 e82c43d82..ad2932f92 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);
@@ -667,6 +679,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/service/OperationResults.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java
index 878f6ca47..c59a7d172 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java
@@ -40,7 +40,7 @@ public abstract class OperationResults {
public static class ImportKeyResult extends OperationResultParcel {
- public final int mNewKeys, mUpdatedKeys, mBadKeys;
+ public final int mNewKeys, mUpdatedKeys, mBadKeys, mSecret;
// At least one new key
public static final int RESULT_OK_NEWKEYS = 2;
@@ -76,14 +76,16 @@ public abstract class OperationResults {
mNewKeys = source.readInt();
mUpdatedKeys = source.readInt();
mBadKeys = source.readInt();
+ mSecret = source.readInt();
}
public ImportKeyResult(int result, OperationLog log,
- int newKeys, int updatedKeys, int badKeys) {
+ int newKeys, int updatedKeys, int badKeys, int secret) {
super(result, log);
mNewKeys = newKeys;
mUpdatedKeys = updatedKeys;
mBadKeys = badKeys;
+ mSecret = secret;
}
@Override
@@ -92,6 +94,7 @@ public abstract class OperationResults {
dest.writeInt(mNewKeys);
dest.writeInt(mUpdatedKeys);
dest.writeInt(mBadKeys);
+ dest.writeInt(mSecret);
}
public static Creator<ImportKeyResult> CREATOR = new Creator<ImportKeyResult>() {
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 d1109631a..96a332d3e 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
@@ -79,6 +79,9 @@ public class KeyListFragment extends LoaderFragment
private KeyListAdapter mAdapter;
private StickyListHeadersListView mStickyList;
+ // saves the mode object for multiselect, needed for reset at some point
+ private ActionMode mActionMode = null;
+
private String mQuery;
private SearchView mSearchView;
// empty list layout
@@ -146,6 +149,7 @@ public class KeyListFragment extends LoaderFragment
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
android.view.MenuInflater inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.key_list_multi, menu);
+ mActionMode = mode;
return true;
}
@@ -191,6 +195,7 @@ public class KeyListFragment extends LoaderFragment
@Override
public void onDestroyActionMode(ActionMode mode) {
+ mActionMode = null;
mAdapter.clearSelection();
}
@@ -286,6 +291,13 @@ public class KeyListFragment extends LoaderFragment
// this view is made visible if no data is available
mStickyList.setEmptyView(getActivity().findViewById(R.id.key_list_empty));
+ // end action mode, if any
+ if (mActionMode != null) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+ mActionMode.finish();
+ }
+ }
+
// The list should now be shown.
if (isResumed()) {
setContentShown(true);
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 71f4504d7..fede86b1c 100644
--- a/OpenKeychain/src/main/res/values/strings.xml
+++ b/OpenKeychain/src/main/res/values/strings.xml
@@ -301,8 +301,10 @@
<string name="progress_decompressing_data">decompressing data…</string>
<string name="progress_verifying_integrity">verifying integrity…</string>
<string name="progress_deleting_securely">deleting \'%s\' securely…</string>
+ <string name="progress_deleting">deleting keys…</string>
- <string name="progress_con_reimport">reimporting database…</string>
+ <string name="progress_con_saving">consolidate: saving to cache…</string>
+ <string name="progress_con_reimport">consolidate: reimporting…</string>
<!-- action strings -->
<string name="hint_keyserver_search_hint">Name/Email/Key ID…</string>