diff options
author | Vincent Breitmoser <valodim@mugenguild.com> | 2016-05-11 16:10:53 +0200 |
---|---|---|
committer | Vincent Breitmoser <valodim@mugenguild.com> | 2016-05-11 16:17:01 +0200 |
commit | 48758cdec5b7b42e02afc25bea13fe00c3c5e66b (patch) | |
tree | 008fafa09f05d857a5a67d02f5880d08cc6761d6 /OpenKeychain/src/main/java/org/sufficientlysecure | |
parent | b362668f8144f07b2bd388ccae4d52dca1590396 (diff) | |
download | open-keychain-48758cdec5b7b42e02afc25bea13fe00c3c5e66b.tar.gz open-keychain-48758cdec5b7b42e02afc25bea13fe00c3c5e66b.tar.bz2 open-keychain-48758cdec5b7b42e02afc25bea13fe00c3c5e66b.zip |
update progress handling in PgpDecryptVerifyOperation
- less progress messages overall
- report progress again based on input stream position, if filesize is known
- limit progress messages to one every 200ms while decrypting
- also fixed a bug in DecryptListFragment, the recycler view now reuses
old views as intended instead of crossfading all the time.
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure')
3 files changed, 34 insertions, 39 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java index a27e4a8d5..e0d71bd1e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java @@ -84,6 +84,8 @@ import org.sufficientlysecure.keychain.util.ProgressScaler; public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInputParcel> { + public static final int PROGRESS_STRIDE_MILLISECONDS = 200; + public PgpDecryptVerifyOperation(Context context, ProviderHelper providerHelper, Progressable progressable) { super(context, providerHelper, progressable); } @@ -153,10 +155,10 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp return verifyDetachedSignature(input, inputData, outputStream, 0); } else { // automatically works with PGP ascii armor and PGP binary - InputStream in = PGPUtil.getDecoderStream(inputData.getInputStream()); + InputStream inputStream = PGPUtil.getDecoderStream(inputData.getInputStream()); - if (in instanceof ArmoredInputStream) { - ArmoredInputStream aIn = (ArmoredInputStream) in; + if (inputStream instanceof ArmoredInputStream) { + ArmoredInputStream aIn = (ArmoredInputStream) inputStream; // it is ascii armored Log.d(Constants.TAG, "ASCII Armor Header Line: " + aIn.getArmorHeaderLine()); @@ -165,10 +167,10 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp return verifyCleartextSignature(aIn, outputStream, 0); } else { // else: ascii armored encryption! go on... - return decryptVerify(input, cryptoInput, in, outputStream, 0); + return decryptVerify(input, cryptoInput, inputData, inputStream, outputStream, 0); } } else { - return decryptVerify(input, cryptoInput, in, outputStream, 0); + return decryptVerify(input, cryptoInput, inputData, inputStream, outputStream, 0); } } } catch (PGPException e) { @@ -272,15 +274,14 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp @NonNull private DecryptVerifyResult decryptVerify( PgpDecryptVerifyInputParcel input, CryptoInputParcel cryptoInput, - InputStream in, OutputStream out, int indent) throws IOException, PGPException { + InputData inputData, InputStream in, OutputStream out, int indent) throws IOException, PGPException { OperationLog log = new OperationLog(); log.add(LogType.MSG_DC, indent); indent += 1; - int currentProgress = 0; - updateProgress(R.string.progress_reading_data, currentProgress, 100); + updateProgress(R.string.progress_reading_data, 0, 100); // parse ASCII Armor headers ArmorHeaders armorHeaders = parseArmorHeaders(in, log, indent); @@ -301,8 +302,7 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp if (obj instanceof PGPEncryptedDataList) { esResult = handleEncryptedPacket( - input, cryptoInput, (PGPEncryptedDataList) obj, log, indent, - currentProgress, useBackupCode); + input, cryptoInput, (PGPEncryptedDataList) obj, log, indent, useBackupCode); // if there is an error, nothing left to do here if (esResult.errorResult != null) { @@ -346,8 +346,6 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp // resolve compressed data if (dataChunk instanceof PGPCompressedData) { log.add(LogType.MSG_DC_CLEAR_DECOMPRESS, indent + 1); - currentProgress += 2; - updateProgress(R.string.progress_decompressing_data, currentProgress, 100); PGPCompressedData compressedData = (PGPCompressedData) dataChunk; @@ -377,8 +375,6 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp log.add(LogType.MSG_DC_CLEAR_DATA, indent + 1); indent += 2; - currentProgress += 4; - updateProgress(R.string.progress_decrypting, currentProgress, 100); PGPLiteralData literalData = (PGPLiteralData) dataChunk; @@ -436,20 +432,22 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp return result; } - ProgressScaler progressScaler = - new ProgressScaler(mProgressable, currentProgress, 95, 100); - InputStream dataIn = literalData.getInputStream(); long opTime, startTime = System.currentTimeMillis(); long alreadyWritten = 0; - long wholeSize = 0; // TODO inputData.getSize() - inputData.getStreamPosition(); + long wholeSize = inputData.getSize() - inputData.getStreamPosition(); + boolean sizeIsKnown = inputData.getSize() != InputData.UNKNOWN_FILESIZE && wholeSize > 0; int length; byte[] buffer = new byte[8192]; byte[] firstBytes = new byte[48]; CharsetVerifier charsetVerifier = new CharsetVerifier(buffer, mimeType, charset); + updateProgress(R.string.progress_decrypting, 1, 100); + + long nextProgressTime = 0L; + int lastReportedProgress = 1; while ((length = dataIn.read(buffer)) > 0) { // Log.d(Constants.TAG, "read bytes: " + length); if (out != null) { @@ -467,14 +465,17 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp } alreadyWritten += length; - // noinspection ConstantConditions, TODO progress - if (wholeSize > 0) { - long progress = 100 * alreadyWritten / wholeSize; + if (sizeIsKnown && nextProgressTime < System.currentTimeMillis()) { + long progress = 100 * inputData.getStreamPosition() / wholeSize; // stop at 100% for wrong file sizes... if (progress > 100) { progress = 100; } - progressScaler.setProgress((int) progress, 100); + if (progress > lastReportedProgress) { + updateProgress((int) progress, 100); + lastReportedProgress = (int) progress; + nextProgressTime = System.currentTimeMillis() + PROGRESS_STRIDE_MILLISECONDS; + } } } @@ -490,7 +491,8 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp } opTime = System.currentTimeMillis()-startTime; - Log.d(Constants.TAG, "decrypt time taken: " + String.format("%.2f", opTime / 1000.0) + "s"); + Log.d(Constants.TAG, "decrypt time taken: " + String.format("%.2f", opTime / 1000.0) + "s, for " + + alreadyWritten + " bytes"); // special treatment to detect pgp mime types // TODO move into CharsetVerifier? seems like that would be a plausible place for this logic @@ -513,8 +515,6 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp if (esResult != null) { if (esResult.encryptedData.isIntegrityProtected()) { - updateProgress(R.string.progress_verifying_integrity, 95, 100); - if (esResult.encryptedData.verify()) { log.add(LogType.MSG_DC_INTEGRITY_CHECK_OK, indent); } else { @@ -548,7 +548,7 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp } private EncryptStreamResult handleEncryptedPacket(PgpDecryptVerifyInputParcel input, CryptoInputParcel cryptoInput, - PGPEncryptedDataList enc, OperationLog log, int indent, int currentProgress, boolean useBackupCode) throws PGPException { + PGPEncryptedDataList enc, OperationLog log, int indent, boolean useBackupCode) throws PGPException { EncryptStreamResult result = new EncryptStreamResult(); @@ -574,9 +574,6 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp if (obj instanceof PGPPublicKeyEncryptedData) { anyPacketFound = true; - currentProgress += 2; - updateProgress(R.string.progress_finding_key, currentProgress, 100); - PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) obj; long subKeyId = encData.getKeyID(); @@ -741,9 +738,6 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp // we made sure above one of these two would be true if (symmetricPacketFound) { - currentProgress += 2; - updateProgress(R.string.progress_preparing_streams, currentProgress, 100); - PGPDigestCalculatorProvider digestCalcProvider = new JcaPGPDigestCalculatorProviderBuilder() .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(); PBEDataDecryptorFactory decryptorFactory = new JcePBEDataDecryptorFactoryBuilder( @@ -764,9 +758,6 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp result.symmetricEncryptionAlgo = encryptedDataSymmetric.getSymmetricAlgorithm(decryptorFactory); } else if (asymmetricPacketFound) { - currentProgress += 2; - updateProgress(R.string.progress_extracting_key, currentProgress, 100); - CachingDataDecryptorFactory decryptorFactory; if (decryptedSessionKeyAvailable) { decryptorFactory = cachedKeyDecryptorFactory; @@ -782,9 +773,6 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp return result.with(new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log)); } - currentProgress += 2; - updateProgress(R.string.progress_preparing_streams, currentProgress, 100); - decryptorFactory = decryptionKey.getCachingDecryptorFactory(cryptoInput); // special case: if the decryptor does not have a session key cached for this encrypted diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java index 6f85342d6..79bf55d79 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java @@ -169,7 +169,12 @@ public class DecryptListFragment vFilesList.setHasFixedSize(true); // TODO make this a grid, for tablets! vFilesList.setLayoutManager(new LinearLayoutManager(getActivity())); - vFilesList.setItemAnimator(new DefaultItemAnimator()); + vFilesList.setItemAnimator(new DefaultItemAnimator() { + @Override + public boolean canReuseUpdatedViewHolder(@NonNull RecyclerView.ViewHolder viewHolder) { + return true; + } + }); mAdapter = new DecryptFilesAdapter(); vFilesList.setAdapter(mAdapter); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/InputData.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/InputData.java index 1f73dcb28..10d13632e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/InputData.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/InputData.java @@ -23,6 +23,8 @@ import java.io.InputStream; * Wrapper to include size besides an InputStream */ public class InputData { + public static final int UNKNOWN_FILESIZE = -1; + private PositionAwareInputStream mInputStream; private long mSize; String mOriginalFilename; |