Handle inline images in EmailProvider
* Automatically prefetch these attachments * Use AttachmentProvider properly (to get output stream) Bug: 6437156 Change-Id: I6f594e3b9b6286cb19d7fb7390aa6979ba492c22
This commit is contained in:
parent
cf1a862526
commit
21102f6323
@ -32,6 +32,8 @@ import android.webkit.MimeTypeMap;
|
||||
import com.android.emailcommon.Logging;
|
||||
import com.android.emailcommon.provider.EmailContent.Attachment;
|
||||
import com.android.emailcommon.provider.EmailContent.AttachmentColumns;
|
||||
import com.android.emailcommon.provider.EmailContent.Body;
|
||||
import com.android.emailcommon.provider.EmailContent.BodyColumns;
|
||||
import com.android.emailcommon.provider.EmailContent.Message;
|
||||
import com.android.emailcommon.provider.EmailContent.MessageColumns;
|
||||
import com.android.mail.providers.UIProvider;
|
||||
@ -42,6 +44,7 @@ import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class AttachmentUtilities {
|
||||
public static final String AUTHORITY = "com.android.email.attachmentprovider";
|
||||
@ -361,8 +364,7 @@ public class AttachmentUtilities {
|
||||
}
|
||||
}
|
||||
|
||||
private static long copyFile(InputStream in, File file) throws IOException {
|
||||
FileOutputStream out = new FileOutputStream(file);
|
||||
private static long copyFile(InputStream in, OutputStream out) throws IOException {
|
||||
long size = IOUtils.copy(in, out);
|
||||
in.close();
|
||||
out.flush();
|
||||
@ -378,24 +380,20 @@ public class AttachmentUtilities {
|
||||
ContentValues cv = new ContentValues();
|
||||
long attachmentId = attachment.mId;
|
||||
long accountId = attachment.mAccountKey;
|
||||
String contentUri;
|
||||
String contentUri = null;
|
||||
long size;
|
||||
try {
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
if (attachment.mUiDestination == UIProvider.AttachmentDestination.CACHE) {
|
||||
File saveIn = getAttachmentDirectory(context, accountId);
|
||||
if (!saveIn.exists()) {
|
||||
saveIn.mkdirs();
|
||||
}
|
||||
File file = getAttachmentFilename(context, accountId, attachmentId);
|
||||
file.createNewFile();
|
||||
size = copyFile(in, file);
|
||||
contentUri = getAttachmentUri(accountId, attachmentId).toString();
|
||||
Uri attUri = getAttachmentUri(accountId, attachmentId);
|
||||
size = copyFile(in, resolver.openOutputStream(attUri));
|
||||
contentUri = attUri.toString();
|
||||
} else if (Utility.isExternalStorageMounted()) {
|
||||
File downloads = Environment.getExternalStoragePublicDirectory(
|
||||
Environment.DIRECTORY_DOWNLOADS);
|
||||
downloads.mkdirs();
|
||||
File file = Utility.createUniqueFile(downloads, attachment.mFileName);
|
||||
size = copyFile(in, file);
|
||||
size = copyFile(in, new FileOutputStream(file));
|
||||
String absolutePath = file.getAbsolutePath();
|
||||
|
||||
// Although the download manager can scan media files, scanning only happens
|
||||
@ -428,5 +426,20 @@ public class AttachmentUtilities {
|
||||
}
|
||||
context.getContentResolver().update(uri, cv, null, null);
|
||||
|
||||
// If this is an inline attachment, update the body
|
||||
if (contentUri != null && attachment.mContentId != null) {
|
||||
Body body = Body.restoreBodyWithMessageId(context, attachment.mMessageKey);
|
||||
if (body != null && body.mHtmlContent != null) {
|
||||
cv.clear();
|
||||
String html = body.mHtmlContent;
|
||||
String contentIdRe =
|
||||
"\\s+(?i)src=\"cid(?-i):\\Q" + attachment.mContentId + "\\E\"";
|
||||
String srcContentUri = " src=\"" + contentUri + "\"";
|
||||
html = html.replaceAll(contentIdRe, srcContentUri);
|
||||
cv.put(BodyColumns.HTML_CONTENT, html);
|
||||
context.getContentResolver().update(
|
||||
ContentUris.withAppendedId(Body.CONTENT_URI, body.mId), cv, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2333,6 +2333,9 @@ outer:
|
||||
ArrayList<com.android.mail.providers.Attachment> uiAtts =
|
||||
new ArrayList<com.android.mail.providers.Attachment>();
|
||||
for (Attachment att : atts) {
|
||||
if (att.mContentId != null && att.mContentUri != null) {
|
||||
continue;
|
||||
}
|
||||
com.android.mail.providers.Attachment uiAtt =
|
||||
new com.android.mail.providers.Attachment();
|
||||
uiAtt.name = att.mFileName;
|
||||
|
@ -352,25 +352,28 @@ public class AttachmentDownloadService extends Service implements Runnable {
|
||||
// We'll load up the newest 25 attachments that aren't loaded or queued
|
||||
Uri lookupUri = EmailContent.uriWithLimit(Attachment.CONTENT_URI,
|
||||
MAX_ATTACHMENTS_TO_CHECK);
|
||||
Cursor c = mContext.getContentResolver().query(lookupUri, AttachmentInfo.PROJECTION,
|
||||
Cursor c = mContext.getContentResolver().query(lookupUri,
|
||||
Attachment.CONTENT_PROJECTION,
|
||||
EmailContent.Attachment.PRECACHE_INBOX_SELECTION,
|
||||
null, Attachment.RECORD_ID + " DESC");
|
||||
File cacheDir = mContext.getCacheDir();
|
||||
try {
|
||||
while (c.moveToNext()) {
|
||||
long accountKey = c.getLong(AttachmentInfo.COLUMN_ACCOUNT_KEY);
|
||||
long id = c.getLong(AttachmentInfo.COLUMN_ID);
|
||||
Account account = Account.restoreAccountWithId(mContext, accountKey);
|
||||
Attachment att = new Attachment();
|
||||
att.restore(c);
|
||||
Account account = Account.restoreAccountWithId(mContext, att.mAccountKey);
|
||||
if (account == null) {
|
||||
// Clean up this orphaned attachment; there's no point in keeping it
|
||||
// around; then try to find another one
|
||||
EmailContent.delete(mContext, Attachment.CONTENT_URI, id);
|
||||
} else if (canPrefetchForAccount(account, cacheDir)) {
|
||||
EmailContent.delete(mContext, Attachment.CONTENT_URI, att.mId);
|
||||
} else {
|
||||
// Check that the attachment meets system requirements for download
|
||||
AttachmentInfo info = new AttachmentInfo(mContext, c);
|
||||
AttachmentInfo info = new AttachmentInfo(mContext, att);
|
||||
if (info.isEligibleForDownload()) {
|
||||
Attachment att = Attachment.restoreAttachmentWithId(mContext, id);
|
||||
if (att != null) {
|
||||
// Either the account must be able to prefetch or this must be
|
||||
// an inline attachment
|
||||
if (att.mContentId != null ||
|
||||
(canPrefetchForAccount(account, cacheDir))) {
|
||||
Integer tryCount;
|
||||
tryCount = mAttachmentFailureMap.get(att.mId);
|
||||
if (tryCount != null && tryCount > MAX_DOWNLOAD_RETRIES) {
|
||||
|
Loading…
Reference in New Issue
Block a user