Cache attachments on send

Cache attachments in a email directory when sending to allow sending
to succeed when the content provider has a permission

Bug: 7381557
Change-Id: Icf9faead2048de237228625f998b42feade48978
This commit is contained in:
Paul Westbrook 2013-02-22 19:42:40 -08:00
parent 3e2fdd33e3
commit 9a95253846
7 changed files with 191 additions and 61 deletions

View File

@ -18,6 +18,7 @@ package com.android.emailcommon.internet;
import android.content.Context;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Base64OutputStream;
@ -27,11 +28,14 @@ import com.android.emailcommon.provider.EmailContent.Attachment;
import com.android.emailcommon.provider.EmailContent.Body;
import com.android.emailcommon.provider.EmailContent.Message;
import com.android.mail.utils.LogUtils;
import org.apache.commons.io.IOUtils;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@ -49,6 +53,7 @@ import java.util.regex.Pattern;
* Utility class to output RFC 822 messages from provider email messages
*/
public class Rfc822Output {
private static final String TAG = "Email";
// In MIME, en_US-like date format should be used. In other words "MMM" should be encoded to
// "Jan", not the other localized format like "Ene" (meaning January in locale es).
@ -233,9 +238,25 @@ public class Rfc822Output {
if (attachment.mContentBytes != null) {
inStream = new ByteArrayInputStream(attachment.mContentBytes);
} else {
// try to open the file
Uri fileUri = Uri.parse(attachment.getContentUri());
inStream = context.getContentResolver().openInputStream(fileUri);
// First try the cached file
final String cachedFile = attachment.getCachedFilePath();
if (!TextUtils.isEmpty(cachedFile)) {
try {
inStream = new FileInputStream(cachedFile);
} catch (IOException e) {
// Couldn't open the cached file, fall back to the original content uri
inStream = null;
LogUtils.d(TAG, "Rfc822Output#writeOneAttachment(), failed to load" +
"cached file, falling back to: %s", attachment.getContentUri());
}
}
if (inStream == null) {
// try to open the file
final Uri fileUri = Uri.parse(attachment.getContentUri());
inStream = context.getContentResolver().openInputStream(fileUri);
}
}
// switch to output stream for base64 text output
writer.flush();
@ -254,8 +275,12 @@ public class Rfc822Output {
}
catch (FileNotFoundException fnfe) {
// Ignore this - empty file is OK
LogUtils.e(TAG, fnfe, "Rfc822Output#writeOneAttachment(), FileNotFoundException" +
"when sending attachment");
}
catch (IOException ioe) {
LogUtils.e(TAG, ioe, "Rfc822Output#writeOneAttachment(), IOException" +
"when sending attachment");
throw new MessagingException("Invalid attachment.", ioe);
}
}

View File

@ -1150,6 +1150,8 @@ public abstract class EmailContent {
// The location of the loaded attachment (probably a file)
@SuppressWarnings("hiding")
public static final String CONTENT_URI = "contentUri";
// The cached location of the attachment
public static final String CACHED_FILE = "cachedFile";
// A foreign key into the Message table (the message owning this attachment)
public static final String MESSAGE_KEY = "messageKey";
// The location of the attachment on the server side
@ -1200,6 +1202,7 @@ public abstract class EmailContent {
public long mSize;
public String mContentId;
private String mContentUri;
private String mCachedFile;
public long mMessageKey;
public String mLocation;
public String mEncoding;
@ -1217,23 +1220,25 @@ public abstract class EmailContent {
public static final int CONTENT_SIZE_COLUMN = 3;
public static final int CONTENT_CONTENT_ID_COLUMN = 4;
public static final int CONTENT_CONTENT_URI_COLUMN = 5;
public static final int CONTENT_MESSAGE_ID_COLUMN = 6;
public static final int CONTENT_LOCATION_COLUMN = 7;
public static final int CONTENT_ENCODING_COLUMN = 8;
public static final int CONTENT_CONTENT_COLUMN = 9; // Not currently used
public static final int CONTENT_FLAGS_COLUMN = 10;
public static final int CONTENT_CONTENT_BYTES_COLUMN = 11;
public static final int CONTENT_ACCOUNT_KEY_COLUMN = 12;
public static final int CONTENT_UI_STATE_COLUMN = 13;
public static final int CONTENT_UI_DESTINATION_COLUMN = 14;
public static final int CONTENT_UI_DOWNLOADED_SIZE_COLUMN = 15;
public static final int CONTENT_CACHED_FILE_COLUMN = 6;
public static final int CONTENT_MESSAGE_ID_COLUMN = 7;
public static final int CONTENT_LOCATION_COLUMN = 8;
public static final int CONTENT_ENCODING_COLUMN = 9;
public static final int CONTENT_CONTENT_COLUMN = 10; // Not currently used
public static final int CONTENT_FLAGS_COLUMN = 11;
public static final int CONTENT_CONTENT_BYTES_COLUMN = 12;
public static final int CONTENT_ACCOUNT_KEY_COLUMN = 13;
public static final int CONTENT_UI_STATE_COLUMN = 14;
public static final int CONTENT_UI_DESTINATION_COLUMN = 15;
public static final int CONTENT_UI_DOWNLOADED_SIZE_COLUMN = 16;
public static final String[] CONTENT_PROJECTION = new String[] {
RECORD_ID, AttachmentColumns.FILENAME, AttachmentColumns.MIME_TYPE,
AttachmentColumns.SIZE, AttachmentColumns.CONTENT_ID, AttachmentColumns.CONTENT_URI,
AttachmentColumns.MESSAGE_KEY, AttachmentColumns.LOCATION, AttachmentColumns.ENCODING,
AttachmentColumns.CONTENT, AttachmentColumns.FLAGS, AttachmentColumns.CONTENT_BYTES,
AttachmentColumns.ACCOUNT_KEY, AttachmentColumns.UI_STATE,
AttachmentColumns.UI_DESTINATION, AttachmentColumns.UI_DOWNLOADED_SIZE
AttachmentColumns.CACHED_FILE, AttachmentColumns.MESSAGE_KEY,
AttachmentColumns.LOCATION, AttachmentColumns.ENCODING, AttachmentColumns.CONTENT,
AttachmentColumns.FLAGS, AttachmentColumns.CONTENT_BYTES, AttachmentColumns.ACCOUNT_KEY,
AttachmentColumns.UI_STATE, AttachmentColumns.UI_DESTINATION,
AttachmentColumns.UI_DOWNLOADED_SIZE
};
// All attachments with an empty URI, regardless of mailbox
@ -1275,6 +1280,14 @@ public abstract class EmailContent {
mBaseUri = CONTENT_URI;
}
public void setCachedFilePath(String cachedFile) {
mCachedFile = cachedFile;
}
public String getCachedFilePath() {
return mCachedFile;
}
public void setContentUri(String contentUri) {
mContentUri = contentUri;
}
@ -1376,6 +1389,7 @@ public abstract class EmailContent {
mSize = cursor.getLong(CONTENT_SIZE_COLUMN);
mContentId = cursor.getString(CONTENT_CONTENT_ID_COLUMN);
mContentUri = cursor.getString(CONTENT_CONTENT_URI_COLUMN);
mCachedFile = cursor.getString(CONTENT_CACHED_FILE_COLUMN);
mMessageKey = cursor.getLong(CONTENT_MESSAGE_ID_COLUMN);
mLocation = cursor.getString(CONTENT_LOCATION_COLUMN);
mEncoding = cursor.getString(CONTENT_ENCODING_COLUMN);
@ -1396,6 +1410,7 @@ public abstract class EmailContent {
values.put(AttachmentColumns.SIZE, mSize);
values.put(AttachmentColumns.CONTENT_ID, mContentId);
values.put(AttachmentColumns.CONTENT_URI, mContentUri);
values.put(AttachmentColumns.CACHED_FILE, mCachedFile);
values.put(AttachmentColumns.MESSAGE_KEY, mMessageKey);
values.put(AttachmentColumns.LOCATION, mLocation);
values.put(AttachmentColumns.ENCODING, mEncoding);
@ -1423,6 +1438,7 @@ public abstract class EmailContent {
dest.writeLong(mSize);
dest.writeString(mContentId);
dest.writeString(mContentUri);
dest.writeString(mCachedFile);
dest.writeLong(mMessageKey);
dest.writeString(mLocation);
dest.writeString(mEncoding);
@ -1448,6 +1464,7 @@ public abstract class EmailContent {
mSize = in.readLong();
mContentId = in.readString();
mContentUri = in.readString();
mCachedFile = in.readString();
mMessageKey = in.readLong();
mLocation = in.readString();
mEncoding = in.readString();
@ -1482,9 +1499,10 @@ public abstract class EmailContent {
@Override
public String toString() {
return "[" + mFileName + ", " + mMimeType + ", " + mSize + ", " + mContentId + ", "
+ mContentUri + ", " + mMessageKey + ", " + mLocation + ", " + mEncoding + ", "
+ mFlags + ", " + mContentBytes + ", " + mAccountKey + "," + mUiState + ","
+ mUiDestination + "," + mUiDownloadedSize + "]";
+ mContentUri + ", " + mCachedFile + ", " + mMessageKey + ", "
+ mLocation + ", " + mEncoding + ", " + mFlags + ", " + mContentBytes + ", "
+ mAccountKey + "," + mUiState + "," + mUiDestination + ","
+ mUiDownloadedSize + "]";
}
}

View File

@ -58,6 +58,10 @@ public class AttachmentUtilities {
public static final String SIZE = "_size";
}
private static final String[] ATTACHMENT_CACHED_FILE_PROJECTION = new String[] {
AttachmentColumns.CACHED_FILE
};
/**
* The MIME type(s) of attachments we're willing to send via attachments.
*
@ -299,6 +303,34 @@ public class AttachmentUtilities {
}
}
/**
* In support of deleting a message, find all attachments and delete associated cached
* attachment files.
* @param context
* @param accountId the account for the message
* @param messageId the message
*/
public static void deleteAllCachedAttachmentFiles(Context context, long accountId,
long messageId) {
final Uri uri = ContentUris.withAppendedId(Attachment.MESSAGE_ID_URI, messageId);
final Cursor c = context.getContentResolver().query(uri, ATTACHMENT_CACHED_FILE_PROJECTION,
null, null, null);
try {
while (c.moveToNext()) {
final String fileName = c.getString(0);
if (!TextUtils.isEmpty(fileName)) {
final File cachedFile = new File(fileName);
// Note, delete() throws no exceptions for basic FS errors (e.g. file not found)
// it just returns false, which we ignore, and proceed to the next file.
// This entire loop is best-effort only.
cachedFile.delete();
}
}
} finally {
c.close();
}
}
/**
* In support of deleting a mailbox, find all messages and delete their attachments.
*

View File

@ -57,6 +57,7 @@ import com.android.emailcommon.provider.ProviderUnavailableException;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
@ -744,14 +745,30 @@ public class Utility {
} else if (attachment.mContentBytes != null) {
return true;
} else {
String contentUri = attachment.getContentUri();
final String cachedFile = attachment.getCachedFilePath();
// Try the cached file first
if (!TextUtils.isEmpty(cachedFile)) {
try {
final InputStream inStream = new FileInputStream(cachedFile);
try {
inStream.close();
} catch (IOException e) {
// Nothing to be done if can't close the stream
}
return true;
} catch (FileNotFoundException e) {
// We weren't able to open the file, try the content uri below
}
}
final String contentUri = attachment.getContentUri();
if (TextUtils.isEmpty(contentUri)) {
return false;
}
try {
Uri fileUri = Uri.parse(contentUri);
final Uri fileUri = Uri.parse(contentUri);
try {
InputStream inStream = context.getContentResolver().openInputStream(fileUri);
final InputStream inStream =
context.getContentResolver().openInputStream(fileUri);
try {
inStream.close();
} catch (IOException e) {

View File

@ -132,8 +132,9 @@ public final class DBHelper {
// Version 104&105: add syncData to Message
// Version 106: Add certificate to HostAuth
// Version 107: Add a SEEN column to the message table
// Version 108: Add a cachedFile column to the attachments table
public static final int DATABASE_VERSION = 107;
public static final int DATABASE_VERSION = 108;
// Any changes to the database format *must* include update-in-place code.
// Original version: 2
@ -453,7 +454,8 @@ public final class DBHelper {
+ AttachmentColumns.ACCOUNT_KEY + " integer, "
+ AttachmentColumns.UI_STATE + " integer, "
+ AttachmentColumns.UI_DESTINATION + " integer, "
+ AttachmentColumns.UI_DOWNLOADED_SIZE + " integer"
+ AttachmentColumns.UI_DOWNLOADED_SIZE + " integer, "
+ AttachmentColumns.CACHED_FILE + " text"
+ ");";
db.execSQL("create table " + Attachment.TABLE_NAME + s);
db.execSQL(createIndex(Attachment.TABLE_NAME, AttachmentColumns.MESSAGE_KEY));
@ -1028,6 +1030,17 @@ public final class DBHelper {
}
oldVersion = 107;
}
if (oldVersion == 107) {
try {
db.execSQL("alter table " + Attachment.TABLE_NAME
+ " add column " + Attachment.CACHED_FILE +" text" + ";");
oldVersion = 108;
} catch (SQLException e) {
// Shouldn't be needed unless we're debugging and interrupt the process
Log.w(TAG, "Exception upgrading EmailProvider.db from v107 to v108", e);
}
}
}
@Override

View File

@ -88,6 +88,7 @@ import com.android.mail.providers.UIProvider.ConversationPriority;
import com.android.mail.providers.UIProvider.ConversationSendingState;
import com.android.mail.providers.UIProvider.DraftType;
import com.android.mail.providers.UIProvider.Swipe;
import com.android.mail.utils.AttachmentUtils;
import com.android.mail.utils.LogUtils;
import com.android.mail.utils.MatrixCursorWithCachedColumns;
import com.android.mail.utils.MatrixCursorWithExtra;
@ -3529,12 +3530,16 @@ outer:
* Convert a UIProvider attachment to an EmailProvider attachment (for sending); we only need
* a few of the fields
* @param uiAtt the UIProvider attachment to convert
* @param cachedFile the path to the cached file to
* @return the EmailProvider attachment
*/
// TODO(pwestbro): once the Attachment contains the cached uri, the second parameter can be
// removed
private static Attachment convertUiAttachmentToAttachment(
com.android.mail.providers.Attachment uiAtt) {
Attachment att = new Attachment();
com.android.mail.providers.Attachment uiAtt, String cachedFile) {
final Attachment att = new Attachment();
att.setContentUri(uiAtt.contentUri.toString());
att.setCachedFilePath(cachedFile);
att.mFileName = uiAtt.getName();
att.mMimeType = uiAtt.getContentType();
att.mSize = uiAtt.size;
@ -3624,10 +3629,11 @@ outer:
* @param values the content values that represent message fields
* @return the uri of the newly created message
*/
private Uri uiSaveMessage(Message msg, Mailbox mailbox, ContentValues values) {
Context context = getContext();
private Uri uiSaveMessage(Message msg, Mailbox mailbox, ContentValues values,
Bundle attachmentFds) {
final Context context = getContext();
// Fill in the message
Account account = Account.restoreAccountWithId(context, mailbox.mAccountKey);
final Account account = Account.restoreAccountWithId(context, mailbox.mAccountKey);
if (account == null) return null;
msg.mFrom = account.mEmailAddress;
msg.mTimeStamp = System.currentTimeMillis();
@ -3643,10 +3649,11 @@ outer:
msg.mFlagLoaded = Message.FLAG_LOADED_COMPLETE;
msg.mFlagRead = true;
msg.mFlagSeen = true;
Integer quoteStartPos = values.getAsInteger(UIProvider.MessageColumns.QUOTE_START_POS);
final Integer quoteStartPos =
values.getAsInteger(UIProvider.MessageColumns.QUOTE_START_POS);
msg.mQuotedTextStartPos = quoteStartPos == null ? 0 : quoteStartPos;
int flags = 0;
int draftType = values.getAsInteger(UIProvider.MessageColumns.DRAFT_TYPE);
final int draftType = values.getAsInteger(UIProvider.MessageColumns.DRAFT_TYPE);
switch(draftType) {
case DraftType.FORWARD:
flags |= Message.FLAG_TYPE_FORWARD;
@ -3674,7 +3681,7 @@ outer:
msg.mDraftInfo = draftInfo;
msg.mFlags = flags;
String ref = values.getAsString(UIProvider.MessageColumns.REF_MESSAGE_ID);
final String ref = values.getAsString(UIProvider.MessageColumns.REF_MESSAGE_ID);
if (ref != null && msg.mQuotedTextStartPos >= 0) {
String refId = Uri.parse(ref).getLastPathSegment();
try {
@ -3686,24 +3693,24 @@ outer:
}
// Get attachments from the ContentValues
List<com.android.mail.providers.Attachment> uiAtts =
final List<com.android.mail.providers.Attachment> uiAtts =
com.android.mail.providers.Attachment.fromJSONArray(
values.getAsString(UIProvider.MessageColumns.ATTACHMENTS));
ArrayList<Attachment> atts = new ArrayList<Attachment>();
final ArrayList<Attachment> atts = new ArrayList<Attachment>();
boolean hasUnloadedAttachments = false;
for (com.android.mail.providers.Attachment uiAtt: uiAtts) {
Uri attUri = uiAtt.uri;
final Uri attUri = uiAtt.uri;
if (attUri != null && attUri.getAuthority().equals(EmailContent.AUTHORITY)) {
// If it's one of ours, retrieve the attachment and add it to the list
long attId = Long.parseLong(attUri.getLastPathSegment());
Attachment att = Attachment.restoreAttachmentWithId(context, attId);
final long attId = Long.parseLong(attUri.getLastPathSegment());
final Attachment att = Attachment.restoreAttachmentWithId(context, attId);
if (att != null) {
// We must clone the attachment into a new one for this message; easiest to
// use a parcel here
Parcel p = Parcel.obtain();
final Parcel p = Parcel.obtain();
att.writeToParcel(p, 0);
p.setDataPosition(0);
Attachment attClone = new Attachment(p);
final Attachment attClone = new Attachment(p);
p.recycle();
// Clear the messageKey (this is going to be a new attachment)
attClone.mMessageKey = 0;
@ -3717,8 +3724,13 @@ outer:
atts.add(attClone);
}
} else {
// Cache the attachment. This will allow us to send it, if the permissions are
// revoked
final String cachedFileUri =
AttachmentUtils.cacheAttachmentUri(context, uiAtt, attachmentFds);
// Convert external attachment to one of ours and add to the list
atts.add(convertUiAttachmentToAttachment(uiAtt));
atts.add(convertUiAttachmentToAttachment(uiAtt, cachedFileUri));
}
}
if (!atts.isEmpty()) {
@ -3734,7 +3746,8 @@ outer:
} else {
// This is tricky due to how messages/attachments are saved; rather than putz with
// what's changed, we'll delete/re-add them
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
final ArrayList<ContentProviderOperation> ops =
new ArrayList<ContentProviderOperation>();
// Delete all existing attachments
ops.add(ContentProviderOperation.newDelete(
ContentUris.withAppendedId(Attachment.MESSAGE_ID_URI, msg.mId))
@ -3752,18 +3765,18 @@ outer:
}
}
if (mailbox.mType == Mailbox.TYPE_OUTBOX) {
EmailServiceProxy service = EmailServiceUtils.getServiceForAccount(context,
final EmailServiceProxy service = EmailServiceUtils.getServiceForAccount(context,
mServiceCallback, mailbox.mAccountKey);
try {
service.startSync(mailbox.mId, true);
} catch (RemoteException e) {
}
long originalMsgId = msg.mSourceKey;
final long originalMsgId = msg.mSourceKey;
if (originalMsgId != 0) {
Message originalMsg = Message.restoreMessageWithId(context, originalMsgId);
final Message originalMsg = Message.restoreMessageWithId(context, originalMsgId);
// If the original message exists, set its forwarded/replied to flags
if (originalMsg != null) {
ContentValues cv = new ContentValues();
final ContentValues cv = new ContentValues();
flags = originalMsg.mFlags;
switch(draftType) {
case DraftType.FORWARD:
@ -3795,7 +3808,7 @@ outer:
if (mailbox == null) return null;
Message msg = getMessageFromPathSegments(pathSegments);
try {
return uiSaveMessage(msg, mailbox, values);
return uiSaveMessage(msg, mailbox, values, null);
} finally {
// Kick observers
getContext().getContentResolver().notifyChange(Mailbox.CONTENT_URI, null);
@ -3813,21 +3826,27 @@ outer:
Mailbox mailbox = getMailboxByAccountIdAndType(pathSegments.get(1), Mailbox.TYPE_DRAFTS);
if (mailbox == null) return null;
Message msg = getMessageFromPathSegments(pathSegments);
return uiSaveMessage(msg, mailbox, values);
return uiSaveMessage(msg, mailbox, values, null);
}
private Uri uiSaveDraftMessageBundle(Uri accountUri, Bundle extras) {
List<String> pathSegments = accountUri.getPathSegments();
Mailbox mailbox = getMailboxByAccountIdAndType(pathSegments.get(1), Mailbox.TYPE_DRAFTS);
final List<String> pathSegments = accountUri.getPathSegments();
final Mailbox mailbox =
getMailboxByAccountIdAndType(pathSegments.get(1), Mailbox.TYPE_DRAFTS);
if (mailbox == null) return null;
final ContentValues values = translateMessage(extras);
final Message msg = new Message();
return uiSaveMessage(msg, mailbox, values);
// Get the Bundle of open fds from the extra
final Bundle attachmentFds =
extras.getParcelable(UIProvider.SendOrSaveMethodParamKeys.OPENED_FD_MAP);
return uiSaveMessage(msg, mailbox, values, attachmentFds);
}
private Uri uiSendDraftMessageBundle(Uri uri, Bundle extras) {
final long accountId = Long.parseLong(uri.getPathSegments().get(1));
Context context = getContext();
final Context context = getContext();
final Message msg;
if (extras.containsKey(BaseColumns._ID)) {
final long messageId = extras.getLong(BaseColumns._ID);
@ -3837,12 +3856,16 @@ outer:
}
if (msg == null) return null;
long mailboxId = Mailbox.findMailboxOfType(context, accountId, Mailbox.TYPE_OUTBOX);
final long mailboxId = Mailbox.findMailboxOfType(context, accountId, Mailbox.TYPE_OUTBOX);
if (mailboxId == Mailbox.NO_MAILBOX) return null;
Mailbox mailbox = Mailbox.restoreMailboxWithId(context, mailboxId);
final Mailbox mailbox = Mailbox.restoreMailboxWithId(context, mailboxId);
if (mailbox == null) return null;
final ContentValues values = translateMessage(extras);
final Uri messageUri = uiSaveMessage(msg, mailbox, values);
// Get the Bundle of open fds from the extra
final Bundle attachmentFds =
extras.getParcelable(UIProvider.SendOrSaveMethodParamKeys.OPENED_FD_MAP);
final Uri messageUri = uiSaveMessage(msg, mailbox, values, attachmentFds);
// Kick observers
context.getContentResolver().notifyChange(Mailbox.CONTENT_URI, null);
return messageUri;
@ -3901,7 +3924,7 @@ outer:
if (msg == null) return 0;
Mailbox mailbox = Mailbox.restoreMailboxWithId(context, msg.mMailboxKey);
if (mailbox == null) return 0;
uiSaveMessage(msg, mailbox, values);
uiSaveMessage(msg, mailbox, values, null);
return 1;
}
@ -3914,7 +3937,7 @@ outer:
if (mailboxId == Mailbox.NO_MAILBOX) return 0;
Mailbox mailbox = Mailbox.restoreMailboxWithId(context, mailboxId);
if (mailbox == null) return 0;
uiSaveMessage(msg, mailbox, values);
uiSaveMessage(msg, mailbox, values, null);
// Kick observers
context.getContentResolver().notifyChange(Mailbox.CONTENT_URI, null);
return 1;

View File

@ -524,26 +524,28 @@ public abstract class EmailServiceStub extends IEmailService.Stub implements IEm
continue;
}
// 4. move to sent, or delete
Uri syncedUri =
final Uri syncedUri =
ContentUris.withAppendedId(EmailContent.Message.SYNCED_CONTENT_URI, messageId);
// Delete all cached files
AttachmentUtilities.deleteAllCachedAttachmentFiles(context, account.mId, messageId);
if (requireMoveMessageToSentFolder) {
// If this is a forwarded message and it has attachments, delete them, as they
// duplicate information found elsewhere (on the server). This saves storage.
EmailContent.Message msg =
final EmailContent.Message msg =
EmailContent.Message.restoreMessageWithId(context, messageId);
if (msg != null &&
((msg.mFlags & EmailContent.Message.FLAG_TYPE_FORWARD) != 0)) {
AttachmentUtilities.deleteAllAttachmentFiles(context, account.mId,
messageId);
}
int flags = msg.mFlags & ~(EmailContent.Message.FLAG_TYPE_REPLY |
final int flags = msg.mFlags & ~(EmailContent.Message.FLAG_TYPE_REPLY |
EmailContent.Message.FLAG_TYPE_FORWARD);
moveToSentValues.put(EmailContent.MessageColumns.FLAGS, flags);
resolver.update(syncedUri, moveToSentValues, null, null);
} else {
AttachmentUtilities.deleteAllAttachmentFiles(context, account.mId,
messageId);
Uri uri =
final Uri uri =
ContentUris.withAppendedId(EmailContent.Message.CONTENT_URI, messageId);
resolver.delete(uri, null, null);
resolver.delete(syncedUri, null, null);