From dc8fd39c7ecd51035562f04a0c4dbf7de78efcf2 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Fri, 30 Jan 2015 16:10:47 +0100 Subject: [PATCH] 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 --- .../k9/crypto/MessageDecryptVerifier.java | 8 +- .../k9/mailstore/DecryptStreamParser.java | 10 +- .../k9/mailstore/LocalMessageExtractor.java | 66 ++++------ .../k9/mailstore/OpenPgpResultAnnotation.java | 25 +++- .../k9/ui/message/DecodeMessageLoader.java | 7 +- .../ui/messageview/MessageCryptoHelper.java | 118 ++++++++++++------ .../ui/messageview/MessageViewFragment.java | 7 +- 7 files changed, 147 insertions(+), 94 deletions(-) diff --git a/k9mail/src/main/java/com/fsck/k9/crypto/MessageDecryptVerifier.java b/k9mail/src/main/java/com/fsck/k9/crypto/MessageDecryptVerifier.java index 1a331c539..61cd960d4 100644 --- a/k9mail/src/main/java/com/fsck/k9/crypto/MessageDecryptVerifier.java +++ b/k9mail/src/main/java/com/fsck/k9/crypto/MessageDecryptVerifier.java @@ -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); } diff --git a/k9mail/src/main/java/com/fsck/k9/mailstore/DecryptStreamParser.java b/k9mail/src/main/java/com/fsck/k9/mailstore/DecryptStreamParser.java index b5f61ff95..ff8352b49 100644 --- a/k9mail/src/main/java/com/fsck/k9/mailstore/DecryptStreamParser.java +++ b/k9mail/src/main/java/com/fsck/k9/mailstore/DecryptStreamParser.java @@ -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 stack = new Stack(); - public PartBuilder(File decryptedTempDirectory, OpenPgpResultBodyPart decryptedRootPart) + public PartBuilder(File decryptedTempDirectory, MimeBodyPart decryptedRootPart) throws MessagingException { this.decryptedTempDirectory = decryptedTempDirectory; this.decryptedRootPart = decryptedRootPart; diff --git a/k9mail/src/main/java/com/fsck/k9/mailstore/LocalMessageExtractor.java b/k9mail/src/main/java/com/fsck/k9/mailstore/LocalMessageExtractor.java index d0b8a5fce..5d9db8c1d 100644 --- a/k9mail/src/main/java/com/fsck/k9/mailstore/LocalMessageExtractor.java +++ b/k9mail/src/main/java/com/fsck/k9/mailstore/LocalMessageExtractor.java @@ -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(""); } - 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 parts = getCryptPieces(message); + List parts = getCryptPieces(message, annotations); // 2. extract viewables/attachments of parts ArrayList containers = new ArrayList(); 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 attachments = new ArrayList(); List viewables = MessageExtractor.getViewables(part, attachments); @@ -440,12 +448,11 @@ public class LocalMessageExtractor { attachments); List 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 getCryptPieces(Part part) throws MessagingException { + public static List 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 parts = new ArrayList(); - if (!getCryptSubPieces(part, parts)) { - parts.add(part); + if (!getCryptSubPieces(message, parts, annotations)) { + parts.add(message); } return parts; } - public static boolean getCryptSubPieces(Part part, ArrayList parts) throws MessagingException { + public static boolean getCryptSubPieces(Part part, ArrayList 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 extractAttachmentInfos(Context context, List attachmentParts) throws MessagingException { diff --git a/k9mail/src/main/java/com/fsck/k9/mailstore/OpenPgpResultAnnotation.java b/k9mail/src/main/java/com/fsck/k9/mailstore/OpenPgpResultAnnotation.java index bcd60b711..ad77177a3 100644 --- a/k9mail/src/main/java/com/fsck/k9/mailstore/OpenPgpResultAnnotation.java +++ b/k9mail/src/main/java/com/fsck/k9/mailstore/OpenPgpResultAnnotation.java @@ -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; + } + } diff --git a/k9mail/src/main/java/com/fsck/k9/ui/message/DecodeMessageLoader.java b/k9mail/src/main/java/com/fsck/k9/ui/message/DecodeMessageLoader.java index 27a0a5e00..d2644acaf 100644 --- a/k9mail/src/main/java/com/fsck/k9/ui/message/DecodeMessageLoader.java +++ b/k9mail/src/main/java/com/fsck/k9/ui/message/DecodeMessageLoader.java @@ -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 { 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 { @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; diff --git a/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageCryptoHelper.java b/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageCryptoHelper.java index e1865fbc7..3314f6a29 100644 --- a/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageCryptoHelper.java +++ b/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageCryptoHelper.java @@ -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() { + new AsyncTask() { @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); - errorPart.setError(error); - addOpenPgpResultPartToMessage(errorPart); - } catch (MessagingException e) { - Log.e(K9.LOG_TAG, "This shouldn't happen", e); - } + OpenPgpResultAnnotation errorPart = new OpenPgpResultAnnotation(); + errorPart.setError(error); + addOpenPgpResultPartToMessage(errorPart); onCryptoFinished(); } @@ -381,7 +409,25 @@ class MessageCryptoHelper { } private void returnResultToFragment() { - fragment.startExtractingTextAndAttachments(message); + fragment.startExtractingTextAndAttachments(messageAnnotations); + } + + public static class MessageCryptoAnnotations { + + private HashMap annotations = new HashMap(); + + 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); + } + } } diff --git a/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.java b/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.java index f016d3950..084ae5b41 100644 --- a/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.java +++ b/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.java @@ -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 onCreateLoader(int id, Bundle args) { setProgress(true); - return new DecodeMessageLoader(mContext, mMessage); + return new DecodeMessageLoader(mContext, mMessage, messageAnnotations); } @Override