From 08cd19e5a8b434a7251aff0803c194011a614c40 Mon Sep 17 00:00:00 2001 From: Daniel Applebaum Date: Thu, 17 Sep 2009 03:43:02 +0000 Subject: [PATCH] svn merge -x -w -c 760 ../issue4-1.X/ . Improve reliability of message viewing and composing while still using MessagingController worker queues svn merge -x -w -c 761 ../issue4-1.X/ . Put loading a message from the LocalStore into a ThreadPool executor, like was done previously in MessageView. Remote loading still goes through the work queue. --- .../android/email/MessagingController.java | 60 ++++++++++++------- .../email/activity/MessageCompose.java | 16 ++--- 2 files changed, 46 insertions(+), 30 deletions(-) diff --git a/src/com/android/email/MessagingController.java b/src/com/android/email/MessagingController.java index 0152b9577..1e5b7fa3c 100644 --- a/src/com/android/email/MessagingController.java +++ b/src/com/android/email/MessagingController.java @@ -15,6 +15,8 @@ import java.util.Set; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; @@ -106,6 +108,8 @@ public class MessagingController implements Runnable { private ConcurrentHashMap sendCount = new ConcurrentHashMap(); + private final ExecutorService threadPool = Executors.newFixedThreadPool(3); + public enum SORT_TYPE { SORT_DATE(R.string.sort_earliest_first, R.string.sort_latest_first, false), SORT_SUBJECT(R.string.sort_subject_alpha, R.string.sort_subject_re_alpha, true), @@ -287,10 +291,10 @@ public class MessagingController implements Runnable { if (command != null) { commandDescription = command.description; - Log.d(Email.LOG_TAG, "Running background command '" + command.description + "'"); + Log.i(Email.LOG_TAG, "Running background command '" + command.description + "'"); mBusy = true; command.runnable.run(); - Log.d(Email.LOG_TAG, "Background command '" + command.description + "' completed"); + Log.i(Email.LOG_TAG, "Background command '" + command.description + "' completed"); for (MessagingListener l : getListeners()) { l.controllerCommandCompleted(mCommands.size() > 0); } @@ -307,25 +311,20 @@ public class MessagingController implements Runnable { } private void put(String description, MessagingListener listener, Runnable runnable) { - try { - Command command = new Command(); - command.listener = listener; - command.runnable = runnable; - command.description = description; - mCommands.put(command); + putCommand(mCommands, description, listener, runnable); } - catch (InterruptedException ie) { - throw new Error(ie); - } - } - + private void putBackground(String description, MessagingListener listener, Runnable runnable) { + putCommand(backCommands, description, listener, runnable); + } + + private void putCommand(BlockingQueue queue, String description, MessagingListener listener, Runnable runnable) { try { Command command = new Command(); command.listener = listener; command.runnable = runnable; command.description = description; - backCommands.put(command); + queue.put(command); } catch (InterruptedException ie) { throw new Error(ie); @@ -1797,14 +1796,14 @@ public class MessagingController implements Runnable { markMessageRead(account, localFolder, message, true); } - if (listener != null) + if (listener != null && !getListeners().contains(listener)) { listener.loadMessageForViewBodyAvailable(account, folder, uid, message); } for (MessagingListener l : getListeners()) { l.loadMessageForViewBodyAvailable(account, folder, uid, message); } - if (listener != null) + if (listener != null && !getListeners().contains(listener)) { listener.loadMessageForViewFinished(account, folder, uid, message); } @@ -1816,6 +1815,10 @@ public class MessagingController implements Runnable { for (MessagingListener l : getListeners()) { l.loadMessageForViewFailed(account, folder, uid, e.getMessage()); } + if (listener != null && !getListeners().contains(listener)) + { + listener.loadMessageForViewFailed(account, folder, uid, e.getMessage()); + } addErrorMessage(account, e); } @@ -1843,10 +1846,17 @@ public class MessagingController implements Runnable { } public void loadMessageForView(final Account account, final String folder, final String uid, - MessagingListener listener) { + final MessagingListener listener) { for (MessagingListener l : getListeners()) { l.loadMessageForViewStarted(account, folder, uid); } + if (listener != null && !getListeners().contains(listener)) + { + listener.loadMessageForViewStarted(account, folder, uid); + } + threadPool.execute(new Runnable() { + public void run() { + try { Store localStore = Store.getInstance(account.getLocalStoreUri(), mApplication); LocalFolder localFolder = (LocalFolder) localStore.getFolder(folder); @@ -1857,7 +1867,7 @@ public class MessagingController implements Runnable { for (MessagingListener l : getListeners()) { l.loadMessageForViewHeadersAvailable(account, folder, uid, message); } - if (listener != null) + if (listener != null && !getListeners().contains(listener)) { listener.loadMessageForViewHeadersAvailable(account, folder, uid, message); } @@ -1874,7 +1884,7 @@ public class MessagingController implements Runnable { localFolder.fetch(new Message[] { message }, fp, null); - + localFolder.close(false); if (!message.isSet(Flag.SEEN)) { markMessageRead(account, localFolder, message, true); } @@ -1882,7 +1892,7 @@ public class MessagingController implements Runnable { for (MessagingListener l : getListeners()) { l.loadMessageForViewBodyAvailable(account, folder, uid, message); } - if (listener != null) + if (listener != null && !getListeners().contains(listener)) { listener.loadMessageForViewBodyAvailable(account, folder, uid, message); } @@ -1890,19 +1900,25 @@ public class MessagingController implements Runnable { for (MessagingListener l : getListeners()) { l.loadMessageForViewFinished(account, folder, uid, message); } - if (listener != null) + if (listener != null && !getListeners().contains(listener)) { listener.loadMessageForViewFinished(account, folder, uid, message); } - localFolder.close(false); + } catch (Exception e) { for (MessagingListener l : getListeners()) { l.loadMessageForViewFailed(account, folder, uid, e.getMessage()); } + if (listener != null && !getListeners().contains(listener)) + { + listener.loadMessageForViewFailed(account, folder, uid, e.getMessage()); + } addErrorMessage(account, e); } + } + }); } // public void loadMessageForViewSynchronous(final Account account, final String folder, final String uid, diff --git a/src/com/android/email/activity/MessageCompose.java b/src/com/android/email/activity/MessageCompose.java index 5cd401cfe..32552fa25 100644 --- a/src/com/android/email/activity/MessageCompose.java +++ b/src/com/android/email/activity/MessageCompose.java @@ -500,14 +500,6 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc updateFrom(); updateSignature(); - Log.d(Email.LOG_TAG, "action = " + action + ", mAccount = " + mAccount + ", mFolder = " + mFolder + ", mSourceMessageUid = " + mSourceMessageUid); - if ((ACTION_REPLY.equals(action) || ACTION_REPLY_ALL.equals(action)) && mAccount != null && mFolder != null && mSourceMessageUid != null) { - Log.d(Email.LOG_TAG, "Setting message ANSWERED flag to true"); - // TODO: Really, we should wait until we send the message, but that would require saving the original - // message info along with a Draft copy, in case it is left in Drafts for a while before being sent - MessagingController.getInstance(getApplication()).setMessageFlag(mAccount, mFolder, mSourceMessageUid, Flag.ANSWERED, true); - } - if (ACTION_REPLY.equals(action) || ACTION_REPLY_ALL.equals(action) || ACTION_FORWARD.equals(action) || ACTION_EDIT_DRAFT.equals(action)) { /* * If we need to load the message we add ourself as a message listener here @@ -527,6 +519,14 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc addAddress(mBccView, new Address(mAccount.getAlwaysBcc(), "")); } + Log.d(Email.LOG_TAG, "action = " + action + ", mAccount = " + mAccount + ", mFolder = " + mFolder + ", mSourceMessageUid = " + mSourceMessageUid); + if ((ACTION_REPLY.equals(action) || ACTION_REPLY_ALL.equals(action)) && mAccount != null && mFolder != null && mSourceMessageUid != null) { + Log.d(Email.LOG_TAG, "Setting message ANSWERED flag to true"); + // TODO: Really, we should wait until we send the message, but that would require saving the original + // message info along with a Draft copy, in case it is left in Drafts for a while before being sent + MessagingController.getInstance(getApplication()).setMessageFlag(mAccount, mFolder, mSourceMessageUid, Flag.ANSWERED, true); + } + updateTitle(); }