import-log: add OperationResults, use it in ImportKeys operation

This commit is contained in:
Vincent Breitmoser
2014-06-10 01:30:20 +02:00
parent 97c679ada3
commit 067ffa876d
6 changed files with 261 additions and 102 deletions

View File

@@ -174,14 +174,11 @@ public class KeychainIntentService extends IntentService
public static final String RESULT_DECRYPTED_BYTES = "decrypted_data";
public static final String RESULT_DECRYPT_VERIFY_RESULT = "signature";
// import
public static final String RESULT_IMPORT_ADDED = "added";
public static final String RESULT_IMPORT_UPDATED = "updated";
public static final String RESULT_IMPORT_BAD = "bad";
// export
public static final String RESULT_EXPORT = "exported";
public static final String RESULT = "result";
Messenger mMessenger;
private boolean mIsCanceled;
@@ -648,7 +645,10 @@ public class KeychainIntentService extends IntentService
List<ParcelableKeyRing> entries = data.getParcelableArrayList(IMPORT_KEY_LIST);
PgpImportExport pgpImportExport = new PgpImportExport(this, this);
Bundle resultData = pgpImportExport.importKeyRings(entries);
OperationResults.ImportResult result = pgpImportExport.importKeyRings(entries);
Bundle resultData = new Bundle();
resultData.putParcelable(RESULT, result);
sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, resultData);
} catch (Exception e) {

View File

@@ -0,0 +1,207 @@
package org.sufficientlysecure.keychain.service;
import android.os.Parcel;
import android.os.Parcelable;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.util.IterableIterator;
import java.util.ArrayList;
/** Represent the result of an operation.
*
* This class holds a result and the log of an operation. It can be subclassed
* to include typed additional information specific to the operation. To keep
* the class structure (somewhat) simple, this class contains an exhaustive
* list (ie, enum) of all possible log types, which should in all cases be tied
* to string resource ids.
*
*/
public class OperationResultParcel implements Parcelable {
/** Holds the overall result, the number specifying varying degrees of success.
* Values smaller than 100 are considered an overall success. */
final int mResult;
public static final int RESULT_OK = 0;
public static final int RESULT_ERROR = 100;
/// A list of log entries tied to the operation result.
final OperationLog mLog;
public OperationResultParcel(int result, OperationLog log) {
mResult = result;
mLog = log;
}
public OperationResultParcel(Parcel source) {
mResult = source.readInt();
mLog = new OperationLog();
mLog.addAll(source.createTypedArrayList(LogEntryParcel.CREATOR));
}
public int getResult() {
return mResult;
}
public boolean isSuccessful() {
return mResult < 100;
}
public OperationLog getLog() {
return mLog;
}
/** One entry in the log. */
public static class LogEntryParcel implements Parcelable {
public final LogLevel mLevel;
public final LogType mType;
public final String[] mParameters;
public final int mIndent;
public LogEntryParcel(LogLevel level, LogType type, String[] parameters, int indent) {
mLevel = level;
mType = type;
mParameters = parameters;
mIndent = indent;
}
public LogEntryParcel(LogLevel level, LogType type, String[] parameters) {
this(level, type, parameters, 0);
}
public LogEntryParcel(Parcel source) {
mLevel = LogLevel.values()[source.readInt()];
mType = LogType.values()[source.readInt()];
mParameters = source.createStringArray();
mIndent = source.readInt();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mLevel.ordinal());
dest.writeInt(mType.ordinal());
dest.writeStringArray(mParameters);
dest.writeInt(mIndent);
}
public static final Creator<LogEntryParcel> CREATOR = new Creator<LogEntryParcel>() {
public LogEntryParcel createFromParcel(final Parcel source) {
return new LogEntryParcel(source);
}
public LogEntryParcel[] newArray(final int size) {
return new LogEntryParcel[size];
}
};
}
public static enum LogType {
MSG_IP_APPLY_BATCH (R.string.msg_ip_apply_batch),
MSG_IP_BAD_TYPE_SECRET (R.string.msg_ip_bad_type_secret),
MSG_IP_DELETE_OLD_FAIL (R.string.msg_ip_delete_old_fail),
MSG_IP_DELETE_OLD_OK (R.string.msg_ip_delete_old_ok),
MSG_IP_ENCODE_FAIL (R.string.msg_ip_encode_fail),
MSG_IP_FAIL_IO_EXC (R.string.msg_ip_fail_io_exc),
MSG_IP_FAIL_OP_EX (R.string.msg_ip_fail_op_ex),
MSG_IP_FAIL_REMOTE_EX (R.string.msg_ip_fail_remote_ex),
MSG_IP_IMPORTING (R.string.msg_ip_importing),
MSG_IP_INSERT_KEYRING (R.string.msg_ip_insert_keyring),
MSG_IP_INSERT_SUBKEYS (R.string.msg_ip_insert_subkeys),
MSG_IP_PRESERVING_SECRET (R.string.msg_ip_preserving_secret),
MSG_IP_REINSERT_SECRET (R.string.msg_ip_reinsert_secret),
MSG_IP_SUBKEY (R.string.msg_ip_subkey),
MSG_IP_SUBKEY_EXPIRED (R.string.msg_ip_subkey_expired),
MSG_IP_SUBKEY_EXPIRES (R.string.msg_ip_subkey_expires),
MSG_IP_SUBKEY_FLAGS (R.string.msg_ip_subkey_flags),
MSG_IP_SUBKEY_FUTURE (R.string.msg_ip_subkey_future),
MSG_IP_SUCCESS (R.string.msg_ip_success),
MSG_IP_TRUST_RETRIEVE (R.string.msg_ip_trust_retrieve),
MSG_IP_TRUST_USING (R.string.msg_ip_trust_using),
MSG_IP_TRUST_USING_SEC (R.string.msg_ip_trust_using_sec),
MSG_IP_UID_CERT_BAD (R.string.msg_ip_uid_cert_bad),
MSG_IP_UID_CERT_ERROR (R.string.msg_ip_uid_cert_error),
MSG_IP_UID_CERT_GOOD (R.string.msg_ip_uid_cert_good),
MSG_IP_UID_CERTS_UNKNOWN (R.string.msg_ip_uid_certs_unknown),
MSG_IP_UID_CLASSIFYING (R.string.msg_ip_uid_classifying),
MSG_IP_UID_INSERT (R.string.msg_ip_uid_insert),
MSG_IP_UID_PROCESSING (R.string.msg_ip_uid_processing),
MSG_IP_UID_REVOKED (R.string.msg_ip_uid_revoked),
MSG_IP_UID_SELF_BAD (R.string.msg_ip_uid_self_bad),
MSG_IP_UID_SELF_GOOD (R.string.msg_ip_uid_self_good),
MSG_IP_UID_SELF_IGNORING_OLD (R.string.msg_ip_uid_self_ignoring_old),
MSG_IP_UID_SELF_NEWER (R.string.msg_ip_uid_self_newer),
MSG_IS_BAD_TYPE_PUBLIC (R.string.msg_is_bad_type_public),
MSG_IS_IMPORTING (R.string.msg_is_importing),
MSG_IS_IMPORTING_SUBKEYS (R.string.msg_is_importing_subkeys),
MSG_IS_IO_EXCPTION (R.string.msg_is_io_excption),
MSG_IS_SUBKEY_NONEXISTENT (R.string.msg_is_subkey_nonexistent),
MSG_IS_SUBKEY_OK (R.string.msg_is_subkey_ok),
MSG_IS_SUBKEY_STRIPPED (R.string.msg_is_subkey_stripped),
MSG_IS_SUCCESS (R.string.msg_is_success),
;
private final int mMsgId;
LogType(int msgId) {
mMsgId = msgId;
}
public int getMsgId() {
return mMsgId;
}
}
/** Enumeration of possible log levels. */
public static enum LogLevel {
OK,
DEBUG,
INFO,
WARN,
/** If any ERROR log entry is included in the result, the overall operation should have failed. */
ERROR,
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mResult);
dest.writeTypedList(mLog);
}
public static final Creator<OperationResultParcel> CREATOR = new Creator<OperationResultParcel>() {
public OperationResultParcel createFromParcel(final Parcel source) {
return new OperationResultParcel(source);
}
public OperationResultParcel[] newArray(final int size) {
return new OperationResultParcel[size];
}
};
public static class OperationLog extends ArrayList<LogEntryParcel> {
/// Simple convenience method
public void add(LogLevel level, LogType type, String[] parameters, int indent) {
add(new OperationResultParcel.LogEntryParcel(level, type, parameters, indent));
}
public boolean containsWarnings() {
int warn = LogLevel.WARN.ordinal();
for(LogEntryParcel entry : new IterableIterator<LogEntryParcel>(iterator())) {
if (entry.mLevel.ordinal() >= warn) {
return true;
}
}
return false;
}
}
}

View File

@@ -0,0 +1,63 @@
package org.sufficientlysecure.keychain.service;
import android.os.Parcel;
public abstract class OperationResults {
public static class ImportResult extends OperationResultParcel {
public final int mNewKeys, mUpdatedKeys, mBadKeys;
// Operation ok, at least one new key (no warnings)
public static final int RESULT_OK_NEWKEYS = 1;
// Operation ok, at least one new and one updated key (no warnings)
public static final int RESULT_OK_BOTHKEYS = 2;
// Operation ok, no new keys but upated ones (no warnings)
public static final int RESULT_OK_UPDATED = 3;
// Operation ok, but with warnings
public static final int RESULT_OK_WITH_WARNINGS = 4;
// Operation partially ok, but at least one key failed!
public static final int RESULT_PARTIAL_WITH_ERRORS = 50;
// Operation failed, errors thrown and no new keys imported
public static final int RESULT_FAIL_ERROR = 100;
// Operation failed, no keys to import...
public static final int RESULT_FAIL_NOTHING = 101;
public ImportResult(Parcel source) {
super(source);
mNewKeys = source.readInt();
mUpdatedKeys = source.readInt();
mBadKeys = source.readInt();
}
public ImportResult(int result, OperationLog log,
int newKeys, int updatedKeys, int badKeys) {
super(result, log);
mNewKeys = newKeys;
mUpdatedKeys = updatedKeys;
mBadKeys = badKeys;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(mNewKeys);
dest.writeInt(mUpdatedKeys);
dest.writeInt(mBadKeys);
}
public static Creator<ImportResult> CREATOR = new Creator<ImportResult>() {
public ImportResult createFromParcel(final Parcel source) {
return new ImportResult(source);
}
public ImportResult[] newArray(final int size) {
return new ImportResult[size];
}
};
}
}