aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations
diff options
context:
space:
mode:
authorVincent Breitmoser <valodim@mugenguild.com>2015-09-14 16:21:04 +0200
committerVincent Breitmoser <valodim@mugenguild.com>2015-09-14 16:21:04 +0200
commit3814ae7d53a22ba89f1e39d7a4661016f76cf8c8 (patch)
treed83d41d3c424a784da144515665fb41ef650aa52 /OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations
parentdbaf7070ead596f5c70ad48fc55aada2f77a856a (diff)
parentd5dd6a49c8156a699b3fbbbeef06658e1c232c16 (diff)
downloadopen-keychain-3814ae7d53a22ba89f1e39d7a4661016f76cf8c8.tar.gz
open-keychain-3814ae7d53a22ba89f1e39d7a4661016f76cf8c8.tar.bz2
open-keychain-3814ae7d53a22ba89f1e39d7a4661016f76cf8c8.zip
Merge branch 'master' into mime4j
Conflicts: OpenKeychain/build.gradle OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java OpenKeychain/src/main/res/values/strings.xml
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ExportOperation.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportOperation.java153
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/RevokeOperation.java52
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/LinkedVerifyResult.java49
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java117
6 files changed, 219 insertions, 158 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ExportOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ExportOperation.java
index a5b70a41f..531ac01f2 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ExportOperation.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ExportOperation.java
@@ -145,6 +145,8 @@ public class ExportOperation extends BaseOperation<ExportKeyringParcel> {
return new ExportResult(ExportResult.RESULT_ERROR, log);
}
+ log.add(LogType.MSG_EXPORT_FILE_NAME, 1, outputFile);
+
// check if storage is ready
if (!FileHelper.isStorageMounted(outputFile)) {
log.add(LogType.MSG_EXPORT_ERROR_STORAGE, 1);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportOperation.java
index 4acfd6e30..89575338f 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportOperation.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportOperation.java
@@ -22,9 +22,8 @@ package org.sufficientlysecure.keychain.operations;
import java.io.IOException;
import java.net.Proxy;
import java.util.ArrayList;
-import java.util.HashSet;
+import java.util.GregorianCalendar;
import java.util.Iterator;
-import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
@@ -99,29 +98,9 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
return serialKeyRingImport(entries, num, keyServerUri, mProgressable, proxy);
}
- public ImportKeyResult serialKeyRingImport(List<ParcelableKeyRing> entries,
- String keyServerUri, Proxy proxy) {
-
- Iterator<ParcelableKeyRing> it = entries.iterator();
- int numEntries = entries.size();
-
- return serialKeyRingImport(it, numEntries, keyServerUri, mProgressable, proxy);
-
- }
-
- public ImportKeyResult serialKeyRingImport(List<ParcelableKeyRing> entries, String keyServerUri,
- Progressable progressable, Proxy proxy) {
-
- Iterator<ParcelableKeyRing> it = entries.iterator();
- int numEntries = entries.size();
-
- return serialKeyRingImport(it, numEntries, keyServerUri, progressable, proxy);
-
- }
-
@NonNull
- public ImportKeyResult serialKeyRingImport(ParcelableFileCache<ParcelableKeyRing> cache,
- String keyServerUri, Proxy proxy) {
+ private ImportKeyResult serialKeyRingImport(ParcelableFileCache<ParcelableKeyRing> cache,
+ String keyServerUri, Proxy proxy) {
// get entries from cached file
try {
@@ -143,7 +122,7 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
/**
* Since the introduction of multithreaded import, we expect calling functions to handle the
- * key sync i,eContactSyncAdapterService.requestSync()
+ * contact-to-key sync i.e ContactSyncAdapterService.requestSync()
*
* @param entries keys to import
* @param num number of keys to import
@@ -152,9 +131,9 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
* progress of a single key being imported
*/
@NonNull
- public ImportKeyResult serialKeyRingImport(Iterator<ParcelableKeyRing> entries, int num,
- String keyServerUri, Progressable progressable,
- Proxy proxy) {
+ private ImportKeyResult serialKeyRingImport(Iterator<ParcelableKeyRing> entries, int num,
+ String keyServerUri, Progressable progressable,
+ Proxy proxy) {
if (progressable != null) {
progressable.setProgress(R.string.progress_importing, 0, 100);
}
@@ -231,8 +210,8 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
log.add(LogType.MSG_IMPORT_FETCH_ERROR_DECODE, 3);
}
} catch (Keyserver.QueryFailedException e) {
- Log.e(Constants.TAG, "query failed", e);
- log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER_ERROR, 3, e.getMessage());
+ Log.d(Constants.TAG, "query failed", e);
+ log.add(LogType.MSG_IMPORT_FETCH_ERROR_KEYSERVER, 3, e.getMessage());
}
}
@@ -264,7 +243,7 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
} catch (Keyserver.QueryFailedException e) {
// download failed, too bad. just proceed
Log.e(Constants.TAG, "query failed", e);
- log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER_ERROR, 3, e.getMessage());
+ log.add(LogType.MSG_IMPORT_FETCH_ERROR_KEYSERVER, 3, e.getMessage());
}
}
}
@@ -275,15 +254,11 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
continue;
}
- // If we have an expected fingerprint, make sure it matches
- if (entry.mExpectedFingerprint != null) {
- if (!key.containsSubkey(entry.mExpectedFingerprint)) {
- log.add(LogType.MSG_IMPORT_FINGERPRINT_ERROR, 2);
- badKeys += 1;
- continue;
- } else {
- log.add(LogType.MSG_IMPORT_FINGERPRINT_OK, 2);
- }
+ // never import secret keys from keyserver!
+ if (entry.mBytes == null && key.isSecret()) {
+ log.add(LogType.MSG_IMPORT_FETCH_ERROR_KEYSERVER_SECRET, 2);
+ badKeys += 1;
+ continue;
}
// Another check if we have been cancelled
@@ -293,31 +268,44 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
}
SaveKeyringResult result;
- mProviderHelper.clearLog();
- if (key.isSecret()) {
- result = mProviderHelper.saveSecretKeyRing(key,
- new ProgressScaler(progressable, (int) (position * progSteps),
- (int) ((position + 1) * progSteps), 100));
- } else {
- result = mProviderHelper.savePublicKeyRing(key,
- new ProgressScaler(progressable, (int) (position * progSteps),
- (int) ((position + 1) * progSteps), 100));
+ // synchronizing prevents https://github.com/open-keychain/open-keychain/issues/1221
+ // and https://github.com/open-keychain/open-keychain/issues/1480
+ synchronized (mProviderHelper) {
+ mProviderHelper.clearLog();
+ if (key.isSecret()) {
+ result = mProviderHelper.saveSecretKeyRing(key,
+ new ProgressScaler(progressable, (int) (position * progSteps),
+ (int) ((position + 1) * progSteps), 100));
+ } else {
+ result = mProviderHelper.savePublicKeyRing(key,
+ new ProgressScaler(progressable, (int) (position * progSteps),
+ (int) ((position + 1) * progSteps), 100), entry.mExpectedFingerprint);
+ }
}
if (!result.success()) {
badKeys += 1;
- } else if (result.updated()) {
- updatedKeys += 1;
- importedMasterKeyIds.add(key.getMasterKeyId());
} else {
- newKeys += 1;
- if (key.isSecret()) {
- secret += 1;
+ if (result.updated()) {
+ updatedKeys += 1;
+ importedMasterKeyIds.add(key.getMasterKeyId());
+ } else {
+ newKeys += 1;
+ if (key.isSecret()) {
+ secret += 1;
+ }
+ importedMasterKeyIds.add(key.getMasterKeyId());
+ }
+ if (entry.mBytes == null) {
+ // synonymous to isDownloadFromKeyserver.
+ // If no byte data was supplied, import from keyserver took place
+ // this prevents file imports being noted as keyserver imports
+ mProviderHelper.renewKeyLastUpdatedTime(key.getMasterKeyId(),
+ GregorianCalendar.getInstance().getTimeInMillis(),
+ TimeUnit.MILLISECONDS);
}
- importedMasterKeyIds.add(key.getMasterKeyId());
}
log.add(result, 2);
-
} catch (IOException | PgpGeneralException e) {
Log.e(Constants.TAG, "Encountered bad key on import!", e);
++badKeys;
@@ -327,9 +315,15 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
}
// Special: consolidate on secret key import (cannot be cancelled!)
+ // synchronized on mProviderHelper to prevent
+ // https://github.com/open-keychain/open-keychain/issues/1221 since a consolidate deletes
+ // and re-inserts keys, which could conflict with a parallel db key update
if (secret > 0) {
setPreventCancel();
- ConsolidateResult result = mProviderHelper.consolidateDatabaseStep1(progressable);
+ ConsolidateResult result;
+ synchronized (mProviderHelper) {
+ result = mProviderHelper.consolidateDatabaseStep1(progressable);
+ }
log.add(result, 1);
}
@@ -386,7 +380,7 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
@NonNull
@Override
- public OperationResult execute(ImportKeyringParcel importInput, CryptoInputParcel cryptoInput) {
+ public ImportKeyResult execute(ImportKeyringParcel importInput, CryptoInputParcel cryptoInput) {
ArrayList<ParcelableKeyRing> keyList = importInput.mKeyList;
String keyServer = importInput.mKeyserver;
@@ -411,20 +405,8 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
} else {
proxy = cryptoInput.getParcelableProxy().getProxy();
}
- // if there is more than one key with the same fingerprint, we do a serial import to
- // prevent
- // https://github.com/open-keychain/open-keychain/issues/1221
- HashSet<String> keyFingerprintSet = new HashSet<>();
- for (int i = 0; i < keyList.size(); i++) {
- keyFingerprintSet.add(keyList.get(i).mExpectedFingerprint);
- }
- if (keyFingerprintSet.size() == keyList.size()) {
- // all keys have unique fingerprints
- result = multiThreadedKeyImport(keyList.iterator(), keyList.size(), keyServer,
- proxy);
- } else {
- result = serialKeyRingImport(keyList, keyServer, proxy);
- }
+
+ result = multiThreadedKeyImport(keyList.iterator(), keyList.size(), keyServer, proxy);
}
ContactSyncAdapterService.requestSync();
@@ -462,7 +444,8 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
ArrayList<ParcelableKeyRing> list = new ArrayList<>();
list.add(pkRing);
- return serialKeyRingImport(list, keyServer, ignoreProgressable, proxy);
+ return serialKeyRingImport(list.iterator(), 1, keyServer,
+ ignoreProgressable, proxy);
}
};
@@ -486,18 +469,18 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
}
return accumulator.getConsolidatedResult();
}
- return null; // TODO: Decide if we should just crash instead of returning null
+ return new ImportKeyResult(ImportKeyResult.RESULT_FAIL_NOTHING, new OperationLog());
}
/**
* Used to accumulate the results of individual key imports
*/
- private class KeyImportAccumulator {
+ public static class KeyImportAccumulator {
private OperationResult.OperationLog mImportLog = new OperationResult.OperationLog();
Progressable mProgressable;
private int mTotalKeys;
private int mImportedKeys = 0;
- ArrayList<Long> mImportedMasterKeyIds = new ArrayList<Long>();
+ ArrayList<Long> mImportedMasterKeyIds = new ArrayList<>();
private int mBadKeys = 0;
private int mNewKeys = 0;
private int mUpdatedKeys = 0;
@@ -515,21 +498,17 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
public KeyImportAccumulator(int totalKeys, Progressable externalProgressable) {
mTotalKeys = totalKeys;
mProgressable = externalProgressable;
- mProgressable.setProgress(0, totalKeys);
- }
-
- public int getTotalKeys() {
- return mTotalKeys;
- }
-
- public int getImportedKeys() {
- return mImportedKeys;
+ if (mProgressable != null) {
+ mProgressable.setProgress(0, totalKeys);
+ }
}
public synchronized void accumulateKeyImport(ImportKeyResult result) {
mImportedKeys++;
- mProgressable.setProgress(mImportedKeys, mTotalKeys);
+ if (mProgressable != null) {
+ mProgressable.setProgress(mImportedKeys, mTotalKeys);
+ }
mImportLog.addAll(result.getLog().toList());//accumulates log
mBadKeys += result.mBadKeys;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java
index 30f37dd4f..8f1abde83 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java
@@ -43,7 +43,7 @@ import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
import org.sufficientlysecure.keychain.operations.results.KeybaseVerificationResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult;
-import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
+import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyOperation;
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel;
import org.sufficientlysecure.keychain.pgp.Progressable;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
@@ -141,7 +141,7 @@ public class KeybaseVerificationOperation extends BaseOperation<KeybaseVerificat
}
}
- PgpDecryptVerify op = new PgpDecryptVerify(mContext, mProviderHelper, mProgressable);
+ PgpDecryptVerifyOperation op = new PgpDecryptVerifyOperation(mContext, mProviderHelper, mProgressable);
PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(messageBytes)
.setSignedLiteralData(true)
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/RevokeOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/RevokeOperation.java
index ecf64e1af..975cf541a 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/RevokeOperation.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/RevokeOperation.java
@@ -20,7 +20,6 @@
package org.sufficientlysecure.keychain.operations;
import android.content.Context;
-import android.database.Cursor;
import android.net.Uri;
import android.support.annotation.NonNull;
@@ -39,7 +38,7 @@ 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 class RevokeOperation extends BaseOperation<RevokeKeyringParcel> {
public RevokeOperation(Context context, ProviderHelper providerHelper, Progressable progressable) {
super(context, providerHelper, progressable);
@@ -71,13 +70,15 @@ public class RevokeOperation extends BaseOperation<RevokeKeyringParcel> {
return new RevokeResult(RevokeResult.RESULT_ERROR, log, masterKeyId);
}
- SaveKeyringParcel saveKeyringParcel = getRevokedSaveKeyringParcel(masterKeyId,
- keyRing.getFingerprint());
+ SaveKeyringParcel saveKeyringParcel =
+ new SaveKeyringParcel(masterKeyId, keyRing.getFingerprint());
// all revoke operations are made atomic as of now
saveKeyringParcel.setUpdateOptions(revokeKeyringParcel.mUpload, true,
revokeKeyringParcel.mKeyserver);
+ saveKeyringParcel.mRevokeSubKeys.add(masterKeyId);
+
InputPendingResult revokeAndUploadResult = new EditKeyOperation(mContext,
mProviderHelper, mProgressable, mCancelled)
.execute(saveKeyringParcel, cryptoInputParcel);
@@ -92,54 +93,15 @@ public class RevokeOperation extends BaseOperation<RevokeKeyringParcel> {
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);
+ log.add(OperationResult.LogType.MSG_REVOKE_ERROR_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);
+ log.add(OperationResult.LogType.MSG_REVOKE_ERROR_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;
- }
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/LinkedVerifyResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/LinkedVerifyResult.java
new file mode 100644
index 000000000..42e9ec3f0
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/LinkedVerifyResult.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.operations.results;
+
+import android.os.Parcel;
+
+public class LinkedVerifyResult extends OperationResult {
+
+ public LinkedVerifyResult(int result, OperationLog log) {
+ super(result, log);
+ }
+
+ /** Construct from a parcel - trivial because we have no extra data. */
+ public LinkedVerifyResult(Parcel source) {
+ super(source);
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ }
+
+ public static Creator<LinkedVerifyResult> CREATOR = new Creator<LinkedVerifyResult>() {
+ public LinkedVerifyResult createFromParcel(final Parcel source) {
+ return new LinkedVerifyResult(source);
+ }
+
+ public LinkedVerifyResult[] newArray(final int size) {
+ return new LinkedVerifyResult[size];
+ }
+ };
+
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java
index 3c15a2e7b..3856209b3 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java
@@ -20,6 +20,7 @@ package org.sufficientlysecure.keychain.operations.results;
import android.app.Activity;
import android.content.Intent;
+import android.content.res.Resources;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
@@ -52,6 +53,8 @@ import java.util.List;
*/
public abstract class OperationResult implements Parcelable {
+ final static String INDENTATION_WHITESPACE = " ";
+
public static final String EXTRA_RESULT = "operation_result";
/**
@@ -166,6 +169,27 @@ public abstract class OperationResult implements Parcelable {
", mIndent=" + mIndent +
'}';
}
+
+ StringBuilder getPrintableLogEntry(Resources resources, int indent) {
+
+ StringBuilder result = new StringBuilder();
+ int padding = mIndent +indent;
+ if (padding > INDENTATION_WHITESPACE.length()) {
+ padding = INDENTATION_WHITESPACE.length();
+ }
+ result.append(INDENTATION_WHITESPACE, 0, padding);
+ result.append(LOG_LEVEL_NAME[mType.mLevel.ordinal()]).append(' ');
+
+ // special case: first parameter may be a quantity
+ if (mParameters != null && mParameters.length > 0 && mParameters[0] instanceof Integer) {
+ result.append(resources.getQuantityString(mType.getMsgId(), (Integer) mParameters[0], mParameters));
+ } else {
+ result.append(resources.getString(mType.getMsgId(), mParameters));
+ }
+
+ return result;
+ }
+
}
public static class SubLogEntryParcel extends LogEntryParcel {
@@ -202,6 +226,17 @@ public abstract class OperationResult implements Parcelable {
dest.writeParcelable(mSubResult, 0);
}
+ @Override
+ StringBuilder getPrintableLogEntry(Resources resources, int indent) {
+
+ LogEntryParcel subEntry = mSubResult.getLog().getLast();
+ if (subEntry != null) {
+ return subEntry.getPrintableLogEntry(resources, mIndent +indent);
+ } else {
+ return super.getPrintableLogEntry(resources, indent);
+ }
+ }
+
}
public Showable createNotify(final Activity activity) {
@@ -245,15 +280,15 @@ public abstract class OperationResult implements Parcelable {
}
return Notify.create(activity, logText, Notify.LENGTH_LONG, style,
- new ActionListener() {
- @Override
- public void onAction() {
- Intent intent = new Intent(
- activity, LogDisplayActivity.class);
- intent.putExtra(LogDisplayFragment.EXTRA_RESULT, OperationResult.this);
- activity.startActivity(intent);
- }
- }, R.string.snackbar_details);
+ new ActionListener() {
+ @Override
+ public void onAction() {
+ Intent intent = new Intent(
+ activity, LogDisplayActivity.class);
+ intent.putExtra(LogDisplayFragment.EXTRA_RESULT, OperationResult.this);
+ activity.startActivity(intent);
+ }
+ }, R.string.snackbar_details);
}
@@ -289,6 +324,8 @@ public abstract class OperationResult implements Parcelable {
MSG_IP_ERROR_IO_EXC (LogLevel.ERROR, R.string.msg_ip_error_io_exc),
MSG_IP_ERROR_OP_EXC (LogLevel.ERROR, R.string.msg_ip_error_op_exc),
MSG_IP_ERROR_REMOTE_EX (LogLevel.ERROR, R.string.msg_ip_error_remote_ex),
+ MSG_IP_FINGERPRINT_ERROR (LogLevel.ERROR, R.string.msg_ip_fingerprint_error),
+ MSG_IP_FINGERPRINT_OK (LogLevel.INFO, R.string.msg_ip_fingerprint_ok),
MSG_IP_INSERT_KEYRING (LogLevel.DEBUG, R.string.msg_ip_insert_keyring),
MSG_IP_INSERT_SUBKEYS (LogLevel.DEBUG, R.string.msg_ip_insert_keys),
MSG_IP_PREPARE (LogLevel.DEBUG, R.string.msg_ip_prepare),
@@ -631,6 +668,7 @@ public abstract class OperationResult implements Parcelable {
MSG_DC_TRAIL_SYM (LogLevel.DEBUG, R.string.msg_dc_trail_sym),
MSG_DC_TRAIL_UNKNOWN (LogLevel.DEBUG, R.string.msg_dc_trail_unknown),
MSG_DC_UNLOCKING (LogLevel.INFO, R.string.msg_dc_unlocking),
+ MSG_DC_INSECURE_ENCRYPTION_KEY (LogLevel.WARN, R.string.msg_dc_insecure_encryption_key),
MSG_DC_INSECURE_SYMMETRIC_ENCRYPTION_ALGO(LogLevel.WARN, R.string.msg_dc_insecure_symmetric_encryption_algo),
MSG_DC_INSECURE_HASH_ALGO(LogLevel.ERROR, R.string.msg_dc_insecure_hash_algo),
MSG_DC_INSECURE_MDC_MISSING(LogLevel.ERROR, R.string.msg_dc_insecure_mdc_missing),
@@ -704,21 +742,21 @@ public abstract class OperationResult implements Parcelable {
MSG_IMPORT_FETCH_ERROR (LogLevel.ERROR, R.string.msg_import_fetch_error),
MSG_IMPORT_FETCH_ERROR_DECODE (LogLevel.ERROR, R.string.msg_import_fetch_error_decode),
+ MSG_IMPORT_FETCH_ERROR_KEYSERVER(LogLevel.ERROR, R.string.msg_import_fetch_error_keyserver),
+ MSG_IMPORT_FETCH_ERROR_KEYSERVER_SECRET (LogLevel.ERROR, R.string.msg_import_fetch_error_keyserver_secret),
+ MSG_IMPORT_FETCH_KEYBASE (LogLevel.INFO, R.string.msg_import_fetch_keybase),
MSG_IMPORT_FETCH_KEYSERVER (LogLevel.INFO, R.string.msg_import_fetch_keyserver),
MSG_IMPORT_FETCH_KEYSERVER_OK (LogLevel.DEBUG, R.string.msg_import_fetch_keyserver_ok),
- MSG_IMPORT_FETCH_KEYSERVER_ERROR (LogLevel.ERROR, R.string.msg_import_fetch_keyserver_error),
- MSG_IMPORT_FETCH_KEYBASE (LogLevel.INFO, R.string.msg_import_fetch_keybase),
MSG_IMPORT_KEYSERVER (LogLevel.DEBUG, R.string.msg_import_keyserver),
MSG_IMPORT_MERGE (LogLevel.DEBUG, R.string.msg_import_merge),
MSG_IMPORT_MERGE_ERROR (LogLevel.ERROR, R.string.msg_import_merge_error),
- MSG_IMPORT_FINGERPRINT_ERROR (LogLevel.ERROR, R.string.msg_import_fingerprint_error),
- MSG_IMPORT_FINGERPRINT_OK (LogLevel.DEBUG, R.string.msg_import_fingerprint_ok),
MSG_IMPORT_ERROR (LogLevel.ERROR, R.string.msg_import_error),
MSG_IMPORT_ERROR_IO (LogLevel.ERROR, R.string.msg_import_error_io),
MSG_IMPORT_PARTIAL (LogLevel.ERROR, R.string.msg_import_partial),
MSG_IMPORT_SUCCESS (LogLevel.OK, R.string.msg_import_success),
MSG_EXPORT (LogLevel.START, R.plurals.msg_export),
+ MSG_EXPORT_FILE_NAME (LogLevel.INFO, R.string.msg_export_file_name),
MSG_EXPORT_UPLOAD_PUBLIC (LogLevel.START, R.string.msg_export_upload_public),
MSG_EXPORT_PUBLIC (LogLevel.DEBUG, R.string.msg_export_public),
MSG_EXPORT_SECRET (LogLevel.DEBUG, R.string.msg_export_secret),
@@ -763,10 +801,9 @@ public abstract class OperationResult implements Parcelable {
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_ERROR_NOT_FOUND (LogLevel.ERROR, R.string.msg_revoke_error_not_found),
MSG_REVOKE (LogLevel.DEBUG, R.string.msg_revoke_key),
- MSG_REVOKE_KEY_FAIL (LogLevel.ERROR, R.string.msg_revoke_key_fail),
+ MSG_REVOKE_ERROR_KEY_FAIL (LogLevel.ERROR, R.string.msg_revoke_key_fail),
MSG_REVOKE_OK (LogLevel.OK, R.string.msg_revoke_ok),
// keybase verification
@@ -781,17 +818,31 @@ public abstract class OperationResult implements Parcelable {
MSG_KEYBASE_ERROR_PAYLOAD_MISMATCH(LogLevel.ERROR,
R.string.msg_keybase_error_msg_payload_mismatch),
- // export log
- MSG_EXPORT_LOG(LogLevel.START,R.string.msg_export_log_start),
- MSG_EXPORT_LOG_EXPORT_ERROR_NO_FILE(LogLevel.ERROR,R.string.msg_export_log_error_no_file),
- MSG_EXPORT_LOG_EXPORT_ERROR_FOPEN(LogLevel.ERROR,R.string.msg_export_log_error_fopen),
- MSG_EXPORT_LOG_EXPORT_ERROR_WRITING(LogLevel.ERROR,R.string.msg_export_log_error_writing),
- MSG_EXPORT_LOG_EXPORT_SUCCESS (LogLevel.OK, R.string.msg_export_log_success),
-
- // mim parsing
+ // mime parsing
MSG_MIME_PARSING(LogLevel.START,R.string.msg_mime_parsing_start),
MSG_MIME_PARSING_ERROR(LogLevel.ERROR,R.string.msg_mime_parsing_error),
MSG_MIME_PARSING_SUCCESS(LogLevel.OK,R.string.msg_mime_parsing_success),
+
+ MSG_LV (LogLevel.START, R.string.msg_lv),
+ MSG_LV_MATCH (LogLevel.DEBUG, R.string.msg_lv_match),
+ MSG_LV_MATCH_ERROR (LogLevel.ERROR, R.string.msg_lv_match_error),
+ MSG_LV_FP_OK (LogLevel.DEBUG, R.string.msg_lv_fp_ok),
+ MSG_LV_FP_ERROR (LogLevel.ERROR, R.string.msg_lv_fp_error),
+
+ MSG_LV_ERROR_TWITTER_AUTH (LogLevel.ERROR, R.string.msg_lv_error_twitter_auth),
+ MSG_LV_ERROR_TWITTER_HANDLE (LogLevel.ERROR, R.string.msg_lv_error_twitter_handle),
+ MSG_LV_ERROR_TWITTER_RESPONSE (LogLevel.ERROR, R.string.msg_lv_error_twitter_response),
+ MSG_LV_ERROR_GITHUB_HANDLE (LogLevel.ERROR, R.string.msg_lv_error_github_handle),
+ MSG_LV_ERROR_GITHUB_NOT_FOUND (LogLevel.ERROR, R.string.msg_lv_error_github_not_found),
+
+ MSG_LV_FETCH (LogLevel.DEBUG, R.string.msg_lv_fetch),
+ MSG_LV_FETCH_REDIR (LogLevel.DEBUG, R.string.msg_lv_fetch_redir),
+ MSG_LV_FETCH_OK (LogLevel.DEBUG, R.string.msg_lv_fetch_ok),
+ MSG_LV_FETCH_ERROR (LogLevel.ERROR, R.string.msg_lv_fetch_error),
+ MSG_LV_FETCH_ERROR_URL (LogLevel.ERROR, R.string.msg_lv_fetch_error_url),
+ MSG_LV_FETCH_ERROR_IO (LogLevel.ERROR, R.string.msg_lv_fetch_error_io),
+ MSG_LV_FETCH_ERROR_FORMAT(LogLevel.ERROR, R.string.msg_lv_fetch_error_format),
+ MSG_LV_FETCH_ERROR_NOTHING (LogLevel.ERROR, R.string.msg_lv_fetch_error_nothing),
;
public final int mMsgId;
@@ -815,6 +866,10 @@ public abstract class OperationResult implements Parcelable {
OK, // should occur once at the end of a successful operation
CANCELLED, // should occur once at the end of a cancelled operation
}
+ // for print of debug log. keep those in sync with above!
+ static final String[] LOG_LEVEL_NAME = new String[] {
+ "[DEBUG]", "[INFO]", "[WARN]", "[ERROR]", "[START]", "[OK]", "[CANCEL]"
+ };
@Override
public int describeContents() {
@@ -913,6 +968,20 @@ public abstract class OperationResult implements Parcelable {
public Iterator<LogEntryParcel> iterator() {
return mParcels.iterator();
}
+
+ /**
+ * returns an indented String of an entire OperationLog
+ * @param indent padding to add at the start of all log entries, made for use with SubLogs
+ * @return printable, indented version of passed operationLog
+ */
+ public String getPrintableOperationLog(Resources resources, int indent) {
+ StringBuilder log = new StringBuilder();
+ for (LogEntryParcel entry : this) {
+ log.append(entry.getPrintableLogEntry(resources, indent)).append("\n");
+ }
+ return log.toString().substring(0, log.length() -1); // get rid of extra new line
+ }
+
}
}