mirror of
https://github.com/moparisthebest/k-9
synced 2024-11-30 05:02:26 -05:00
move crypto data into an annotation structure, and fix pgp/inline
note that we currently lack proper confirmation about whether data was actually decrypted or not, so for now we always assume it wasn't
This commit is contained in:
parent
4bec165fdc
commit
dc8fd39c7e
@ -83,7 +83,7 @@ public class MessageDecryptVerifier {
|
||||
String mimeType = part.getMimeType();
|
||||
Body body = part.getBody();
|
||||
|
||||
if (TEXT_PLAIN.equals(mimeType)) {
|
||||
if (TEXT_PLAIN.equalsIgnoreCase(mimeType)) {
|
||||
String text = MessageExtractor.getTextFromPart(part);
|
||||
switch (OpenPgpUtils.parseMessage(text)) {
|
||||
case OpenPgpUtils.PARSE_RESULT_MESSAGE:
|
||||
@ -120,6 +120,12 @@ public class MessageDecryptVerifier {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Note: This method should ONLY be used to differentiate parts
|
||||
// already filtered with the methods above!
|
||||
public static boolean isPgpInlinePart(Part part) {
|
||||
return TEXT_PLAIN.equals(part.getMimeType());
|
||||
}
|
||||
|
||||
public static boolean isPgpMimePart(Part part) {
|
||||
return isPgpMimeSignedPart(part) || isPgpMimeEncryptedPart(part);
|
||||
}
|
||||
|
@ -35,15 +35,15 @@ import org.apache.james.mime4j.stream.Field;
|
||||
import org.apache.james.mime4j.stream.MimeConfig;
|
||||
import org.apache.james.mime4j.util.MimeUtil;
|
||||
|
||||
|
||||
// TODO rename this class? this class doesn't really bear any 'decrypted' semantics anymore...
|
||||
public class DecryptStreamParser {
|
||||
|
||||
private static final String DECRYPTED_CACHE_DIRECTORY = "decrypted";
|
||||
|
||||
public static OpenPgpResultBodyPart parse(Context context, InputStream inputStream) throws MessagingException, IOException {
|
||||
public static MimeBodyPart parse(Context context, InputStream inputStream) throws MessagingException, IOException {
|
||||
File decryptedTempDirectory = getDecryptedTempDirectory(context);
|
||||
|
||||
OpenPgpResultBodyPart decryptedRootPart = new OpenPgpResultBodyPart(true);
|
||||
MimeBodyPart decryptedRootPart = new MimeBodyPart();
|
||||
|
||||
MimeConfig parserConfig = new MimeConfig();
|
||||
parserConfig.setMaxHeaderLen(-1);
|
||||
@ -111,10 +111,10 @@ public class DecryptStreamParser {
|
||||
|
||||
private static class PartBuilder implements ContentHandler {
|
||||
private final File decryptedTempDirectory;
|
||||
private final OpenPgpResultBodyPart decryptedRootPart;
|
||||
private final MimeBodyPart decryptedRootPart;
|
||||
private final Stack<Object> stack = new Stack<Object>();
|
||||
|
||||
public PartBuilder(File decryptedTempDirectory, OpenPgpResultBodyPart decryptedRootPart)
|
||||
public PartBuilder(File decryptedTempDirectory, MimeBodyPart decryptedRootPart)
|
||||
throws MessagingException {
|
||||
this.decryptedTempDirectory = decryptedTempDirectory;
|
||||
this.decryptedRootPart = decryptedRootPart;
|
||||
|
@ -6,7 +6,6 @@ import android.net.Uri;
|
||||
|
||||
import com.fsck.k9.R;
|
||||
import com.fsck.k9.crypto.DecryptedTempFileBody;
|
||||
import com.fsck.k9.crypto.MessageDecryptVerifier;
|
||||
import com.fsck.k9.mail.Address;
|
||||
import com.fsck.k9.mail.Body;
|
||||
import com.fsck.k9.mail.BodyPart;
|
||||
@ -22,6 +21,7 @@ import com.fsck.k9.mail.internet.Viewable;
|
||||
import com.fsck.k9.mailstore.MessageViewInfo.MessageViewContainer;
|
||||
import com.fsck.k9.provider.AttachmentProvider;
|
||||
import com.fsck.k9.provider.K9FileProvider;
|
||||
import com.fsck.k9.ui.messageview.MessageCryptoHelper.MessageCryptoAnnotations;
|
||||
import org.openintents.openpgp.OpenPgpError;
|
||||
import org.openintents.openpgp.OpenPgpSignatureResult;
|
||||
|
||||
@ -45,7 +45,7 @@ public class LocalMessageExtractor {
|
||||
private static final int FILENAME_PREFIX_LENGTH = FILENAME_PREFIX.length();
|
||||
private static final String FILENAME_SUFFIX = " ";
|
||||
private static final int FILENAME_SUFFIX_LENGTH = FILENAME_SUFFIX.length();
|
||||
private static final OpenPgpResultBodyPart NO_SIGNATURE_RESULT = null;
|
||||
private static final OpenPgpResultAnnotation NO_ANNOTATIONS = null;
|
||||
|
||||
private LocalMessageExtractor() {}
|
||||
/**
|
||||
@ -424,14 +424,22 @@ public class LocalMessageExtractor {
|
||||
html.append("</td></tr>");
|
||||
}
|
||||
|
||||
public static MessageViewInfo decodeMessageForView(Context context, Message message) throws MessagingException {
|
||||
public static MessageViewInfo decodeMessageForView(Context context,
|
||||
Message message, MessageCryptoAnnotations annotations) throws MessagingException {
|
||||
|
||||
// 1. break mime structure on encryption/signature boundaries
|
||||
List<Part> parts = getCryptPieces(message);
|
||||
List<Part> parts = getCryptPieces(message, annotations);
|
||||
|
||||
// 2. extract viewables/attachments of parts
|
||||
ArrayList<MessageViewContainer> containers = new ArrayList<MessageViewContainer>();
|
||||
for (Part part : parts) {
|
||||
OpenPgpResultAnnotation pgpAnnotation = annotations.get(part);
|
||||
|
||||
// TODO properly handle decrypted data part - this just replaces the part
|
||||
if (pgpAnnotation != NO_ANNOTATIONS && pgpAnnotation.hasOutputData()) {
|
||||
part = pgpAnnotation.getOutputData();
|
||||
}
|
||||
|
||||
ArrayList<Part> attachments = new ArrayList<Part>();
|
||||
List<Viewable> viewables = MessageExtractor.getViewables(part, attachments);
|
||||
|
||||
@ -440,12 +448,11 @@ public class LocalMessageExtractor {
|
||||
attachments);
|
||||
List<AttachmentViewInfo> attachmentInfos = extractAttachmentInfos(context, attachments);
|
||||
|
||||
OpenPgpResultBodyPart resultBodyPart = getSignatureResultForPart(part);
|
||||
if (resultBodyPart != NO_SIGNATURE_RESULT) {
|
||||
OpenPgpSignatureResult pgpResult = resultBodyPart.getSignatureResult();
|
||||
OpenPgpError pgpError = resultBodyPart.getError();
|
||||
boolean wasEncrypted = resultBodyPart.wasEncrypted();
|
||||
PendingIntent pendingIntent = resultBodyPart.getPendingIntent();
|
||||
if (pgpAnnotation != NO_ANNOTATIONS) {
|
||||
OpenPgpSignatureResult pgpResult = pgpAnnotation.getSignatureResult();
|
||||
OpenPgpError pgpError = pgpAnnotation.getError();
|
||||
boolean wasEncrypted = pgpAnnotation.wasEncrypted();
|
||||
PendingIntent pendingIntent = pgpAnnotation.getPendingIntent();
|
||||
|
||||
containers.add(new MessageViewContainer(
|
||||
viewable.html, attachmentInfos, pgpResult, pgpError, wasEncrypted, pendingIntent));
|
||||
@ -458,7 +465,7 @@ public class LocalMessageExtractor {
|
||||
return new MessageViewInfo(containers, message);
|
||||
}
|
||||
|
||||
public static List<Part> getCryptPieces(Part part) throws MessagingException {
|
||||
public static List<Part> getCryptPieces(Message message, MessageCryptoAnnotations annotations) throws MessagingException {
|
||||
|
||||
// TODO make sure this method does what it is supposed to
|
||||
/* This method returns a list of mime parts which are to be parsed into
|
||||
@ -470,14 +477,15 @@ public class LocalMessageExtractor {
|
||||
|
||||
|
||||
ArrayList<Part> parts = new ArrayList<Part>();
|
||||
if (!getCryptSubPieces(part, parts)) {
|
||||
parts.add(part);
|
||||
if (!getCryptSubPieces(message, parts, annotations)) {
|
||||
parts.add(message);
|
||||
}
|
||||
|
||||
return parts;
|
||||
}
|
||||
|
||||
public static boolean getCryptSubPieces(Part part, ArrayList<Part> parts) throws MessagingException {
|
||||
public static boolean getCryptSubPieces(Part part, ArrayList<Part> parts,
|
||||
MessageCryptoAnnotations annotations) throws MessagingException {
|
||||
|
||||
Body body = part.getBody();
|
||||
if (body instanceof Multipart) {
|
||||
@ -485,46 +493,20 @@ public class LocalMessageExtractor {
|
||||
if ("multipart/mixed".equals(part.getMimeType())) {
|
||||
boolean foundSome = false;
|
||||
for (BodyPart sub : multi.getBodyParts()) {
|
||||
foundSome |= getCryptSubPieces(sub, parts);
|
||||
foundSome |= getCryptSubPieces(sub, parts, annotations);
|
||||
}
|
||||
if (!foundSome) {
|
||||
parts.add(part);
|
||||
return true;
|
||||
}
|
||||
} else if (MessageDecryptVerifier.isPgpMimeSignedPart(part)) {
|
||||
} else if (annotations.has(part)) {
|
||||
parts.add(part);
|
||||
return true;
|
||||
} else if (isPgpMimeDecryptedPart(part)) {
|
||||
parts.add(multi.getBodyPart(2));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isPgpMimeDecryptedPart (Part part) {
|
||||
Body body = part.getBody();
|
||||
return (body instanceof Multipart)
|
||||
&& MessageDecryptVerifier.isPgpMimeEncryptedPart(part)
|
||||
&& ((Multipart) part.getBody()).getCount() == 3;
|
||||
}
|
||||
|
||||
private static OpenPgpResultBodyPart getSignatureResultForPart(Part part) {
|
||||
if (part instanceof OpenPgpResultBodyPart) {
|
||||
OpenPgpResultBodyPart openPgpResultBodyPart = (OpenPgpResultBodyPart) part;
|
||||
return openPgpResultBodyPart;
|
||||
}
|
||||
if (MessageDecryptVerifier.isPgpMimeSignedPart(part)) {
|
||||
Multipart multi = (Multipart) part.getBody();
|
||||
if (multi.getCount() == 3 && multi.getBodyPart(2) instanceof OpenPgpResultBodyPart) {
|
||||
OpenPgpResultBodyPart openPgpResultBodyPart = (OpenPgpResultBodyPart) multi.getBodyPart(2);
|
||||
return openPgpResultBodyPart;
|
||||
}
|
||||
}
|
||||
|
||||
return NO_SIGNATURE_RESULT;
|
||||
}
|
||||
|
||||
private static List<AttachmentViewInfo> extractAttachmentInfos(Context context, List<Part> attachmentParts)
|
||||
throws MessagingException {
|
||||
|
||||
|
@ -3,21 +3,17 @@ package com.fsck.k9.mailstore;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
|
||||
import com.fsck.k9.mail.MessagingException;
|
||||
import com.fsck.k9.mail.internet.MimeBodyPart;
|
||||
import org.openintents.openpgp.OpenPgpError;
|
||||
import org.openintents.openpgp.OpenPgpSignatureResult;
|
||||
|
||||
|
||||
public class OpenPgpResultAnnotation extends MimeBodyPart {
|
||||
public class OpenPgpResultAnnotation {
|
||||
private boolean wasEncrypted;
|
||||
private OpenPgpSignatureResult signatureResult;
|
||||
private OpenPgpError error;
|
||||
private PendingIntent pendingIntent;
|
||||
|
||||
public OpenPgpResultAnnotation(boolean wasEncrypted) throws MessagingException {
|
||||
this.wasEncrypted = wasEncrypted;
|
||||
}
|
||||
private MimeBodyPart outputData;
|
||||
|
||||
public OpenPgpSignatureResult getSignatureResult() {
|
||||
return signatureResult;
|
||||
@ -43,7 +39,24 @@ public class OpenPgpResultAnnotation extends MimeBodyPart {
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
public boolean hasOutputData() {
|
||||
return outputData != null;
|
||||
}
|
||||
|
||||
public void setOutputData(MimeBodyPart outputData) {
|
||||
this.outputData = outputData;
|
||||
}
|
||||
|
||||
public MimeBodyPart getOutputData() {
|
||||
return outputData;
|
||||
}
|
||||
|
||||
public boolean wasEncrypted() {
|
||||
return wasEncrypted;
|
||||
}
|
||||
|
||||
public void setWasEncrypted(boolean wasEncrypted) {
|
||||
this.wasEncrypted = wasEncrypted;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -9,15 +9,18 @@ import com.fsck.k9.K9;
|
||||
import com.fsck.k9.mail.Message;
|
||||
import com.fsck.k9.mailstore.LocalMessageExtractor;
|
||||
import com.fsck.k9.mailstore.MessageViewInfo;
|
||||
import com.fsck.k9.ui.messageview.MessageCryptoHelper.MessageCryptoAnnotations;
|
||||
|
||||
|
||||
public class DecodeMessageLoader extends AsyncTaskLoader<MessageViewInfo> {
|
||||
private final Message message;
|
||||
private MessageViewInfo messageViewInfo;
|
||||
private MessageCryptoAnnotations annotations;
|
||||
|
||||
public DecodeMessageLoader(Context context, Message message) {
|
||||
public DecodeMessageLoader(Context context, Message message, MessageCryptoAnnotations annotations) {
|
||||
super(context);
|
||||
this.message = message;
|
||||
this.annotations = annotations;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -40,7 +43,7 @@ public class DecodeMessageLoader extends AsyncTaskLoader<MessageViewInfo> {
|
||||
@Override
|
||||
public MessageViewInfo loadInBackground() {
|
||||
try {
|
||||
return LocalMessageExtractor.decodeMessageForView(getContext(), message);
|
||||
return LocalMessageExtractor.decodeMessageForView(getContext(), message, annotations);
|
||||
} catch (Exception e) {
|
||||
Log.e(K9.LOG_TAG, "Error while decoding message", e);
|
||||
return null;
|
||||
|
@ -1,11 +1,13 @@
|
||||
package com.fsck.k9.ui.messageview;
|
||||
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PipedInputStream;
|
||||
import java.io.PipedOutputStream;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
@ -30,9 +32,11 @@ import com.fsck.k9.mail.MessagingException;
|
||||
import com.fsck.k9.mail.Multipart;
|
||||
import com.fsck.k9.mail.Part;
|
||||
import com.fsck.k9.mail.internet.MessageExtractor;
|
||||
import com.fsck.k9.mail.internet.MimeBodyPart;
|
||||
import com.fsck.k9.mail.internet.TextBody;
|
||||
import com.fsck.k9.mailstore.DecryptStreamParser;
|
||||
import com.fsck.k9.mailstore.LocalMessage;
|
||||
import com.fsck.k9.mailstore.OpenPgpResultBodyPart;
|
||||
import com.fsck.k9.mailstore.OpenPgpResultAnnotation;
|
||||
import org.openintents.openpgp.IOpenPgpService;
|
||||
import org.openintents.openpgp.OpenPgpError;
|
||||
import org.openintents.openpgp.OpenPgpSignatureResult;
|
||||
@ -42,7 +46,7 @@ import org.openintents.openpgp.util.OpenPgpServiceConnection;
|
||||
import org.openintents.openpgp.util.OpenPgpServiceConnection.OnBound;
|
||||
|
||||
|
||||
class MessageCryptoHelper {
|
||||
public class MessageCryptoHelper {
|
||||
|
||||
private final Context context;
|
||||
private final MessageViewFragment fragment;
|
||||
@ -54,12 +58,16 @@ class MessageCryptoHelper {
|
||||
private Part currentlyDecrypringOrVerifyingPart;
|
||||
private Intent currentCryptoResult;
|
||||
|
||||
private MessageCryptoAnnotations messageAnnotations;
|
||||
|
||||
private static final int INVALID_OPENPGP_RESULT_CODE = -1;
|
||||
|
||||
public MessageCryptoHelper(Context context, MessageViewFragment fragment, Account account) {
|
||||
this.context = context;
|
||||
this.fragment = fragment;
|
||||
this.account = account;
|
||||
|
||||
this.messageAnnotations = new MessageCryptoAnnotations();
|
||||
}
|
||||
|
||||
public void decryptOrVerifyMessagePartsIfNecessary(LocalMessage message) {
|
||||
@ -149,6 +157,8 @@ class MessageCryptoHelper {
|
||||
try {
|
||||
if (MessageDecryptVerifier.isPgpMimeSignedPart(currentlyDecrypringOrVerifyingPart)) {
|
||||
callAsyncDetachedVerify(intent);
|
||||
} else if (MessageDecryptVerifier.isPgpInlinePart(currentlyDecrypringOrVerifyingPart)) {
|
||||
callAsyncInlineOperation(intent);
|
||||
} else {
|
||||
callAsyncDecrypt(intent);
|
||||
}
|
||||
@ -159,6 +169,29 @@ class MessageCryptoHelper {
|
||||
}
|
||||
}
|
||||
|
||||
private void callAsyncInlineOperation(Intent intent) throws IOException {
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
PipedInputStream pipedInputStream = getPipedInputStreamForEncryptedOrInlineData();
|
||||
final ByteArrayOutputStream decryptedOutputStream = new ByteArrayOutputStream();
|
||||
|
||||
openPgpApi.executeApiAsync(intent, pipedInputStream, decryptedOutputStream, new IOpenPgpCallback() {
|
||||
@Override
|
||||
public void onReturn(Intent result) {
|
||||
currentCryptoResult = result;
|
||||
|
||||
MimeBodyPart decryptedPart = null;
|
||||
try {
|
||||
TextBody body = new TextBody(new String(decryptedOutputStream.toByteArray()));
|
||||
decryptedPart = new MimeBodyPart(body, "text/plain");
|
||||
} catch (MessagingException e) {
|
||||
Log.e(K9.LOG_TAG, "MessagingException", e);
|
||||
}
|
||||
|
||||
onCryptoConverge(decryptedPart);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void callAsyncDecrypt(Intent intent) throws IOException {
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
PipedInputStream pipedInputStream = getPipedInputStreamForEncryptedOrInlineData();
|
||||
@ -223,15 +256,17 @@ class MessageCryptoHelper {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
if (currentlyDecrypringOrVerifyingPart instanceof Multipart) {
|
||||
if (MessageDecryptVerifier.isPgpMimePart(currentlyDecrypringOrVerifyingPart)) {
|
||||
Multipart multipartEncryptedMultipart =
|
||||
(Multipart) currentlyDecrypringOrVerifyingPart.getBody();
|
||||
BodyPart encryptionPayloadPart = multipartEncryptedMultipart.getBodyPart(1);
|
||||
Body encryptionPayloadBody = encryptionPayloadPart.getBody();
|
||||
encryptionPayloadBody.writeTo(out);
|
||||
} else {
|
||||
} else if (MessageDecryptVerifier.isPgpInlinePart(currentlyDecrypringOrVerifyingPart)) {
|
||||
String text = MessageExtractor.getTextFromPart(currentlyDecrypringOrVerifyingPart);
|
||||
out.write(text.getBytes());
|
||||
} else {
|
||||
Log.wtf(K9.LOG_TAG, "No suitable data to stream found!");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(K9.LOG_TAG, "Exception while writing message to crypto provider", e);
|
||||
@ -251,16 +286,16 @@ class MessageCryptoHelper {
|
||||
private PipedOutputStream getPipedOutputStreamForDecryptedData(final CountDownLatch latch) throws IOException {
|
||||
PipedOutputStream decryptedOutputStream = new PipedOutputStream();
|
||||
final PipedInputStream decryptedInputStream = new PipedInputStream(decryptedOutputStream);
|
||||
new AsyncTask<Void, Void, OpenPgpResultBodyPart>() {
|
||||
new AsyncTask<Void, Void, MimeBodyPart>() {
|
||||
@Override
|
||||
protected OpenPgpResultBodyPart doInBackground(Void... params) {
|
||||
OpenPgpResultBodyPart decryptedPart = null;
|
||||
protected MimeBodyPart doInBackground(Void... params) {
|
||||
MimeBodyPart decryptedPart = null;
|
||||
try {
|
||||
decryptedPart = DecryptStreamParser.parse(context, decryptedInputStream);
|
||||
|
||||
latch.await();
|
||||
} catch (InterruptedException e) {
|
||||
Log.e(K9.LOG_TAG, "we were interrupted while waiting for onReturn!", e);
|
||||
Log.w(K9.LOG_TAG, "we were interrupted while waiting for onReturn!", e);
|
||||
} catch (Exception e) {
|
||||
Log.e(K9.LOG_TAG, "Something went wrong while parsing the decrypted MIME part", e);
|
||||
//TODO: pass error to main thread and display error message to user
|
||||
@ -269,14 +304,14 @@ class MessageCryptoHelper {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(OpenPgpResultBodyPart decryptedPart) {
|
||||
protected void onPostExecute(MimeBodyPart decryptedPart) {
|
||||
onCryptoConverge(decryptedPart);
|
||||
}
|
||||
}.execute();
|
||||
return decryptedOutputStream;
|
||||
}
|
||||
|
||||
private void onCryptoConverge(OpenPgpResultBodyPart openPgpResultBodyPart) {
|
||||
private void onCryptoConverge(MimeBodyPart outputPart) {
|
||||
try {
|
||||
if (currentCryptoResult == null) {
|
||||
Log.e(K9.LOG_TAG, "Internal error: we should have a result here!");
|
||||
@ -318,24 +353,26 @@ class MessageCryptoHelper {
|
||||
break;
|
||||
}
|
||||
case OpenPgpApi.RESULT_CODE_SUCCESS: {
|
||||
if (openPgpResultBodyPart == null) {
|
||||
openPgpResultBodyPart = new OpenPgpResultBodyPart(false);
|
||||
}
|
||||
OpenPgpResultAnnotation resultAnnotation = new OpenPgpResultAnnotation();
|
||||
|
||||
resultAnnotation.setOutputData(outputPart);
|
||||
|
||||
// TODO if the data /was/ encrypted, we should set it here!
|
||||
// this is not easy to determine for inline data though
|
||||
resultAnnotation.setWasEncrypted(false);
|
||||
|
||||
OpenPgpSignatureResult signatureResult =
|
||||
currentCryptoResult.getParcelableExtra(OpenPgpApi.RESULT_SIGNATURE);
|
||||
openPgpResultBodyPart.setSignatureResult(signatureResult);
|
||||
resultAnnotation.setSignatureResult(signatureResult);
|
||||
|
||||
PendingIntent pendingIntent =
|
||||
currentCryptoResult.getParcelableExtra(OpenPgpApi.RESULT_INTENT);
|
||||
openPgpResultBodyPart.setPendingIntent(pendingIntent);
|
||||
resultAnnotation.setPendingIntent(pendingIntent);
|
||||
|
||||
onCryptoSuccess(openPgpResultBodyPart);
|
||||
onCryptoSuccess(resultAnnotation);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (MessagingException e) {
|
||||
// catching the empty OpenPgpResultBodyPart constructor above - this can't actually happen
|
||||
Log.e(K9.LOG_TAG, "This shouldn't happen", e);
|
||||
} finally {
|
||||
currentCryptoResult = null;
|
||||
}
|
||||
@ -350,28 +387,19 @@ class MessageCryptoHelper {
|
||||
}
|
||||
}
|
||||
|
||||
private void onCryptoSuccess(OpenPgpResultBodyPart decryptedPart) {
|
||||
addOpenPgpResultPartToMessage(decryptedPart);
|
||||
private void onCryptoSuccess(OpenPgpResultAnnotation resultAnnotation) {
|
||||
addOpenPgpResultPartToMessage(resultAnnotation);
|
||||
onCryptoFinished();
|
||||
}
|
||||
|
||||
private void addOpenPgpResultPartToMessage(OpenPgpResultBodyPart decryptedPart) {
|
||||
if ( ! (currentlyDecrypringOrVerifyingPart.getBody() instanceof Multipart)) {
|
||||
// TODO this is a text/plain part - care about this later!
|
||||
return;
|
||||
}
|
||||
Multipart multipart = (Multipart) currentlyDecrypringOrVerifyingPart.getBody();
|
||||
multipart.addBodyPart(decryptedPart);
|
||||
private void addOpenPgpResultPartToMessage(OpenPgpResultAnnotation resultAnnotation) {
|
||||
messageAnnotations.put(currentlyDecrypringOrVerifyingPart, resultAnnotation);
|
||||
}
|
||||
|
||||
private void onCryptoFailed(OpenPgpError error) {
|
||||
try {
|
||||
OpenPgpResultBodyPart errorPart = new OpenPgpResultBodyPart(false);
|
||||
OpenPgpResultAnnotation errorPart = new OpenPgpResultAnnotation();
|
||||
errorPart.setError(error);
|
||||
addOpenPgpResultPartToMessage(errorPart);
|
||||
} catch (MessagingException e) {
|
||||
Log.e(K9.LOG_TAG, "This shouldn't happen", e);
|
||||
}
|
||||
onCryptoFinished();
|
||||
}
|
||||
|
||||
@ -381,7 +409,25 @@ class MessageCryptoHelper {
|
||||
}
|
||||
|
||||
private void returnResultToFragment() {
|
||||
fragment.startExtractingTextAndAttachments(message);
|
||||
fragment.startExtractingTextAndAttachments(messageAnnotations);
|
||||
}
|
||||
|
||||
public static class MessageCryptoAnnotations {
|
||||
|
||||
private HashMap<Part,OpenPgpResultAnnotation> annotations = new HashMap<Part,OpenPgpResultAnnotation>();
|
||||
|
||||
private void put(Part part, OpenPgpResultAnnotation annotation) {
|
||||
annotations.put(part, annotation);
|
||||
}
|
||||
|
||||
public OpenPgpResultAnnotation get(Part part) {
|
||||
return annotations.get(part);
|
||||
}
|
||||
|
||||
public boolean has(Part part) {
|
||||
return annotations.containsKey(part);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ import com.fsck.k9.mailstore.LocalMessage;
|
||||
import com.fsck.k9.mailstore.MessageViewInfo;
|
||||
import com.fsck.k9.ui.message.DecodeMessageLoader;
|
||||
import com.fsck.k9.ui.message.LocalMessageLoader;
|
||||
import com.fsck.k9.ui.messageview.MessageCryptoHelper.MessageCryptoAnnotations;
|
||||
import com.fsck.k9.view.MessageHeader;
|
||||
|
||||
public class MessageViewFragment extends Fragment implements ConfirmationDialogFragmentListener,
|
||||
@ -80,6 +81,7 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF
|
||||
private Account mAccount;
|
||||
private MessageReference mMessageReference;
|
||||
private LocalMessage mMessage;
|
||||
private MessageCryptoAnnotations messageAnnotations;
|
||||
private MessagingController mController;
|
||||
private LayoutInflater mLayoutInflater;
|
||||
private Handler handler = new Handler();
|
||||
@ -258,7 +260,8 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF
|
||||
Toast.makeText(mContext, errorMessage, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
void startExtractingTextAndAttachments(LocalMessage message) {
|
||||
void startExtractingTextAndAttachments(MessageCryptoAnnotations annotations) {
|
||||
this.messageAnnotations = annotations;
|
||||
getLoaderManager().initLoader(DECODE_MESSAGE_LOADER_ID, null, decodeMessageLoaderCallback);
|
||||
}
|
||||
|
||||
@ -742,7 +745,7 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF
|
||||
@Override
|
||||
public Loader<MessageViewInfo> onCreateLoader(int id, Bundle args) {
|
||||
setProgress(true);
|
||||
return new DecodeMessageLoader(mContext, mMessage);
|
||||
return new DecodeMessageLoader(mContext, mMessage, messageAnnotations);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
Reference in New Issue
Block a user