diff options
author | Vincent Breitmoser <valodim@mugenguild.com> | 2015-09-14 16:21:04 +0200 |
---|---|---|
committer | Vincent Breitmoser <valodim@mugenguild.com> | 2015-09-14 16:21:04 +0200 |
commit | 3814ae7d53a22ba89f1e39d7a4661016f76cf8c8 (patch) | |
tree | d83d41d3c424a784da144515665fb41ef650aa52 /OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations | |
parent | dbaf7070ead596f5c70ad48fc55aada2f77a856a (diff) | |
parent | d5dd6a49c8156a699b3fbbbeef06658e1c232c16 (diff) | |
download | open-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')
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 + } + } } |