diff --git a/src/com/android/email/Controller.java b/src/com/android/email/Controller.java index 78b770709..0df020aec 100644 --- a/src/com/android/email/Controller.java +++ b/src/com/android/email/Controller.java @@ -42,6 +42,7 @@ import android.util.Log; import java.io.File; import java.util.HashSet; +import java.util.concurrent.ConcurrentHashMap; /** * New central controller/dispatcher for Email activities that may require remote operations. @@ -70,6 +71,10 @@ public class Controller { }; private static int MESSAGEID_TO_MAILBOXID_COLUMN_MAILBOXID = 1; + /** Cache used by {@link #getServiceForAccount} */ + private final ConcurrentHashMap mAccountToService + = new ConcurrentHashMap(); + protected Controller(Context _context) { mContext = _context.getApplicationContext(); mProviderContext = _context; @@ -777,18 +782,28 @@ public class Controller { /** * For a given account id, return a service proxy if applicable, or null. * - * TODO this should use a cache because we'll be doing this a lot - * * @param accountId the message of interest * @result service proxy, or null if n/a */ private IEmailService getServiceForAccount(long accountId) { - // TODO make this more efficient, caching the account, MUCH smaller lookup here, etc. + // First, try cache. + final Object value = mAccountToService.get(accountId); + if (value != null) { + if (value instanceof IEmailService) { + return (IEmailService) value; + } else { + return null; + } + } Account account = EmailContent.Account.restoreAccountWithId(mProviderContext, accountId); if (account == null || isMessagingController(account)) { + // Put any non-IEmailService object to indicate it uses the legacy controller. + mAccountToService.put(accountId, ""); return null; } else { - return ExchangeUtils.getExchangeEmailService(mContext, mServiceCallback); + IEmailService s = ExchangeUtils.getExchangeEmailService(mContext, mServiceCallback); + mAccountToService.put(accountId, s); + return s; } } @@ -811,6 +826,15 @@ public class Controller { return ("pop3".equals(scheme) || "imap".equals(scheme)); } + /** + * This method should be called when an account is deleted. + * + * TODO: Make it really delete accounts and remove DeleteAccountTask. + */ + public void deleteAccount(long accountId) { + mAccountToService.remove(accountId); + } + /** * Simple callback for synchronous commands. For many commands, this can be largely ignored * and the result is observed via provider cursors. The callback will *not* necessarily be