Merge pull request #1537 from k9mail/compose-attachments-from-viewinfo
Load attachments from AttachmentViewInfo in AttachmentPresenter
This commit is contained in:
commit
915f44ab14
7 changed files with 61 additions and 78 deletions
|
@ -1276,7 +1276,7 @@ public class MessageCompose extends K9Activity implements OnClickListener,
|
|||
}
|
||||
|
||||
if (!mSourceMessageProcessed) {
|
||||
attachmentPresenter.loadAttachments(message, 0);
|
||||
attachmentPresenter.loadNonInlineAttachments(messageViewInfo);
|
||||
}
|
||||
|
||||
// Decode the identity header when loading a draft.
|
||||
|
|
|
@ -21,15 +21,8 @@ import com.fsck.k9.activity.loader.AttachmentContentLoader;
|
|||
import com.fsck.k9.activity.loader.AttachmentInfoLoader;
|
||||
import com.fsck.k9.activity.misc.Attachment;
|
||||
import com.fsck.k9.activity.misc.Attachment.LoadingState;
|
||||
import com.fsck.k9.mail.Flag;
|
||||
import com.fsck.k9.mail.MessagingException;
|
||||
import com.fsck.k9.mail.Multipart;
|
||||
import com.fsck.k9.mail.Part;
|
||||
import com.fsck.k9.mail.internet.MimeUtility;
|
||||
import com.fsck.k9.mailstore.AttachmentViewInfo;
|
||||
import com.fsck.k9.mailstore.LocalBodyPart;
|
||||
import com.fsck.k9.mailstore.MessageViewInfo;
|
||||
import com.fsck.k9.provider.AttachmentProvider;
|
||||
|
||||
|
||||
public class AttachmentPresenter {
|
||||
|
@ -158,16 +151,27 @@ public class AttachmentPresenter {
|
|||
addAttachmentAndStartLoader(attachment);
|
||||
}
|
||||
|
||||
public void processMessageToForward(MessageViewInfo messageViewInfo) {
|
||||
if (messageViewInfo.message.isSet(Flag.X_DOWNLOADED_PARTIAL)) {
|
||||
attachmentMvpView.showMissingAttachmentsPartialMessageWarning();
|
||||
return;
|
||||
}
|
||||
public boolean loadNonInlineAttachments(MessageViewInfo messageViewInfo) {
|
||||
boolean allPartsAvailable = true;
|
||||
|
||||
for (AttachmentViewInfo attachmentViewInfo : messageViewInfo.attachments) {
|
||||
if (!attachmentViewInfo.inlineAttachment) {
|
||||
addAttachment(attachmentViewInfo);
|
||||
if (attachmentViewInfo.inlineAttachment) {
|
||||
continue;
|
||||
}
|
||||
if (!attachmentViewInfo.isContentAvailable) {
|
||||
allPartsAvailable = false;
|
||||
continue;
|
||||
}
|
||||
addAttachment(attachmentViewInfo);
|
||||
}
|
||||
|
||||
return allPartsAvailable;
|
||||
}
|
||||
|
||||
public void processMessageToForward(MessageViewInfo messageViewInfo) {
|
||||
boolean isMissingParts = !loadNonInlineAttachments(messageViewInfo);
|
||||
if (isMissingParts) {
|
||||
attachmentMvpView.showMissingAttachmentsPartialMessageWarning();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -300,45 +304,6 @@ public class AttachmentPresenter {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all attachments of an existing message as if they were added by hand.
|
||||
*
|
||||
* @param part
|
||||
* The message part to check for being an attachment. This method will recurse if it's
|
||||
* a multipart part.
|
||||
* @param depth
|
||||
* The recursion depth. Currently unused.
|
||||
*
|
||||
* @return {@code true} if all attachments were able to be attached, {@code false} otherwise.
|
||||
*/
|
||||
public boolean loadAttachments(Part part, int depth) {
|
||||
if (part.getBody() instanceof Multipart) {
|
||||
Multipart mp = (Multipart) part.getBody();
|
||||
boolean ret = true;
|
||||
for (int i = 0, count = mp.getCount(); i < count; i++) {
|
||||
if (!loadAttachments(mp.getBodyPart(i), depth + 1)) {
|
||||
ret = false;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
String contentType = part.getContentType();
|
||||
String name = MimeUtility.getHeaderParameter(contentType, "name");
|
||||
if (name != null) {
|
||||
if (part instanceof LocalBodyPart) {
|
||||
LocalBodyPart localBodyPart = (LocalBodyPart) part;
|
||||
String accountUuid = localBodyPart.getAccountUuid();
|
||||
long attachmentId = localBodyPart.getId();
|
||||
Uri uri = AttachmentProvider.getAttachmentUri(accountUuid, attachmentId);
|
||||
addAttachment(uri);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
|
||||
void addAttachmentsFromResultIntent(Intent data) {
|
||||
// TODO draftNeedsSaving = true
|
||||
|
|
|
@ -23,14 +23,16 @@ public class AttachmentViewInfo {
|
|||
public final Uri uri;
|
||||
public final boolean inlineAttachment;
|
||||
public final Part part;
|
||||
public final boolean isContentAvailable;
|
||||
|
||||
public AttachmentViewInfo(String mimeType, String displayName, long size, Uri uri, boolean inlineAttachment,
|
||||
Part part) {
|
||||
Part part, boolean isContentAvailable) {
|
||||
this.mimeType = mimeType;
|
||||
this.displayName = displayName;
|
||||
this.size = size;
|
||||
this.uri = uri;
|
||||
this.inlineAttachment = inlineAttachment;
|
||||
this.part = part;
|
||||
this.isContentAvailable = isContentAvailable;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,17 +61,21 @@ public class AttachmentInfoExtractor {
|
|||
public AttachmentViewInfo extractAttachmentInfo(Part part) throws MessagingException {
|
||||
Uri uri;
|
||||
long size;
|
||||
boolean isContentAvailable;
|
||||
|
||||
if (part instanceof LocalPart) {
|
||||
LocalPart localPart = (LocalPart) part;
|
||||
String accountUuid = localPart.getAccountUuid();
|
||||
long messagePartId = localPart.getId();
|
||||
size = localPart.getSize();
|
||||
isContentAvailable = part.getBody() != null;
|
||||
uri = AttachmentProvider.getAttachmentUri(accountUuid, messagePartId);
|
||||
} else if (part instanceof LocalMessage) {
|
||||
LocalMessage localMessage = (LocalMessage) part;
|
||||
String accountUuid = localMessage.getAccount().getUuid();
|
||||
long messagePartId = localMessage.getMessagePartId();
|
||||
size = localMessage.getSize();
|
||||
isContentAvailable = part.getBody() != null;
|
||||
uri = AttachmentProvider.getAttachmentUri(accountUuid, messagePartId);
|
||||
} else {
|
||||
Body body = part.getBody();
|
||||
|
@ -79,13 +83,13 @@ public class AttachmentInfoExtractor {
|
|||
DeferredFileBody decryptedTempFileBody = (DeferredFileBody) body;
|
||||
size = decryptedTempFileBody.getSize();
|
||||
uri = getDecryptedFileProviderUri(decryptedTempFileBody, part.getMimeType());
|
||||
return extractAttachmentInfo(part, uri, size);
|
||||
isContentAvailable = true;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported part type provided");
|
||||
}
|
||||
}
|
||||
|
||||
return extractAttachmentInfo(part, uri, size);
|
||||
return extractAttachmentInfo(part, uri, size, isContentAvailable);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -104,11 +108,13 @@ public class AttachmentInfoExtractor {
|
|||
}
|
||||
|
||||
public AttachmentViewInfo extractAttachmentInfoForDatabase(Part part) throws MessagingException {
|
||||
return extractAttachmentInfo(part, Uri.EMPTY, AttachmentViewInfo.UNKNOWN_SIZE);
|
||||
boolean isContentAvailable = part.getBody() != null;
|
||||
return extractAttachmentInfo(part, Uri.EMPTY, AttachmentViewInfo.UNKNOWN_SIZE, isContentAvailable);
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
private AttachmentViewInfo extractAttachmentInfo(Part part, Uri uri, long size) throws MessagingException {
|
||||
private AttachmentViewInfo extractAttachmentInfo(Part part, Uri uri, long size, boolean isContentAvailable)
|
||||
throws MessagingException {
|
||||
boolean inlineAttachment = false;
|
||||
|
||||
String mimeType = part.getMimeType();
|
||||
|
@ -139,7 +145,7 @@ public class AttachmentInfoExtractor {
|
|||
|
||||
long attachmentSize = extractAttachmentSize(contentDisposition, size);
|
||||
|
||||
return new AttachmentViewInfo(mimeType, name, attachmentSize, uri, inlineAttachment, part);
|
||||
return new AttachmentViewInfo(mimeType, name, attachmentSize, uri, inlineAttachment, part, isContentAvailable);
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
|
|
|
@ -55,7 +55,7 @@ public class AttachmentController {
|
|||
}
|
||||
|
||||
public void viewAttachment() {
|
||||
if (needsDownloading()) {
|
||||
if (!attachment.isContentAvailable) {
|
||||
downloadAndViewAttachment((LocalPart) attachment.part);
|
||||
} else {
|
||||
viewLocalAttachment();
|
||||
|
@ -70,18 +70,6 @@ public class AttachmentController {
|
|||
saveAttachmentTo(new File(directory));
|
||||
}
|
||||
|
||||
private boolean needsDownloading() {
|
||||
return isPartMissing() && isLocalPart();
|
||||
}
|
||||
|
||||
private boolean isPartMissing() {
|
||||
return attachment.part.getBody() == null;
|
||||
}
|
||||
|
||||
private boolean isLocalPart() {
|
||||
return attachment.part instanceof LocalPart;
|
||||
}
|
||||
|
||||
private void downloadAndViewAttachment(LocalPart localPart) {
|
||||
downloadAttachment(localPart, new Runnable() {
|
||||
@Override
|
||||
|
@ -133,7 +121,7 @@ public class AttachmentController {
|
|||
return;
|
||||
}
|
||||
|
||||
if (needsDownloading()) {
|
||||
if (!attachment.isContentAvailable) {
|
||||
downloadAndSaveAttachmentTo((LocalPart) attachment.part, directory);
|
||||
} else {
|
||||
saveLocalAttachmentTo(directory);
|
||||
|
|
|
@ -86,14 +86,15 @@ public class AttachmentResolverTest {
|
|||
subPart1.setHeader(MimeHeader.HEADER_CONTENT_ID, "cid-1");
|
||||
subPart2.setHeader(MimeHeader.HEADER_CONTENT_ID, "cid-2");
|
||||
|
||||
when(attachmentInfoExtractor.extractAttachmentInfo(subPart1)).thenReturn(
|
||||
new AttachmentViewInfo(null, null, AttachmentViewInfo.UNKNOWN_SIZE, ATTACHMENT_TEST_URI_1, false, subPart1));
|
||||
when(attachmentInfoExtractor.extractAttachmentInfo(subPart2)).thenReturn(
|
||||
new AttachmentViewInfo(null, null, AttachmentViewInfo.UNKNOWN_SIZE, ATTACHMENT_TEST_URI_2, false, subPart2));
|
||||
when(attachmentInfoExtractor.extractAttachmentInfo(subPart1)).thenReturn(new AttachmentViewInfo(
|
||||
null, null, AttachmentViewInfo.UNKNOWN_SIZE, ATTACHMENT_TEST_URI_1, false, subPart1, true));
|
||||
when(attachmentInfoExtractor.extractAttachmentInfo(subPart2)).thenReturn(new AttachmentViewInfo(
|
||||
null, null, AttachmentViewInfo.UNKNOWN_SIZE, ATTACHMENT_TEST_URI_2, false, subPart2, true));
|
||||
|
||||
|
||||
Map<String,Uri> result = AttachmentResolver.buildCidToAttachmentUriMap(attachmentInfoExtractor, multipartPart);
|
||||
|
||||
|
||||
assertEquals(2, result.size());
|
||||
assertEquals(ATTACHMENT_TEST_URI_1, result.get("cid-1"));
|
||||
assertEquals(ATTACHMENT_TEST_URI_2, result.get("cid-2"));
|
||||
|
|
|
@ -8,6 +8,7 @@ import android.support.annotation.Nullable;
|
|||
import com.fsck.k9.mail.Part;
|
||||
import com.fsck.k9.mail.internet.MimeBodyPart;
|
||||
import com.fsck.k9.mail.internet.MimeHeader;
|
||||
import com.fsck.k9.mail.internet.TextBody;
|
||||
import com.fsck.k9.mailstore.AttachmentViewInfo;
|
||||
import com.fsck.k9.mailstore.LocalBodyPart;
|
||||
import com.fsck.k9.mailstore.DeferredFileBody;
|
||||
|
@ -162,6 +163,25 @@ public class AttachmentInfoExtractorTest {
|
|||
assertEquals(AttachmentViewInfo.UNKNOWN_SIZE, attachmentViewInfo.size);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void extractInfoForDb__withNoBody__shouldReturnContentNotAvailable() throws Exception {
|
||||
MimeBodyPart part = new MimeBodyPart();
|
||||
|
||||
AttachmentViewInfo attachmentViewInfo = attachmentInfoExtractor.extractAttachmentInfoForDatabase(part);
|
||||
|
||||
assertFalse(attachmentViewInfo.isContentAvailable);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void extractInfoForDb__withNoBody__shouldReturnContentAvailable() throws Exception {
|
||||
MimeBodyPart part = new MimeBodyPart();
|
||||
part.setBody(new TextBody("data"));
|
||||
|
||||
AttachmentViewInfo attachmentViewInfo = attachmentInfoExtractor.extractAttachmentInfoForDatabase(part);
|
||||
|
||||
assertTrue(attachmentViewInfo.isContentAvailable);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void extractInfo__withDeferredFileBody() throws Exception {
|
||||
attachmentInfoExtractor = new AttachmentInfoExtractor(context) {
|
||||
|
@ -187,5 +207,6 @@ public class AttachmentInfoExtractorTest {
|
|||
assertEquals(TEST_SIZE, attachmentViewInfo.size);
|
||||
assertEquals(TEST_MIME_TYPE, attachmentViewInfo.mimeType);
|
||||
assertFalse(attachmentViewInfo.inlineAttachment);
|
||||
assertTrue(attachmentViewInfo.isContentAvailable);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue