Progress updates for POP3 message downloads

* Also, handle MessagingException when doing STAT

Change-Id: I5267b64f18a84fcc97fc2d003e49d4e373ea02c5
This commit is contained in:
Marc Blank 2012-08-03 16:02:55 -07:00
parent 10c7158254
commit 970fe5316b
3 changed files with 45 additions and 11 deletions

View File

@ -120,7 +120,7 @@ public class MimeMessage extends Message {
parse(in);
}
protected void parse(InputStream in) throws IOException, MessagingException {
private MimeStreamParser init() {
// Before parsing the input stream, clear all local fields that may be superceded by
// the new incoming message.
getMimeHeaders().clear();
@ -135,10 +135,22 @@ public class MimeMessage extends Message {
MimeStreamParser parser = new MimeStreamParser();
parser.setContentHandler(new MimeMessageBuilder());
return parser;
}
protected void parse(InputStream in) throws IOException, MessagingException {
MimeStreamParser parser = init();
parser.parse(new EOLConvertingInputStream(in));
mComplete = !parser.getPrematureEof();
}
public void parse(InputStream in, EOLConvertingInputStream.Callback callback)
throws IOException, MessagingException {
MimeStreamParser parser = init();
parser.parse(new EOLConvertingInputStream(in, getSize(), callback));
mComplete = !parser.getPrematureEof();
}
/**
* Return the internal mHeader value, with very lazy initialization.
* The goal is to save memory by not creating the headers until needed.

View File

@ -43,6 +43,8 @@ import com.android.emailcommon.utility.LoggingInputStream;
import com.android.emailcommon.utility.Utility;
import com.google.common.annotations.VisibleForTesting;
import org.apache.james.mime4j.EOLConvertingInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
@ -298,6 +300,8 @@ public class Pop3Store extends Store {
} else {
mMessageCount = Integer.parseInt(parts[1]);
}
} catch (MessagingException me) {
statException = me;
} catch (IOException ioe) {
statException = ioe;
} catch (NumberFormatException nfe) {
@ -596,15 +600,12 @@ public class Pop3Store extends Store {
* for any other value. If the server does not support TOP it is
* emulated with RETR and extra lines are thrown away.
*
* Note: Some servers (e.g. live.com) don't support CAPA, but turn out to
* support TOP after all. For better performance on these servers, we'll always
* probe TOP, and fall back to RETR when it's truly unsupported.
*
* @param message
* @param lines
* @param optional callback that reports progress of the fetch
*/
public void fetchBody(Pop3Message message, int lines)
throws IOException, MessagingException {
public void fetchBody(Pop3Message message, int lines,
EOLConvertingInputStream.Callback callback) throws IOException, MessagingException {
String response = null;
int messageId = mUidToMsgNumMap.get(message.getUid());
if (lines == -1) {
@ -644,7 +645,7 @@ public class Pop3Store extends Store {
if (DEBUG_LOG_RAW_STREAM && MailActivityEmail.DEBUG) {
in = new LoggingInputStream(in);
}
message.parse(new Pop3ResponseInputStream(in));
message.parse(new Pop3ResponseInputStream(in), callback);
}
catch (MessagingException me) {
/*

View File

@ -59,6 +59,8 @@ import com.android.mail.providers.UIProvider;
import com.android.mail.providers.UIProvider.AccountCapabilities;
import com.android.mail.providers.UIProvider.AttachmentState;
import org.apache.james.mime4j.EOLConvertingInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
@ -197,7 +199,8 @@ public class Pop3Service extends Service {
// We'll load them from most recent to oldest
for (int i = cnt - 1; i >= 0; i--) {
Pop3Message message = unsyncedMessages.get(i);
remoteFolder.fetchBody(message, Pop3Store.FETCH_BODY_SANE_SUGGESTED_SIZE / 76);
remoteFolder.fetchBody(message, Pop3Store.FETCH_BODY_SANE_SUGGESTED_SIZE / 76,
null);
int flag = EmailContent.Message.FLAG_LOADED_COMPLETE;
if (!message.isComplete()) {
flag = EmailContent.Message.FLAG_LOADED_UNKNOWN;
@ -213,6 +216,23 @@ public class Pop3Service extends Service {
}
}
private static class FetchCallback implements EOLConvertingInputStream.Callback {
private final ContentResolver mResolver;
private final Uri mAttachmentUri;
private final ContentValues mContentValues = new ContentValues();
FetchCallback(ContentResolver resolver, Uri attachmentUri) {
mResolver = resolver;
mAttachmentUri = attachmentUri;
}
@Override
public void report(int bytesRead) {
mContentValues.put(AttachmentColumns.UI_DOWNLOADED_SIZE, bytesRead);
mResolver.update(mAttachmentUri, mContentValues, null, null);
}
}
/**
* Synchronizer
*
@ -368,15 +388,16 @@ public class Pop3Service extends Service {
String uid = msg.mServerId;
Pop3Message popMessage = remoteUidMap.get(uid);
if (popMessage != null) {
Uri attUri = ContentUris.withAppendedId(Attachment.CONTENT_URI, att.mId);
try {
remoteFolder.fetchBody(popMessage, -1);
remoteFolder.fetchBody(popMessage, -1,
new FetchCallback(resolver, attUri));
} catch (IOException e) {
throw new MessagingException(MessagingException.IOERROR);
}
// Say we've downloaded the attachment
values.put(AttachmentColumns.UI_STATE, AttachmentState.SAVED);
Uri attUri = ContentUris.withAppendedId(Attachment.CONTENT_URI, att.mId);
resolver.update(attUri, values, null, null);
int flag = EmailContent.Message.FLAG_LOADED_COMPLETE;