implemented revocation on deletion
This commit is contained in:
@@ -18,19 +18,29 @@
|
||||
package org.sufficientlysecure.keychain.operations;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.operations.results.ConsolidateResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.DeleteResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.InputPendingResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
|
||||
import org.sufficientlysecure.keychain.pgp.Progressable;
|
||||
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
|
||||
import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData;
|
||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||
import org.sufficientlysecure.keychain.service.ContactSyncAdapterService;
|
||||
import org.sufficientlysecure.keychain.service.DeleteKeyringParcel;
|
||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
|
||||
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
|
||||
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
|
||||
/** An operation which implements a high level keyring delete operation.
|
||||
*
|
||||
@@ -48,12 +58,17 @@ public class DeleteOperation extends BaseOperation<DeleteKeyringParcel> {
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public DeleteResult execute(DeleteKeyringParcel deleteKeyringParcel,
|
||||
public OperationResult execute(DeleteKeyringParcel deleteKeyringParcel,
|
||||
CryptoInputParcel cryptoInputParcel) {
|
||||
|
||||
long[] masterKeyIds = deleteKeyringParcel.mMasterKeyIds;
|
||||
boolean isSecret = deleteKeyringParcel.mIsSecret;
|
||||
|
||||
return onlyDeleteKey(masterKeyIds, isSecret);
|
||||
}
|
||||
|
||||
private DeleteResult onlyDeleteKey(long[] masterKeyIds, boolean isSecret) {
|
||||
|
||||
OperationLog log = new OperationLog();
|
||||
|
||||
if (masterKeyIds.length == 0) {
|
||||
@@ -113,7 +128,6 @@ public class DeleteOperation extends BaseOperation<DeleteKeyringParcel> {
|
||||
}
|
||||
|
||||
return new DeleteResult(result, log, success, fail);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,7 +21,10 @@ import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.keyimport.HkpKeyserver;
|
||||
import org.sufficientlysecure.keychain.operations.results.EditKeyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.ExportResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.InputPendingResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
|
||||
@@ -34,6 +37,7 @@ import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
|
||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||
import org.sufficientlysecure.keychain.provider.ProviderHelper.NotFoundException;
|
||||
import org.sufficientlysecure.keychain.service.ContactSyncAdapterService;
|
||||
import org.sufficientlysecure.keychain.service.ExportKeyringParcel;
|
||||
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
|
||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
|
||||
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||
@@ -58,8 +62,16 @@ public class EditKeyOperation extends BaseOperation<SaveKeyringParcel> {
|
||||
super(context, providerHelper, progressable, cancelled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves an edited key, and uploads it to a server atomically or otherwise as
|
||||
* specified in saveParcel
|
||||
*
|
||||
* @param saveParcel primary input to the operation
|
||||
* @param cryptoInput input that changes if user interaction is required
|
||||
* @return the result of the operation
|
||||
*/
|
||||
@NonNull
|
||||
public OperationResult execute(SaveKeyringParcel saveParcel, CryptoInputParcel cryptoInput) {
|
||||
public InputPendingResult execute(SaveKeyringParcel saveParcel, CryptoInputParcel cryptoInput) {
|
||||
|
||||
OperationLog log = new OperationLog();
|
||||
log.add(LogType.MSG_ED, 0);
|
||||
@@ -120,6 +132,24 @@ public class EditKeyOperation extends BaseOperation<SaveKeyringParcel> {
|
||||
// It's a success, so this must be non-null now
|
||||
UncachedKeyRing ring = modifyResult.getRing();
|
||||
|
||||
if (saveParcel.isUpload()) {
|
||||
ExportKeyringParcel exportKeyringParcel =
|
||||
new ExportKeyringParcel(saveParcel.getUploadKeyserver(), ring);
|
||||
ExportResult uploadResult =
|
||||
new ExportOperation(mContext, mProviderHelper, mProgressable)
|
||||
.execute(exportKeyringParcel, cryptoInput);
|
||||
if (uploadResult.isPending()) {
|
||||
return uploadResult;
|
||||
} else if (!uploadResult.success() && saveParcel.isUploadAtomic()) {
|
||||
// if atomic, update fail implies edit operation should also fail and not save
|
||||
log.add(uploadResult, 2);
|
||||
return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, saveParcel.mMasterKeyId);
|
||||
} else {
|
||||
// upload succeeded or not atomic so we continue
|
||||
log.add(uploadResult, 2);
|
||||
}
|
||||
}
|
||||
|
||||
// Save the new keyring.
|
||||
SaveKeyringResult saveResult = mProviderHelper
|
||||
.saveSecretKeyRing(ring, new ProgressScaler(mProgressable, 60, 95, 100));
|
||||
@@ -160,5 +190,4 @@ public class EditKeyOperation extends BaseOperation<SaveKeyringParcel> {
|
||||
return new EditKeyResult(EditKeyResult.RESULT_OK, log, ring.getMasterKeyId());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import org.spongycastle.bcpg.ArmoredOutputStream;
|
||||
@@ -42,6 +43,7 @@ import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.keyimport.HkpKeyserver;
|
||||
import org.sufficientlysecure.keychain.keyimport.Keyserver.AddKeyException;
|
||||
import org.sufficientlysecure.keychain.operations.results.ExportResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.InputPendingResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
|
||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing;
|
||||
@@ -128,6 +130,18 @@ public class ExportOperation extends BaseOperation<ExportKeyringParcel> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns null if no user input required for upload, an InputPendingResult otherwise
|
||||
*/
|
||||
@Nullable
|
||||
public InputPendingResult getUploadPendingInput() {
|
||||
if (!OrbotHelper.isOrbotInRequiredState(mContext)) {
|
||||
return new ExportResult(null,
|
||||
RequiredInputParcel.createOrbotRequiredOperation());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ExportResult exportToFile(long[] masterKeyIds, boolean exportSecret, String outputFile) {
|
||||
|
||||
OperationLog log = new OperationLog();
|
||||
@@ -351,10 +365,15 @@ public class ExportOperation extends BaseOperation<ExportKeyringParcel> {
|
||||
|
||||
HkpKeyserver hkpKeyserver = new HkpKeyserver(exportInput.mKeyserver);
|
||||
try {
|
||||
CanonicalizedPublicKeyRing keyring
|
||||
= mProviderHelper.getCanonicalizedPublicKeyRing(
|
||||
exportInput.mCanonicalizedPublicKeyringUri);
|
||||
return uploadKeyRingToServer(hkpKeyserver, keyring, proxy);
|
||||
if (exportInput.mCanonicalizedPublicKeyringUri != null) {
|
||||
CanonicalizedPublicKeyRing keyring
|
||||
= mProviderHelper.getCanonicalizedPublicKeyRing(
|
||||
exportInput.mCanonicalizedPublicKeyringUri);
|
||||
return uploadKeyRingToServer(hkpKeyserver, keyring, proxy);
|
||||
} else {
|
||||
return uploadKeyRingToServer(hkpKeyserver, exportInput.mUncachedKeyRing,
|
||||
proxy);
|
||||
}
|
||||
} catch (ProviderHelper.NotFoundException e) {
|
||||
Log.e(Constants.TAG, "error uploading key", e);
|
||||
return new ExportResult(ExportResult.RESULT_ERROR, new OperationLog());
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
package org.sufficientlysecure.keychain.operations;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.operations.results.DeleteResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.InputPendingResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.RevokeResult;
|
||||
import org.sufficientlysecure.keychain.pgp.Progressable;
|
||||
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
|
||||
import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||
import org.sufficientlysecure.keychain.service.RevokeKeyringParcel;
|
||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
|
||||
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
|
||||
public class RevokeOperation extends BaseOperation<RevokeKeyringParcel> {
|
||||
|
||||
public RevokeOperation(Context context, ProviderHelper providerHelper, Progressable progressable) {
|
||||
super(context, providerHelper, progressable);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public OperationResult execute(RevokeKeyringParcel revokeKeyringParcel,
|
||||
CryptoInputParcel cryptoInputParcel) {
|
||||
|
||||
long masterKeyId = revokeKeyringParcel.mMasterKeyId;
|
||||
|
||||
OperationResult.OperationLog log = new OperationResult.OperationLog();
|
||||
log.add(OperationResult.LogType.MSG_REVOKE, 0,
|
||||
KeyFormattingUtils.beautifyKeyId(masterKeyId));
|
||||
|
||||
try {
|
||||
|
||||
Uri secretUri = KeychainContract.KeyRings.buildUnifiedKeyRingUri(masterKeyId);
|
||||
CachedPublicKeyRing keyRing = mProviderHelper.getCachedPublicKeyRing(secretUri);
|
||||
|
||||
// check if this is a master secret key we can work with
|
||||
switch (keyRing.getSecretKeyType(masterKeyId)) {
|
||||
case GNU_DUMMY:
|
||||
log.add(OperationResult.LogType.MSG_EK_ERROR_DUMMY, 1);
|
||||
return new RevokeResult(RevokeResult.RESULT_ERROR, log, masterKeyId);
|
||||
}
|
||||
|
||||
SaveKeyringParcel saveKeyringParcel = getRevokedSaveKeyringParcel(masterKeyId,
|
||||
keyRing.getFingerprint());
|
||||
|
||||
// all revoke operations are made atomic as of now
|
||||
saveKeyringParcel.setUpdateOptions(revokeKeyringParcel.mUpload, true,
|
||||
revokeKeyringParcel.mKeyserver);
|
||||
|
||||
InputPendingResult revokeAndUploadResult = new EditKeyOperation(mContext,
|
||||
mProviderHelper, mProgressable, mCancelled)
|
||||
.execute(saveKeyringParcel, cryptoInputParcel);
|
||||
|
||||
if (revokeAndUploadResult.isPending()) {
|
||||
return revokeAndUploadResult;
|
||||
}
|
||||
|
||||
log.add(revokeAndUploadResult, 1);
|
||||
|
||||
if (revokeAndUploadResult.success()) {
|
||||
log.add(OperationResult.LogType.MSG_REVOKE_OK, 1);
|
||||
return new RevokeResult(RevokeResult.RESULT_OK, log, masterKeyId);
|
||||
} else {
|
||||
log.add(OperationResult.LogType.MSG_REVOKE_KEY_FAIL, 1);
|
||||
return new RevokeResult(RevokeResult.RESULT_ERROR, log, masterKeyId);
|
||||
}
|
||||
|
||||
} catch (PgpKeyNotFoundException | ProviderHelper.NotFoundException e) {
|
||||
Log.e(Constants.TAG, "could not find key to revoke", e);
|
||||
log.add(OperationResult.LogType.MSG_REVOKE_KEY_FAIL, 1);
|
||||
return new RevokeResult(RevokeResult.RESULT_ERROR, log, masterKeyId);
|
||||
}
|
||||
}
|
||||
|
||||
private SaveKeyringParcel getRevokedSaveKeyringParcel(long masterKeyId, byte[] fingerprint) {
|
||||
final String[] SUBKEYS_PROJECTION = new String[]{
|
||||
KeychainContract.Keys.KEY_ID
|
||||
};
|
||||
final int INDEX_KEY_ID = 0;
|
||||
|
||||
Uri keysUri = KeychainContract.Keys.buildKeysUri(masterKeyId);
|
||||
Cursor subKeyCursor =
|
||||
mContext.getContentResolver().query(keysUri, SUBKEYS_PROJECTION, null, null, null);
|
||||
|
||||
SaveKeyringParcel saveKeyringParcel =
|
||||
new SaveKeyringParcel(masterKeyId, fingerprint);
|
||||
|
||||
// add all subkeys, for revocation
|
||||
while (subKeyCursor != null && subKeyCursor.moveToNext()) {
|
||||
saveKeyringParcel.mRevokeSubKeys.add(subKeyCursor.getLong(INDEX_KEY_ID));
|
||||
}
|
||||
if (subKeyCursor != null) {
|
||||
subKeyCursor.close();
|
||||
}
|
||||
|
||||
final String[] USER_IDS_PROJECTION = new String[]{
|
||||
KeychainContract.UserPackets.USER_ID
|
||||
};
|
||||
final int INDEX_USER_ID = 0;
|
||||
|
||||
Uri userIdsUri = KeychainContract.UserPackets.buildUserIdsUri(masterKeyId);
|
||||
Cursor userIdCursor = mContext.getContentResolver().query(
|
||||
userIdsUri, USER_IDS_PROJECTION, null, null, null);
|
||||
|
||||
while (userIdCursor != null && userIdCursor.moveToNext()) {
|
||||
saveKeyringParcel.mRevokeUserIds.add(userIdCursor.getString(INDEX_USER_ID));
|
||||
}
|
||||
if (userIdCursor != null) {
|
||||
userIdCursor.close();
|
||||
}
|
||||
|
||||
return saveKeyringParcel;
|
||||
}
|
||||
}
|
||||
@@ -21,8 +21,10 @@ package org.sufficientlysecure.keychain.operations.results;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Parcel;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
|
||||
import org.sufficientlysecure.keychain.ui.LogDisplayActivity;
|
||||
import org.sufficientlysecure.keychain.ui.LogDisplayFragment;
|
||||
import org.sufficientlysecure.keychain.ui.util.Notify;
|
||||
@@ -30,7 +32,7 @@ import org.sufficientlysecure.keychain.ui.util.Notify.ActionListener;
|
||||
import org.sufficientlysecure.keychain.ui.util.Notify.Showable;
|
||||
import org.sufficientlysecure.keychain.ui.util.Notify.Style;
|
||||
|
||||
public class DeleteResult extends OperationResult {
|
||||
public class DeleteResult extends InputPendingResult {
|
||||
|
||||
final public int mOk, mFail;
|
||||
|
||||
@@ -40,6 +42,18 @@ public class DeleteResult extends OperationResult {
|
||||
mFail = fail;
|
||||
}
|
||||
|
||||
/**
|
||||
* used when more input is required
|
||||
* @param log operation log upto point of required input, if any
|
||||
* @param requiredInput represents input required
|
||||
*/
|
||||
public DeleteResult(@Nullable OperationLog log, RequiredInputParcel requiredInput) {
|
||||
super(log, requiredInput);
|
||||
// values are not to be used
|
||||
mOk = -1;
|
||||
mFail = -1;
|
||||
}
|
||||
|
||||
/** Construct from a parcel - trivial because we have no extra data. */
|
||||
public DeleteResult(Parcel source) {
|
||||
super(source);
|
||||
|
||||
@@ -20,7 +20,7 @@ package org.sufficientlysecure.keychain.operations.results;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
public class EditKeyResult extends OperationResult {
|
||||
public class EditKeyResult extends InputPendingResult {
|
||||
|
||||
public final Long mMasterKeyId;
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.util.ArrayList;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
|
||||
|
||||
public class InputPendingResult extends OperationResult {
|
||||
@@ -30,26 +31,33 @@ public class InputPendingResult extends OperationResult {
|
||||
public static final int RESULT_PENDING = RESULT_ERROR + 8;
|
||||
|
||||
final RequiredInputParcel mRequiredInput;
|
||||
// in case operation needs to add to/changes the cryptoInputParcel sent to it
|
||||
final CryptoInputParcel mCryptoInputParcel;
|
||||
|
||||
public InputPendingResult(int result, OperationLog log) {
|
||||
super(result, log);
|
||||
mRequiredInput = null;
|
||||
mCryptoInputParcel = null;
|
||||
}
|
||||
|
||||
public InputPendingResult(OperationLog log, RequiredInputParcel requiredInput) {
|
||||
public InputPendingResult(OperationLog log, RequiredInputParcel requiredInput,
|
||||
CryptoInputParcel cryptoInputParcel) {
|
||||
super(RESULT_PENDING, log);
|
||||
mRequiredInput = requiredInput;
|
||||
mCryptoInputParcel = cryptoInputParcel;
|
||||
}
|
||||
|
||||
public InputPendingResult(Parcel source) {
|
||||
super(source);
|
||||
mRequiredInput = source.readParcelable(getClass().getClassLoader());
|
||||
mCryptoInputParcel = source.readParcelable(getClass().getClassLoader());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
super.writeToParcel(dest, flags);
|
||||
dest.writeParcelable(mRequiredInput, 0);
|
||||
dest.writeParcelable(mCryptoInputParcel, 0);
|
||||
}
|
||||
|
||||
public boolean isPending() {
|
||||
|
||||
@@ -760,6 +760,13 @@ public abstract class OperationResult implements Parcelable {
|
||||
MSG_DEL_OK (LogLevel.OK, R.plurals.msg_del_ok),
|
||||
MSG_DEL_FAIL (LogLevel.WARN, R.plurals.msg_del_fail),
|
||||
|
||||
MSG_REVOKE_ERROR_EMPTY (LogLevel.ERROR, R.string.msg_revoke_error_empty),
|
||||
MSG_REVOKE_ERROR_MULTI_SECRET (LogLevel.DEBUG, R.string.msg_revoke_error_multi_secret),
|
||||
MSG_REVOKE_ERROR_NOT_FOUND (LogLevel.DEBUG, R.string.msg_revoke_error_multi_secret),
|
||||
MSG_REVOKE (LogLevel.DEBUG, R.string.msg_revoke_key),
|
||||
MSG_REVOKE_KEY_FAIL (LogLevel.WARN, R.string.msg_revoke_key_fail),
|
||||
MSG_REVOKE_OK (LogLevel.OK, R.string.msg_revoke_ok),
|
||||
|
||||
// keybase verification
|
||||
MSG_KEYBASE_VERIFICATION(LogLevel.START, R.string.msg_keybase_verification),
|
||||
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
package org.sufficientlysecure.keychain.operations.results;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
|
||||
import org.sufficientlysecure.keychain.ui.LogDisplayActivity;
|
||||
import org.sufficientlysecure.keychain.ui.LogDisplayFragment;
|
||||
import org.sufficientlysecure.keychain.ui.util.Notify;
|
||||
|
||||
public class RevokeResult extends InputPendingResult {
|
||||
|
||||
public final long mMasterKeyId;
|
||||
|
||||
public RevokeResult(int result, OperationLog log, long masterKeyId) {
|
||||
super(result, log);
|
||||
mMasterKeyId = masterKeyId;
|
||||
}
|
||||
|
||||
/**
|
||||
* used when more input is required
|
||||
* @param log operation log upto point of required input, if any
|
||||
* @param requiredInput represents input required
|
||||
*/
|
||||
public RevokeResult(@Nullable OperationLog log, RequiredInputParcel requiredInput) {
|
||||
super(log, requiredInput);
|
||||
// we won't use these values
|
||||
mMasterKeyId = -1;
|
||||
}
|
||||
|
||||
/** Construct from a parcel - trivial because we have no extra data. */
|
||||
public RevokeResult(Parcel source) {
|
||||
super(source);
|
||||
mMasterKeyId = source.readLong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
super.writeToParcel(dest, flags);
|
||||
dest.writeLong(mMasterKeyId);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<RevokeResult> CREATOR = new Parcelable.Creator<RevokeResult>() {
|
||||
@Override
|
||||
public RevokeResult createFromParcel(Parcel in) {
|
||||
return new RevokeResult(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RevokeResult[] newArray(int size) {
|
||||
return new RevokeResult[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public Notify.Showable createNotify(final Activity activity) {
|
||||
|
||||
int resultType = getResult();
|
||||
|
||||
String str;
|
||||
int duration;
|
||||
Notify.Style style;
|
||||
|
||||
// Not an overall failure
|
||||
if ((resultType & OperationResult.RESULT_ERROR) == 0) {
|
||||
|
||||
duration = Notify.LENGTH_LONG;
|
||||
|
||||
// New and updated keys
|
||||
if (resultType == OperationResult.RESULT_OK) {
|
||||
style = Notify.Style.OK;
|
||||
str = activity.getString(R.string.revoke_ok);
|
||||
} else {
|
||||
duration = 0;
|
||||
style = Notify.Style.ERROR;
|
||||
str = "internal error";
|
||||
}
|
||||
|
||||
} else {
|
||||
duration = 0;
|
||||
style = Notify.Style.ERROR;
|
||||
str = activity.getString(R.string.revoke_fail);
|
||||
}
|
||||
|
||||
return Notify.create(activity, str, duration, style, new Notify.ActionListener() {
|
||||
@Override
|
||||
public void onAction() {
|
||||
Intent intent = new Intent(
|
||||
activity, LogDisplayActivity.class);
|
||||
intent.putExtra(LogDisplayFragment.EXTRA_RESULT, RevokeResult.this);
|
||||
activity.startActivity(intent);
|
||||
}
|
||||
}, R.string.snackbar_details);
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user