mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-23 17:22:16 -05:00
add cancel support to edit key action
This commit is contained in:
parent
d483a8b73e
commit
e46bc24079
@ -73,6 +73,7 @@ import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.Stack;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* This class is the single place where ALL operations that actually modify a PGP public or secret
|
||||
@ -85,6 +86,7 @@ import java.util.Stack;
|
||||
*/
|
||||
public class PgpKeyOperation {
|
||||
private Stack<Progressable> mProgress;
|
||||
private AtomicBoolean mCancelled;
|
||||
|
||||
// most preferred is first
|
||||
private static final int[] PREFERRED_SYMMETRIC_ALGORITHMS = new int[]{
|
||||
@ -134,6 +136,15 @@ public class PgpKeyOperation {
|
||||
}
|
||||
}
|
||||
|
||||
public PgpKeyOperation(Progressable progress, AtomicBoolean cancelled) {
|
||||
this(progress);
|
||||
mCancelled = cancelled;
|
||||
}
|
||||
|
||||
private boolean checkCancelled() {
|
||||
return mCancelled != null && mCancelled.get();
|
||||
}
|
||||
|
||||
private void subProgressPush(int from, int to) {
|
||||
if (mProgress == null) {
|
||||
return;
|
||||
@ -450,6 +461,12 @@ public class PgpKeyOperation {
|
||||
|
||||
try {
|
||||
|
||||
// Check if we were cancelled
|
||||
if (checkCancelled()) {
|
||||
log.add(LogLevel.CANCELLED, LogType.MSG_OPERATION_CANCELLED, indent);
|
||||
return new EditKeyResult(EditKeyResult.RESULT_CANCELLED, log, null);
|
||||
}
|
||||
|
||||
{ // work on master secret key
|
||||
|
||||
PGPPublicKey modifiedPublicKey = masterPublicKey;
|
||||
@ -640,6 +657,12 @@ public class PgpKeyOperation {
|
||||
|
||||
}
|
||||
|
||||
// Check if we were cancelled - again
|
||||
if (checkCancelled()) {
|
||||
log.add(LogLevel.CANCELLED, LogType.MSG_OPERATION_CANCELLED, indent);
|
||||
return new EditKeyResult(EditKeyResult.RESULT_CANCELLED, log, null);
|
||||
}
|
||||
|
||||
// 4a. For each subkey change, generate new subkey binding certificate
|
||||
subProgressPush(50, 60);
|
||||
for (int i = 0; i < saveParcel.mChangeSubKeys.size(); i++) {
|
||||
@ -750,6 +773,12 @@ public class PgpKeyOperation {
|
||||
subProgressPush(70, 90);
|
||||
for (int i = 0; i < saveParcel.mAddSubKeys.size(); i++) {
|
||||
|
||||
// Check if we were cancelled - again. This operation is expensive so we do it each loop.
|
||||
if (checkCancelled()) {
|
||||
log.add(LogLevel.CANCELLED, LogType.MSG_OPERATION_CANCELLED, indent);
|
||||
return new EditKeyResult(EditKeyResult.RESULT_CANCELLED, log, null);
|
||||
}
|
||||
|
||||
progress(R.string.progress_modify_subkeyadd, (i-1) * (100 / saveParcel.mAddSubKeys.size()));
|
||||
SaveKeyringParcel.SubkeyAdd add = saveParcel.mAddSubKeys.get(i);
|
||||
log.add(LogLevel.INFO, LogType.MSG_MF_SUBKEY_NEW, indent,
|
||||
@ -806,6 +835,12 @@ public class PgpKeyOperation {
|
||||
}
|
||||
subProgressPop();
|
||||
|
||||
// Check if we were cancelled - again. This operation is expensive so we do it each loop.
|
||||
if (checkCancelled()) {
|
||||
log.add(LogLevel.CANCELLED, LogType.MSG_OPERATION_CANCELLED, indent);
|
||||
return new EditKeyResult(EditKeyResult.RESULT_CANCELLED, log, null);
|
||||
}
|
||||
|
||||
// 6. If requested, change passphrase
|
||||
if (saveParcel.mNewPassphrase != null) {
|
||||
progress(R.string.progress_modify_passphrase, 90);
|
||||
|
@ -54,6 +54,9 @@ 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;
|
||||
import org.sufficientlysecure.keychain.service.OperationResultParcel.LogLevel;
|
||||
import org.sufficientlysecure.keychain.service.OperationResultParcel.LogType;
|
||||
import org.sufficientlysecure.keychain.service.OperationResultParcel.OperationLog;
|
||||
import org.sufficientlysecure.keychain.service.OperationResults.ConsolidateResult;
|
||||
import org.sufficientlysecure.keychain.service.OperationResults.EditKeyResult;
|
||||
import org.sufficientlysecure.keychain.service.OperationResults.ImportKeyResult;
|
||||
@ -93,7 +96,7 @@ public class KeychainIntentService extends IntentService
|
||||
|
||||
public static final String ACTION_DECRYPT_METADATA = Constants.INTENT_PREFIX + "DECRYPT_METADATA";
|
||||
|
||||
public static final String ACTION_SAVE_KEYRING = Constants.INTENT_PREFIX + "SAVE_KEYRING";
|
||||
public static final String ACTION_EDIT_KEYRING = Constants.INTENT_PREFIX + "EDIT_KEYRING";
|
||||
|
||||
public static final String ACTION_DELETE_FILE_SECURELY = Constants.INTENT_PREFIX
|
||||
+ "DELETE_FILE_SECURELY";
|
||||
@ -144,8 +147,8 @@ public class KeychainIntentService extends IntentService
|
||||
public static final String DECRYPT_PASSPHRASE = "passphrase";
|
||||
|
||||
// save keyring
|
||||
public static final String SAVE_KEYRING_PARCEL = "save_parcel";
|
||||
public static final String SAVE_KEYRING_PASSPHRASE = "passphrase";
|
||||
public static final String EDIT_KEYRING_PARCEL = "save_parcel";
|
||||
public static final String EDIT_KEYRING_PASSPHRASE = "passphrase";
|
||||
|
||||
// delete file securely
|
||||
public static final String DELETE_FILE = "deleteFile";
|
||||
@ -409,21 +412,22 @@ public class KeychainIntentService extends IntentService
|
||||
} catch (Exception e) {
|
||||
sendErrorToHandler(e);
|
||||
}
|
||||
} else if (ACTION_SAVE_KEYRING.equals(action)) {
|
||||
} else if (ACTION_EDIT_KEYRING.equals(action)) {
|
||||
try {
|
||||
/* Input */
|
||||
SaveKeyringParcel saveParcel = data.getParcelable(SAVE_KEYRING_PARCEL);
|
||||
SaveKeyringParcel saveParcel = data.getParcelable(EDIT_KEYRING_PARCEL);
|
||||
if (saveParcel == null) {
|
||||
Log.e(Constants.TAG, "bug: missing save_keyring_parcel in data!");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Operation */
|
||||
PgpKeyOperation keyOperations = new PgpKeyOperation(new ProgressScaler(this, 10, 60, 100));
|
||||
PgpKeyOperation keyOperations =
|
||||
new PgpKeyOperation(new ProgressScaler(this, 10, 60, 100), mActionCanceled);
|
||||
EditKeyResult modifyResult;
|
||||
|
||||
if (saveParcel.mMasterKeyId != null) {
|
||||
String passphrase = data.getString(SAVE_KEYRING_PASSPHRASE);
|
||||
String passphrase = data.getString(EDIT_KEYRING_PASSPHRASE);
|
||||
CanonicalizedSecretKeyRing secRing =
|
||||
new ProviderHelper(this).getCanonicalizedSecretKeyRing(saveParcel.mMasterKeyId);
|
||||
|
||||
@ -445,6 +449,20 @@ public class KeychainIntentService extends IntentService
|
||||
|
||||
UncachedKeyRing ring = modifyResult.getRing();
|
||||
|
||||
// Check if the action was cancelled
|
||||
if (mActionCanceled.get()) {
|
||||
OperationLog log = modifyResult.getLog();
|
||||
// If it wasn't added before, add log entry
|
||||
if (!modifyResult.cancelled()) {
|
||||
log.add(LogLevel.CANCELLED, LogType.MSG_OPERATION_CANCELLED, 0);
|
||||
}
|
||||
// If so, just stop without saving
|
||||
SaveKeyringResult saveResult = new SaveKeyringResult(
|
||||
SaveKeyringResult.RESULT_CANCELLED, log, null);
|
||||
sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, saveResult);
|
||||
return;
|
||||
}
|
||||
|
||||
// Save the keyring. The ProviderHelper is initialized with the previous log
|
||||
SaveKeyringResult saveResult = new ProviderHelper(this, modifyResult.getLog())
|
||||
.saveSecretKeyRing(ring, new ProgressScaler(this, 60, 95, 100));
|
||||
|
@ -86,7 +86,11 @@ public class OperationResultParcel implements Parcelable {
|
||||
}
|
||||
|
||||
public boolean success() {
|
||||
return (mResult & 1) == 0;
|
||||
return (mResult & RESULT_ERROR) == 0;
|
||||
}
|
||||
|
||||
public boolean cancelled() {
|
||||
return (mResult & RESULT_CANCELLED) == RESULT_CANCELLED;
|
||||
}
|
||||
|
||||
public OperationLog getLog() {
|
||||
@ -151,30 +155,25 @@ public class OperationResultParcel implements Parcelable {
|
||||
|
||||
public SuperCardToast createNotify(final Activity activity) {
|
||||
|
||||
int resultType = getResult();
|
||||
|
||||
String str;
|
||||
int duration, color;
|
||||
int color;
|
||||
|
||||
// Not an overall failure
|
||||
if ((resultType & OperationResultParcel.RESULT_ERROR) == 0) {
|
||||
|
||||
if (cancelled()) {
|
||||
color = Style.RED;
|
||||
str = "operation cancelled!";
|
||||
} else if (success()) {
|
||||
if (getLog().containsWarnings()) {
|
||||
color = Style.ORANGE;
|
||||
} else {
|
||||
color = Style.GREEN;
|
||||
}
|
||||
|
||||
str = "operation succeeded!";
|
||||
// str = activity.getString(R.string.import_error);
|
||||
|
||||
} else {
|
||||
|
||||
color = Style.RED;
|
||||
|
||||
str = "operation failed";
|
||||
// str = activity.getString(R.string.import_error);
|
||||
|
||||
}
|
||||
|
||||
boolean button = getLog() != null && !getLog().isEmpty();
|
||||
@ -227,7 +226,8 @@ public class OperationResultParcel implements Parcelable {
|
||||
*/
|
||||
public static enum LogType {
|
||||
|
||||
INTERNAL_ERROR (R.string.internal_error),
|
||||
MSG_INTERNAL_ERROR (R.string.msg_internal_error),
|
||||
MSG_OPERATION_CANCELLED (R.string.msg_cancelled),
|
||||
|
||||
// import public
|
||||
MSG_IP(R.string.msg_ip),
|
||||
@ -444,6 +444,7 @@ public class OperationResultParcel implements Parcelable {
|
||||
ERROR, // should occur once at the end of a failed operation
|
||||
START, // should occur once at the start of each independent operation
|
||||
OK, // should occur once at the end of a successful operation
|
||||
CANCELLED, // should occur once at the end of a cancelled operation
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -31,7 +31,6 @@ import android.view.ViewGroup;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.spongycastle.bcpg.PublicKeyAlgorithmTags;
|
||||
import org.spongycastle.bcpg.sig.KeyFlags;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
@ -126,7 +125,7 @@ public class CreateKeyFinalFragment extends Fragment {
|
||||
|
||||
private void createKey() {
|
||||
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
|
||||
intent.setAction(KeychainIntentService.ACTION_SAVE_KEYRING);
|
||||
intent.setAction(KeychainIntentService.ACTION_EDIT_KEYRING);
|
||||
|
||||
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
|
||||
getActivity(),
|
||||
@ -178,7 +177,7 @@ public class CreateKeyFinalFragment extends Fragment {
|
||||
parcel.mNewPassphrase = mPassphrase;
|
||||
|
||||
// get selected key entries
|
||||
data.putParcelable(KeychainIntentService.SAVE_KEYRING_PARCEL, parcel);
|
||||
data.putParcelable(KeychainIntentService.EDIT_KEYRING_PARCEL, parcel);
|
||||
|
||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||
|
||||
|
@ -507,7 +507,8 @@ public class EditKeyFragment extends LoaderFragment implements
|
||||
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
|
||||
getActivity(),
|
||||
getString(R.string.progress_saving),
|
||||
ProgressDialog.STYLE_HORIZONTAL) {
|
||||
ProgressDialog.STYLE_HORIZONTAL,
|
||||
true) {
|
||||
public void handleMessage(Message message) {
|
||||
// handle messages by standard KeychainIntentServiceHandler first
|
||||
super.handleMessage(message);
|
||||
@ -543,12 +544,12 @@ public class EditKeyFragment extends LoaderFragment implements
|
||||
|
||||
// Send all information needed to service to import key in other thread
|
||||
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
|
||||
intent.setAction(KeychainIntentService.ACTION_SAVE_KEYRING);
|
||||
intent.setAction(KeychainIntentService.ACTION_EDIT_KEYRING);
|
||||
|
||||
// fill values for this action
|
||||
Bundle data = new Bundle();
|
||||
data.putString(KeychainIntentService.SAVE_KEYRING_PASSPHRASE, passphrase);
|
||||
data.putParcelable(KeychainIntentService.SAVE_KEYRING_PARCEL, mSaveKeyringParcel);
|
||||
data.putString(KeychainIntentService.EDIT_KEYRING_PASSPHRASE, passphrase);
|
||||
data.putParcelable(KeychainIntentService.EDIT_KEYRING_PARCEL, mSaveKeyringParcel);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||
|
||||
// Create a new Messenger for the communication back
|
||||
@ -560,5 +561,6 @@ public class EditKeyFragment extends LoaderFragment implements
|
||||
|
||||
// start service with intent
|
||||
getActivity().startService(intent);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -192,6 +192,7 @@ public class LogDisplayFragment extends ListFragment implements OnTouchListener
|
||||
case ERROR: ih.mImg.setBackgroundColor(Color.RED); break;
|
||||
case START: ih.mImg.setBackgroundColor(Color.GREEN); break;
|
||||
case OK: ih.mImg.setBackgroundColor(Color.GREEN); break;
|
||||
case CANCELLED: ih.mImg.setBackgroundColor(Color.RED); break;
|
||||
}
|
||||
|
||||
return convertView;
|
||||
|
@ -443,7 +443,7 @@
|
||||
<!--Consolidate-->
|
||||
<!--PassphraseCache-->
|
||||
<!--unsorted-->
|
||||
<string name="internal_error">Interner Fehler!</string>
|
||||
<string name="msg_internal_error">Interner Fehler!</string>
|
||||
<string name="section_certifier_id">Beglaubiger</string>
|
||||
<string name="section_cert">Zertifikatdetails</string>
|
||||
<string name="label_user_id">Identität</string>
|
||||
|
@ -662,7 +662,7 @@
|
||||
<string name="passp_cache_notif_clear">Limpiar caché</string>
|
||||
<string name="passp_cache_notif_pwd">Contraseña</string>
|
||||
<!--unsorted-->
|
||||
<string name="internal_error">¡Error interno!</string>
|
||||
<string name="msg_internal_error">¡Error interno!</string>
|
||||
<string name="section_certifier_id">Certificador</string>
|
||||
<string name="section_cert">Detalles del certificado</string>
|
||||
<string name="label_user_id">Identidad</string>
|
||||
|
@ -662,7 +662,7 @@
|
||||
<string name="passp_cache_notif_clear">Effacer le cache</string>
|
||||
<string name="passp_cache_notif_pwd">Mot de passe</string>
|
||||
<!--unsorted-->
|
||||
<string name="internal_error">Erreur interne !</string>
|
||||
<string name="msg_internal_error">Erreur interne !</string>
|
||||
<string name="section_certifier_id">Certificateur</string>
|
||||
<string name="section_cert">Détails du certificat</string>
|
||||
<string name="label_user_id">identité</string>
|
||||
|
@ -662,7 +662,7 @@
|
||||
<string name="passp_cache_notif_clear">Pulisci Cache</string>
|
||||
<string name="passp_cache_notif_pwd">Password</string>
|
||||
<!--unsorted-->
|
||||
<string name="internal_error">Errore interno!</string>
|
||||
<string name="msg_internal_error">Errore interno!</string>
|
||||
<string name="section_certifier_id">Certificatore</string>
|
||||
<string name="section_cert">Dettagli Certificato</string>
|
||||
<string name="label_user_id">Identit</string>
|
||||
|
@ -637,7 +637,7 @@
|
||||
<string name="passp_cache_notif_clear">キャッシュクリア</string>
|
||||
<string name="passp_cache_notif_pwd">パスワード</string>
|
||||
<!--unsorted-->
|
||||
<string name="internal_error">内部エラー!</string>
|
||||
<string name="msg_internal_error">内部エラー!</string>
|
||||
<string name="section_certifier_id">検証者</string>
|
||||
<string name="section_cert">証明の詳細</string>
|
||||
<string name="label_user_id">ユーザID</string>
|
||||
|
@ -601,7 +601,7 @@
|
||||
<string name="passp_cache_notif_clear">Очистити кеш</string>
|
||||
<string name="passp_cache_notif_pwd">Пароль</string>
|
||||
<!--unsorted-->
|
||||
<string name="internal_error">Внутрішня помилка!</string>
|
||||
<string name="msg_internal_error">Внутрішня помилка!</string>
|
||||
<string name="section_certifier_id">Ким підписаний</string>
|
||||
<string name="section_cert">Дані сертифікату</string>
|
||||
<string name="label_user_id">Сутність</string>
|
||||
|
@ -262,6 +262,7 @@
|
||||
<!-- progress dialogs, usually ending in '…' -->
|
||||
<string name="progress_done">Done.</string>
|
||||
<string name="progress_cancel">Cancel</string>
|
||||
<string name="progress_cancelling">cancelling…</string>
|
||||
<string name="progress_saving">saving…</string>
|
||||
<string name="progress_importing">importing…</string>
|
||||
<string name="progress_exporting">exporting…</string>
|
||||
@ -519,6 +520,9 @@
|
||||
|
||||
<!-- LogType log messages. Errors should have _ERROR_ in their name and end with a ! -->
|
||||
|
||||
<string name="msg_internal_error">Internal error!</string>
|
||||
<string name="msg_cancelled">Operation cancelled.</string>
|
||||
|
||||
<!-- Import Public log entries -->
|
||||
<string name="msg_ip_apply_batch">Applying insert batch operation.</string>
|
||||
<string name="msg_ip_bad_type_secret">Tried to import secret keyring as public. This is a bug, please file a report!</string>
|
||||
@ -744,7 +748,6 @@
|
||||
<string name="passp_cache_notif_pwd">Password</string>
|
||||
|
||||
<!-- unsorted -->
|
||||
<string name="internal_error">Internal error!</string>
|
||||
<string name="section_certifier_id">Certifier</string>
|
||||
<string name="section_cert">Certificate Details</string>
|
||||
<string name="label_user_id">Identity</string>
|
||||
|
Loading…
Reference in New Issue
Block a user