Add cancelable mechanism and support in key import

Closes #323
This commit is contained in:
Vincent Breitmoser
2014-08-31 17:32:13 +02:00
parent 38c6cf045c
commit 7da7832284
9 changed files with 119 additions and 90 deletions

View File

@@ -72,6 +72,7 @@ import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* This Service contains all important long lasting operations for APG. It receives Intents with
@@ -110,6 +111,8 @@ public class KeychainIntentService extends IntentService
public static final String ACTION_CONSOLIDATE = Constants.INTENT_PREFIX + "CONSOLIDATE";
public static final String ACTION_CANCEL = Constants.INTENT_PREFIX + "CANCEL";
/* keys for data bundle */
// encrypt, decrypt, import export
@@ -196,6 +199,8 @@ public class KeychainIntentService extends IntentService
Messenger mMessenger;
private boolean mIsCanceled;
// this attribute can possibly merged with the one above? not sure...
private AtomicBoolean mActionCanceled = new AtomicBoolean(false);
public KeychainIntentService() {
super("KeychainIntentService");
@@ -214,6 +219,10 @@ public class KeychainIntentService extends IntentService
*/
@Override
protected void onHandleIntent(Intent intent) {
// We have not been cancelled! (yet)
mActionCanceled.set(false);
Bundle extras = intent.getExtras();
if (extras == null) {
Log.e(Constants.TAG, "Extras bundle is null!");
@@ -500,7 +509,7 @@ public class KeychainIntentService extends IntentService
ProviderHelper providerHelper = new ProviderHelper(this);
PgpImportExport pgpImportExport = new PgpImportExport(this, providerHelper, this);
ImportKeyResult result = pgpImportExport.importKeyRings(entries);
ImportKeyResult result = pgpImportExport.importKeyRings(entries, mActionCanceled);
if (result.mSecret > 0) {
providerHelper.consolidateDatabaseStep1(this);
@@ -612,7 +621,6 @@ public class KeychainIntentService extends IntentService
ArrayList<ParcelableKeyRing> keyRings = new ArrayList<ParcelableKeyRing>(entries.size());
for (ImportKeysListEntry entry : entries) {
Keyserver server;
if (entry.getOrigin() == null) {
server = new HkpKeyserver(keyServer);
@@ -874,6 +882,15 @@ public class KeychainIntentService extends IntentService
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (ACTION_CANCEL.equals(intent.getAction())) {
mActionCanceled.set(true);
return START_STICKY;
}
return super.onStartCommand(intent, flags, startId);
}
private String getOriginalFilename(Bundle data) throws PgpGeneralException, FileNotFoundException {
int target = data.getInt(TARGET);
switch (target) {

View File

@@ -60,18 +60,16 @@ public class KeychainIntentServiceHandler extends Handler {
public KeychainIntentServiceHandler(Activity activity, String progressDialogMessage,
int progressDialogStyle) {
this(activity, progressDialogMessage, progressDialogStyle, false, null);
this(activity, progressDialogMessage, progressDialogStyle, false);
}
public KeychainIntentServiceHandler(Activity activity, String progressDialogMessage,
int progressDialogStyle, boolean cancelable,
OnCancelListener onCancelListener) {
int progressDialogStyle, boolean cancelable) {
this.mActivity = activity;
this.mProgressDialogFragment = ProgressDialogFragment.newInstance(
progressDialogMessage,
progressDialogStyle,
cancelable,
onCancelListener);
cancelable);
}
public void showProgressDialog(FragmentActivity activity) {

View File

@@ -55,13 +55,17 @@ public class OperationResultParcel implements Parcelable {
public static final String EXTRA_RESULT = "operation_result";
/** Holds the overall result, the number specifying varying degrees of success. The first bit
* is 0 on overall success, 1 on overall failure. All other bits may be used for more specific
* conditions. */
/** Holds the overall result, the number specifying varying degrees of success:
* - The first bit is 0 on overall success, 1 on overall failure
* - The second bit indicates if the action was cancelled - may still be an error or success!
* - The third bit should be set if the operation succeeded with warnings
* All other bits may be used for more specific conditions. */
final int mResult;
public static final int RESULT_OK = 0;
public static final int RESULT_ERROR = 1;
public static final int RESULT_CANCELLED = 2;
public static final int RESULT_WARNINGS = 4;
/// A list of log entries tied to the operation result.
final OperationLog mLog;

View File

@@ -26,6 +26,7 @@ import android.view.View;
import com.github.johnpersano.supertoasts.SuperCardToast;
import com.github.johnpersano.supertoasts.SuperToast;
import com.github.johnpersano.supertoasts.SuperToast.Duration;
import com.github.johnpersano.supertoasts.util.OnClickWrapper;
import com.github.johnpersano.supertoasts.util.Style;
@@ -44,16 +45,14 @@ public abstract class OperationResults {
public final int mNewKeys, mUpdatedKeys, mBadKeys, mSecret;
// At least one new key
public static final int RESULT_OK_NEWKEYS = 2;
public static final int RESULT_OK_NEWKEYS = 8;
// At least one updated key
public static final int RESULT_OK_UPDATED = 4;
public static final int RESULT_OK_UPDATED = 16;
// At least one key failed (might still be an overall success)
public static final int RESULT_WITH_ERRORS = 8;
// There are warnings in the log
public static final int RESULT_WITH_WARNINGS = 16;
public static final int RESULT_WITH_ERRORS = 32;
// No keys to import...
public static final int RESULT_FAIL_NOTHING = 32 + 1;
public static final int RESULT_FAIL_NOTHING = 64 + 1;
public boolean isOkBoth() {
return (mResult & (RESULT_OK_NEWKEYS | RESULT_OK_UPDATED))
@@ -119,15 +118,20 @@ public abstract class OperationResults {
if ((resultType & OperationResultParcel.RESULT_ERROR) == 0) {
String withWarnings;
duration = Duration.EXTRA_LONG;
color = Style.GREEN;
withWarnings = "";
// Any warnings?
if ((resultType & ImportKeyResult.RESULT_WITH_WARNINGS) > 0) {
if ((resultType & ImportKeyResult.RESULT_WARNINGS) > 0) {
duration = 0;
color = Style.ORANGE;
withWarnings = activity.getResources().getString(R.string.import_with_warnings);
} else {
duration = SuperToast.Duration.LONG;
color = Style.GREEN;
withWarnings = "";
withWarnings += activity.getString(R.string.import_with_warnings);
}
if ((resultType & ImportKeyResult.RESULT_CANCELLED) > 0) {
duration = 0;
color = Style.ORANGE;
withWarnings += activity.getString(R.string.import_with_cancelled);
}
// New and updated keys
@@ -152,13 +156,14 @@ public abstract class OperationResults {
duration = 0;
color = Style.RED;
if (isFailNothing()) {
str = activity.getString(R.string.import_error_nothing);
str = activity.getString((resultType & ImportKeyResult.RESULT_CANCELLED) > 0
? R.string.import_error_nothing_cancelled
: R.string.import_error_nothing);
} else {
str = activity.getString(R.string.import_error);
}
}
// TODO: externalize into Notify class?
boolean button = getLog() != null && !getLog().isEmpty();
SuperCardToast toast = new SuperCardToast(activity,
button ? SuperToast.Type.BUTTON : SuperToast.Type.STANDARD,
@@ -243,7 +248,7 @@ public abstract class OperationResults {
}
// Some old key was updated
public static final int UPDATED = 2;
public static final int UPDATED = 4;
// Public key was saved
public static final int SAVED_PUBLIC = 8;