diff --git a/src/com/android/email/MessagingController.java b/src/com/android/email/MessagingController.java index a2051c78a..b58882c34 100644 --- a/src/com/android/email/MessagingController.java +++ b/src/com/android/email/MessagingController.java @@ -1232,15 +1232,42 @@ public class MessagingController implements Runnable { Folder remoteFolder = remoteStore.getFolder(folder); remoteFolder.open(OpenMode.READ_WRITE, localFolder.getPersistentCallbacks()); - // Get the remote message and fully download it - Message remoteMessage = remoteFolder.getMessage(uid); + // Get the remote message and fully download it (and save into local store) + + if (remoteStore.requireStructurePrefetch()) { + // For remote stores that require it, prefetch the message structure. + FetchProfile fp = new FetchProfile(); + fp.add(FetchProfile.Item.STRUCTURE); + localFolder.fetch(new Message[] { message }, fp, null); + + ArrayList viewables = new ArrayList(); + ArrayList attachments = new ArrayList(); + MimeUtility.collectParts(message, viewables, attachments); + fp.clear(); + for (Part part : viewables) { + fp.add(part); + } + + remoteFolder.fetch(new Message[] { message }, fp, null); + + // Store the updated message locally + localFolder.updateMessage((LocalMessage)message); + + } else { + // Most remote stores can directly obtain the message using only uid + Message remoteMessage = remoteFolder.getMessage(uid); + FetchProfile fp = new FetchProfile(); + fp.add(FetchProfile.Item.BODY); + remoteFolder.fetch(new Message[] { remoteMessage }, fp, null); + + // Store the message locally + localFolder.appendMessages(new Message[] { remoteMessage }); + } + + // Now obtain the local copy for further access & manipulation + message = localFolder.getMessage(uid); FetchProfile fp = new FetchProfile(); fp.add(FetchProfile.Item.BODY); - remoteFolder.fetch(new Message[] { remoteMessage }, fp, null); - - // Store the message locally and load the stored message into memory - localFolder.appendMessages(new Message[] { remoteMessage }); - message = localFolder.getMessage(uid); localFolder.fetch(new Message[] { message }, fp, null); // This is a view message request, so mark it read diff --git a/src/com/android/email/mail/Store.java b/src/com/android/email/mail/Store.java index e742ef09f..2774f20f3 100644 --- a/src/com/android/email/mail/Store.java +++ b/src/com/android/email/mail/Store.java @@ -200,6 +200,17 @@ public abstract class Store { return null; } + /** + * Some stores cannot download a message based only on the uid, and need the message structure + * to be preloaded and provided to them. This method allows a remote store to signal this + * requirement. Most stores do not need this and do not need to overload this method, which + * simply returns "false" in the base class. + * @return Return true if the remote store requires structure prefetch + */ + public boolean requireStructurePrefetch() { + return false; + } + public abstract Folder getFolder(String name) throws MessagingException; public abstract Folder[] getPersonalNamespaces() throws MessagingException; diff --git a/src/com/android/email/mail/exchange/ExchangeStoreExample.java b/src/com/android/email/mail/exchange/ExchangeStoreExample.java index 45ba4fae7..acaaddf2e 100644 --- a/src/com/android/email/mail/exchange/ExchangeStoreExample.java +++ b/src/com/android/email/mail/exchange/ExchangeStoreExample.java @@ -164,5 +164,15 @@ public class ExchangeStoreExample extends Store { public StoreSynchronizer getMessageSynchronizer() { return null; } + + /** + * Inform MessagingController that this store requires message structures to be prefetched + * before it can fetch message bodies (this is due to EAS protocol restrictions.) + * @return always true for EAS + */ + @Override + public boolean requireStructurePrefetch() { + return true; + } }