aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Breitmoser <valodim@mugenguild.com>2016-05-11 16:10:53 +0200
committerVincent Breitmoser <valodim@mugenguild.com>2016-05-11 16:17:01 +0200
commit48758cdec5b7b42e02afc25bea13fe00c3c5e66b (patch)
tree008fafa09f05d857a5a67d02f5880d08cc6761d6
parentb362668f8144f07b2bd388ccae4d52dca1590396 (diff)
downloadopen-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.
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java64
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java7
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/InputData.java2
-rw-r--r--OpenKeychain/src/main/res/values/strings.xml3
4 files changed, 36 insertions, 40 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;
diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml
index 2a44307f8..30ed49f97 100644
--- a/OpenKeychain/src/main/res/values/strings.xml
+++ b/OpenKeychain/src/main/res/values/strings.xml
@@ -457,7 +457,8 @@
<string name="progress_extracting_key">"extracting key…"</string>
<string name="progress_preparing_streams">"preparing streams…"</string>
<string name="progress_encrypting">"encrypting data…"</string>
- <string name="progress_decrypting">"decrypting data…"</string>
+ <string name="progress_prepare_decryption">"Starting decryption…"</string>
+ <string name="progress_decrypting">"Decrypting data…"</string>
<string name="progress_preparing_signature">"preparing signature…"</string>
<string name="progress_processing_signature">processing signature…</string>
<string name="progress_generating_signature">"generating signature…"</string>