diff --git a/res/values/strings.xml b/res/values/strings.xml index 7216f25f6..5dda66ca3 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -289,7 +289,7 @@ Welcome to K-9 Mail setup. K-9 is an open source mail client for Android origin Mark as read on server IMAP path prefix - Optional + (Automatic using NAMESPACE if available) Drafts folder name Sent folder name diff --git a/src/com/android/email/Account.java b/src/com/android/email/Account.java index 6c374caec..3bf731413 100644 --- a/src/com/android/email/Account.java +++ b/src/com/android/email/Account.java @@ -831,6 +831,12 @@ public class Account implements Serializable } return super.equals(o); } + + @Override + public int hashCode() + { + return mUuid.hashCode(); + } public FolderMode getFolderDisplayMode() { diff --git a/src/com/android/email/MessagingController.java b/src/com/android/email/MessagingController.java index eb989ece1..5a23f6e13 100644 --- a/src/com/android/email/MessagingController.java +++ b/src/com/android/email/MessagingController.java @@ -3995,147 +3995,15 @@ public class MessagingController implements Runnable return pushers.values(); } - public Pusher setupPushing(final Account account) + public boolean setupPushing(final Account account) { - Pusher pusher = pushers.get(account); - if (pusher != null) - { - return pusher; - } - Store store = null; try { - store = Store.getInstance(account.getStoreUri(), mApplication); - if (store.isPushCapable() == false) + Pusher previousPusher = pushers.remove(account); + if (previousPusher != null) { - Log.i(Email.LOG_TAG, "Account " + account.getDescription() + " is not push capable, skipping"); - return null; + previousPusher.stop(); } - } - catch (Exception e) - { - Log.e(Email.LOG_TAG, "Could not get remote store", e); - return null; - } - final MessagingController controller = this; - PushReceiver receiver = new PushReceiver() - { - ThreadLocal threadWakeLock = new ThreadLocal(); - public void acquireWakeLock() - { - WakeLock wakeLock = threadWakeLock.get(); - if (wakeLock == null) - { - PowerManager pm = (PowerManager) mApplication.getSystemService(Context.POWER_SERVICE); - wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Email"); - wakeLock.setReferenceCounted(false); - threadWakeLock.set(wakeLock); - } - wakeLock.acquire(Email.PUSH_WAKE_LOCK_TIMEOUT); - if (Email.DEBUG) - { - Log.d(Email.LOG_TAG, "Acquired WakeLock for Pushing for thread " + Thread.currentThread().getName()); - } - } - - public void releaseWakeLock() - { - if (Email.DEBUG) - { - Log.d(Email.LOG_TAG, "Considering releasing WakeLock for Pushing"); - } - WakeLock wakeLock = threadWakeLock.get(); - if (wakeLock != null) - { - - if (Email.DEBUG) - { - Log.d(Email.LOG_TAG, "Releasing WakeLock for Pushing for thread " + Thread.currentThread().getName()); - } - wakeLock.release(); - } - else - { - Log.e(Email.LOG_TAG, "No WakeLock waiting to be released for thread " + Thread.currentThread().getName()); - } - } - - public void messagesFlagsChanged(Folder folder, - List messages) - { - controller.messagesArrived(account, folder, messages, true); - - } - public void messagesArrived(Folder folder, List messages) - { - controller.messagesArrived(account, folder, messages, false); - } - - public void sleep(long millis) - { - SleepService.sleep(mApplication, millis, threadWakeLock.get(), Email.PUSH_WAKE_LOCK_TIMEOUT); - } - - public void pushError(String errorMessage, Exception e) - { - String errMess = errorMessage; - String body = null; - - if (errMess == null && e != null) - { - errMess = e.getMessage(); - } - body = errMess; - if (e != null) - { - body = e.toString(); - } - controller.addErrorMessage(account, errMess, body); - } - - public String getPushState(String folderName) - { - LocalFolder localFolder = null; - try - { - LocalStore localStore = (LocalStore) Store.getInstance(account.getLocalStoreUri(), mApplication); - localFolder= (LocalFolder) localStore.getFolder(folderName); - localFolder.open(OpenMode.READ_WRITE); - return localFolder.getPushState(); - } - catch (Exception e) - { - Log.e(Email.LOG_TAG, "Unable to get push state from account " + account.getDescription() - + ", folder " + folderName, e); - return null; - } - finally - { - if (localFolder != null) - { - try - { - localFolder.close(false); - } - catch (Exception e) - { - Log.e(Email.LOG_TAG, "Unable to close folder '" + folderName + "' in account " + account.getDescription(), e); - } - } - } - } - - public void setPushActive(String folderName, boolean enabled) - { - for (MessagingListener l : getListeners()) - { - l.setPushActive(account, folderName, enabled); - } - } - - }; - try - { Preferences prefs = Preferences.getPreferences(mApplication); Account.FolderMode aDisplayMode = account.getFolderDisplayMode(); @@ -4178,19 +4046,46 @@ public class MessagingController implements Runnable Log.i(Email.LOG_TAG, "Starting pusher for " + account.getDescription() + ":" + folder.getName()); names.add(folder.getName()); } + if (names.size() > 0) { - pusher = store.getPusher(receiver, names); - if (pusher != null) + PushReceiver receiver = new MessagingControllerPushReceiver(mApplication, account, this); + + try { - pushers.put(account, pusher); + Store store = Store.getInstance(account.getStoreUri(), mApplication); + if (store.isPushCapable() == false) + { + Log.i(Email.LOG_TAG, "Account " + account.getDescription() + " is not push capable, skipping"); + return false; + } + Pusher pusher = store.getPusher(receiver); + Pusher oldPusher = null; + if (pusher != null) + { + oldPusher = pushers.putIfAbsent(account, pusher); + } + if (oldPusher != null) + { + pusher = oldPusher; + } + else + { + pusher.start(names); + } } - return pusher; + catch (Exception e) + { + Log.e(Email.LOG_TAG, "Could not get remote store", e); + return false; + } + + return true; } else { Log.i(Email.LOG_TAG, "No folders are configured for pushing in account " + account.getDescription()); - return null; + return false; } } @@ -4198,16 +4093,7 @@ public class MessagingController implements Runnable { Log.e(Email.LOG_TAG, "Got exception while setting up pushing", e); } - return null; - } - - public void stopPushing(Account account) - { - Pusher pusher = pushers.remove(account); - if (pusher != null) - { - pusher.stop(); - } + return false; } public void stopAllPushing() @@ -4220,7 +4106,6 @@ public class MessagingController implements Runnable iter.remove(); pusher.stop(); } - } public void messagesArrived(final Account account, final Folder remoteFolder, final List messages, final boolean flagSyncOnly) @@ -4239,7 +4124,6 @@ public class MessagingController implements Runnable LocalStore localStore = (LocalStore) Store.getInstance(account.getLocalStoreUri(), mApplication); localFolder= (LocalFolder) localStore.getFolder(remoteFolder.getName()); localFolder.open(OpenMode.READ_WRITE); - remoteFolder.open(OpenMode.READ_WRITE); int newCount = downloadMessages(account, remoteFolder, localFolder, messages, flagSyncOnly); setLocalUnreadCountToRemote(localFolder, remoteFolder, messages.size()); diff --git a/src/com/android/email/MessagingControllerPushReceiver.java b/src/com/android/email/MessagingControllerPushReceiver.java new file mode 100644 index 000000000..d9d96cdde --- /dev/null +++ b/src/com/android/email/MessagingControllerPushReceiver.java @@ -0,0 +1,145 @@ +package com.android.email; + +import java.util.List; + +import android.app.Application; +import android.content.Context; +import android.os.PowerManager; +import android.os.PowerManager.WakeLock; +import android.util.Log; + +import com.android.email.mail.Folder; +import com.android.email.mail.Message; +import com.android.email.mail.PushReceiver; +import com.android.email.mail.Store; +import com.android.email.mail.Folder.OpenMode; +import com.android.email.mail.store.LocalStore; +import com.android.email.mail.store.LocalStore.LocalFolder; +import com.android.email.service.SleepService; + +public class MessagingControllerPushReceiver implements PushReceiver +{ + final Account account; + final MessagingController controller; + final Application mApplication; + + public MessagingControllerPushReceiver(Application nApplication, Account nAccount, MessagingController nController) + { + account = nAccount; + controller = nController; + mApplication = nApplication; + } + ThreadLocal threadWakeLock = new ThreadLocal(); + public void acquireWakeLock() + { + WakeLock wakeLock = threadWakeLock.get(); + if (wakeLock == null) + { + PowerManager pm = (PowerManager) mApplication.getSystemService(Context.POWER_SERVICE); + wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Email"); + wakeLock.setReferenceCounted(false); + threadWakeLock.set(wakeLock); + } + wakeLock.acquire(Email.PUSH_WAKE_LOCK_TIMEOUT); + if (Email.DEBUG) + { + Log.d(Email.LOG_TAG, "Acquired WakeLock for Pushing for thread " + Thread.currentThread().getName()); + } + } + + public void releaseWakeLock() + { + if (Email.DEBUG) + { + Log.d(Email.LOG_TAG, "Considering releasing WakeLock for Pushing"); + } + WakeLock wakeLock = threadWakeLock.get(); + if (wakeLock != null) + { + + if (Email.DEBUG) + { + Log.d(Email.LOG_TAG, "Releasing WakeLock for Pushing for thread " + Thread.currentThread().getName()); + } + wakeLock.release(); + } + else + { + Log.e(Email.LOG_TAG, "No WakeLock waiting to be released for thread " + Thread.currentThread().getName()); + } + } + + public void messagesFlagsChanged(Folder folder, + List messages) + { + controller.messagesArrived(account, folder, messages, true); + + } + public void messagesArrived(Folder folder, List messages) + { + controller.messagesArrived(account, folder, messages, false); + } + + public void sleep(long millis) + { + SleepService.sleep(mApplication, millis, threadWakeLock.get(), Email.PUSH_WAKE_LOCK_TIMEOUT); + } + + public void pushError(String errorMessage, Exception e) + { + String errMess = errorMessage; + String body = null; + + if (errMess == null && e != null) + { + errMess = e.getMessage(); + } + body = errMess; + if (e != null) + { + body = e.toString(); + } + controller.addErrorMessage(account, errMess, body); + } + + public String getPushState(String folderName) + { + LocalFolder localFolder = null; + try + { + LocalStore localStore = (LocalStore) Store.getInstance(account.getLocalStoreUri(), mApplication); + localFolder= (LocalFolder) localStore.getFolder(folderName); + localFolder.open(OpenMode.READ_WRITE); + return localFolder.getPushState(); + } + catch (Exception e) + { + Log.e(Email.LOG_TAG, "Unable to get push state from account " + account.getDescription() + + ", folder " + folderName, e); + return null; + } + finally + { + if (localFolder != null) + { + try + { + localFolder.close(false); + } + catch (Exception e) + { + Log.e(Email.LOG_TAG, "Unable to close folder '" + folderName + "' in account " + account.getDescription(), e); + } + } + } + } + + public void setPushActive(String folderName, boolean enabled) + { + for (MessagingListener l : controller.getListeners()) + { + l.setPushActive(account, folderName, enabled); + } + } + +} diff --git a/src/com/android/email/mail/Pusher.java b/src/com/android/email/mail/Pusher.java index e2f942558..37d095b88 100644 --- a/src/com/android/email/mail/Pusher.java +++ b/src/com/android/email/mail/Pusher.java @@ -1,9 +1,11 @@ package com.android.email.mail; +import java.util.List; + public interface Pusher { - public void start(); + public void start(List folderNames); public void refresh(); public void stop(); /** diff --git a/src/com/android/email/mail/Store.java b/src/com/android/email/mail/Store.java index 6411ba419..db47dc9f1 100644 --- a/src/com/android/email/mail/Store.java +++ b/src/com/android/email/mail/Store.java @@ -113,7 +113,7 @@ public abstract class Store { } - public Pusher getPusher(PushReceiver receiver, List names) + public Pusher getPusher(PushReceiver receiver) { return null; } diff --git a/src/com/android/email/mail/store/ImapStore.java b/src/com/android/email/mail/store/ImapStore.java index 082cb2bcb..280758bdc 100644 --- a/src/com/android/email/mail/store/ImapStore.java +++ b/src/com/android/email/mail/store/ImapStore.java @@ -33,6 +33,7 @@ import java.util.List; import java.util.Set; import java.util.StringTokenizer; import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; @@ -99,14 +100,20 @@ public class ImapStore extends Store private static final int IDLE_REFRESH_INTERVAL = 20 * 60 * 1000; // 20 minutes private static final Flag[] PERMANENT_FLAGS = { Flag.DELETED, Flag.SEEN }; + + private static final String CAPABILITY_IDLE = "IDLE"; + private static final String COMMAND_IDLE = "IDLE"; + private static final String CAPABILITY_NAMESPACE = "NAMESPACE"; + private static final String COMMAND_NAMESPACE = "NAMESPACE"; private String mHost; private int mPort; private String mUsername; private String mPassword; private int mConnectionSecurity; - private String mPathPrefix; - private String mPathDelimeter; + private volatile String mPathPrefix; + private volatile String mCombinedPrefix = null; + private volatile String mPathDelimeter; private LinkedList mConnections = new LinkedList(); @@ -196,6 +203,10 @@ public class ImapStore extends Store if ((uri.getPath() != null) && (uri.getPath().length() > 0)) { mPathPrefix = uri.getPath().substring(1); + if (mPathPrefix != null && mPathPrefix.trim().length() == 0) + { + mPathPrefix = null; + } } mModifiedUtf7Charset = new CharsetProvider().charsetForName("X-RFC-3501"); @@ -217,6 +228,34 @@ public class ImapStore extends Store return folder; } + private String getCombinedPrefix() + { + if (mCombinedPrefix == null) + { + if (mPathPrefix != null) + { + String tmpPrefix = mPathPrefix.trim(); + String tmpDelim = (mPathDelimeter != null ? mPathDelimeter.trim() : ""); + if (tmpPrefix.endsWith(tmpDelim)) + { + mCombinedPrefix = tmpPrefix; + } + else if (tmpPrefix.length() > 0) + { + mCombinedPrefix = tmpPrefix + tmpDelim; + } + else + { + mCombinedPrefix = ""; + } + } + else + { + mCombinedPrefix = ""; + } + } + return mCombinedPrefix; + } @Override public Folder[] getPersonalNamespaces() throws MessagingException @@ -225,13 +264,10 @@ public class ImapStore extends Store try { ArrayList folders = new ArrayList(); - if (mPathPrefix == null) - { - mPathPrefix = ""; - } + List responses = connection.executeSimpleCommand(String.format("LIST \"\" \"%s*\"", - mPathPrefix)); + getCombinedPrefix())); for (ImapResponse response : responses) { @@ -243,6 +279,7 @@ public class ImapStore extends Store if (mPathDelimeter == null) { mPathDelimeter = response.getString(2); + mCombinedPrefix = null; } if (folder.equalsIgnoreCase(Email.INBOX)) @@ -251,13 +288,14 @@ public class ImapStore extends Store } else { - if (mPathPrefix.length() > 0) + + if (getCombinedPrefix().length() > 0) { - if (folder.length() >= mPathPrefix.length() + 1) + if (folder.length() >= getCombinedPrefix().length()) { - folder = folder.substring(mPathPrefix.length() + 1); + folder = folder.substring(getCombinedPrefix().length()); } - if (!decodeFolderName(response.getString(3)).equals(mPathPrefix + mPathDelimeter + folder)) + if (!decodeFolderName(response.getString(3)).equals(getCombinedPrefix() + folder)) { includeFolder = false; } @@ -406,12 +444,7 @@ public class ImapStore extends Store return true; } - @Override - public Pusher getPusher(PushReceiver receiver, List names) - { - return new ImapPusher(this, receiver, names); - } - + class ImapFolder extends Folder { private String mName; @@ -433,18 +466,7 @@ public class ImapStore extends Store String prefixedName = ""; if (!Email.INBOX.equalsIgnoreCase(mName)) { - String prefix = mPathPrefix; - String delim = mPathDelimeter; - - if (prefix != null && delim != null) - { - prefix = prefix.trim(); - delim = delim.trim(); - if (prefix.length() > 0 && delim.length() > 0) - { - prefixedName += mPathPrefix + mPathDelimeter; - } - } + prefixedName = getCombinedPrefix(); } prefixedName += mName; @@ -503,7 +525,7 @@ public class ImapStore extends Store // 2 OK [READ-WRITE] Select completed. try { - + if (mPathDelimeter == null) { List nameResponses = @@ -512,7 +534,7 @@ public class ImapStore extends Store { if (response.get(0).equals("LIST")) { - mPathDelimeter = nameResponses.get(0).getString(2); + mPathDelimeter = response.getString(2); if (Email.DEBUG) { Log.d(Email.LOG_TAG, "Got path delimeter '" + mPathDelimeter + "' for " + getLogId()); @@ -1168,6 +1190,37 @@ public class ImapStore extends Store } return responses; } + + protected void handlePossibleUidNext(ImapResponse response) + { + if (response.get(0).equals("OK") && response.size() > 1) + { + Object bracketedObj = response.get(1); + if (bracketedObj instanceof ImapList) + { + ImapList bracketed = (ImapList)bracketedObj; + + if (bracketed.size() > 1) + { + Object keyObj = bracketed.get(0); + if (keyObj instanceof String) + { + String key = (String)keyObj; + if ("UIDNEXT".equals(key)) + { + uidNext = bracketed.getNumber(1); + if (Email.DEBUG) + { + Log.d(Email.LOG_TAG, "Got UidNext = " + uidNext + " for " + getLogId()); + } + } + } + } + + + } + } + } /** * Handle an untagged response that the caller doesn't care to handle themselves. @@ -1186,34 +1239,9 @@ public class ImapStore extends Store Log.d(Email.LOG_TAG, "Got untagged EXISTS with value " + mMessageCount + " for " + getLogId()); } } - if (response.get(0).equals("OK") && response.size() > 1) - { - Object bracketedObj = response.get(1); - if (bracketedObj instanceof ImapList) - { - ImapList bracketed = (ImapList)bracketedObj; - - if (bracketed.size() > 1) - { - Object keyObj = bracketed.get(0); - if (keyObj instanceof String) - { - String key = (String)keyObj; - if ("UIDNEXT".equals(key)) - { - uidNext = bracketed.getNumber(1); - if (Email.DEBUG) - { - Log.d(Email.LOG_TAG, "Got UidNext = " + uidNext + " for " + getLogId()); - } - } - } - } - - - } - } - else if (response.get(1).equals("EXPUNGE") && mMessageCount > 0) + handlePossibleUidNext(response); + + if (response.get(1).equals("EXPUNGE") && mMessageCount > 0) { mMessageCount--; if (Email.DEBUG) @@ -1873,6 +1901,61 @@ public class ImapStore extends Store { throw new AuthenticationFailedException(null, me); } + if (Email.DEBUG) + { + Log.d(Email.LOG_TAG, "NAMESPACE = " + hasCapability(CAPABILITY_NAMESPACE) + + ", mPathPrefix = " + mPathPrefix); + } + if (mPathPrefix == null) + { + if (hasCapability(CAPABILITY_NAMESPACE)) + { + Log.i(Email.LOG_TAG, "mPathPrefix is unset and server has NAMESPACE capability"); + List namespaceResponses = + executeSimpleCommand(COMMAND_NAMESPACE); + for (ImapResponse response : namespaceResponses) + { + if (response.get(0).equals(COMMAND_NAMESPACE)) + { + if (Email.DEBUG) + { + Log.d(Email.LOG_TAG, "Got NAMESPACE response " + response + " on " + getLogId()); + } + + Object personalNamespaces = response.get(1); + if (personalNamespaces != null && personalNamespaces instanceof ImapList) + { + if (Email.DEBUG) + { + Log.d(Email.LOG_TAG, "Got personal namespaces: " + personalNamespaces); + } + ImapList bracketed = (ImapList)personalNamespaces; + Object firstNamespace = bracketed.get(0); + if (firstNamespace != null && firstNamespace instanceof ImapList) + { + if (Email.DEBUG) + { + Log.d(Email.LOG_TAG, "Got first personal namespaces: " + firstNamespace); + } + bracketed = (ImapList)firstNamespace; + mPathPrefix = bracketed.getString(0); + mPathDelimeter = bracketed.getString(1); + mCombinedPrefix = null; + if (Email.DEBUG) + { + Log.d(Email.LOG_TAG, "Got path '" + mPathPrefix + "' and separator '" + mPathDelimeter + "'"); + } + } + } + } + } + } + else + { + Log.i(Email.LOG_TAG, "mPathPrefix is unset but server does not have NAMESPACE capability"); + mPathPrefix = ""; + } + } } catch (SSLException e) { @@ -1922,7 +2005,12 @@ public class ImapStore extends Store // Log.v(Email.LOG_TAG, "Have capability '" + capability + "' for " + getLogId()); // } } - return capabilities.contains("IDLE"); + return capabilities.contains(CAPABILITY_IDLE); + } + + protected boolean hasCapability(String capability) + { + return capabilities.contains(capability); } private boolean isOpen() @@ -2287,7 +2375,7 @@ public class ImapStore extends Store } } - public void start() throws MessagingException + public void start() { Runnable runner = new Runnable() { @@ -2297,7 +2385,6 @@ public class ImapStore extends Store Log.i(Email.LOG_TAG, "Pusher starting for " + getLogId()); while (stop.get() != true) { - try { int oldUidNext = -1; @@ -2332,17 +2419,17 @@ public class ImapStore extends Store { handleUntaggedResponses(responses); } - if (uidNext > oldUidNext) + int startUid = oldUidNext; + if (startUid < uidNext - 10) + { + startUid = uidNext - 10; + } + if (startUid < 1) + { + startUid = 1; + } + if (uidNext > startUid) { - int startUid = oldUidNext; - if (startUid < uidNext - 100) - { - startUid = uidNext - 100; - } - if (startUid < 1) - { - startUid = 1; - } Log.i(Email.LOG_TAG, "Needs sync from uid " + startUid + " to " + uidNext + " for " + getLogId()); List messages = new ArrayList(); @@ -2359,7 +2446,7 @@ public class ImapStore extends Store } else { - if (stop.get() != true) + if (stop.get() == false) { List untaggedResponses = null; if (storedUntaggedResponses.size() > 0) @@ -2378,8 +2465,11 @@ public class ImapStore extends Store idling.set(false); } - storedUntaggedResponses.clear(); - processUntaggedResponses(untaggedResponses); + if (stop.get() == false) + { + storedUntaggedResponses.clear(); + processUntaggedResponses(untaggedResponses); + } delayTime.set(NORMAL_DELAY_TIME); } } @@ -2404,6 +2494,7 @@ public class ImapStore extends Store } else { + receiver.pushError("Push error: " + e.getMessage(), null); Log.e(Email.LOG_TAG, "Got exception while idling for " + getLogId(), e); int delayTimeInt = delayTime.get(); receiver.sleep(delayTimeInt); @@ -2453,25 +2544,34 @@ public class ImapStore extends Store } storedUntaggedResponses.add(response); } + handlePossibleUidNext(response); } } protected void processUntaggedResponses(List responses) { + boolean skipSync = false; int oldMessageCount = mMessageCount; + if (oldMessageCount == -1) + { + skipSync = true; + } List flagSyncMsgSeqs = new ArrayList(); for (ImapResponse response : responses) { oldMessageCount += processUntaggedResponse(oldMessageCount, response, flagSyncMsgSeqs); } - if (oldMessageCount < 0) + if (skipSync == false) { - oldMessageCount = 0; - } - if (mMessageCount > oldMessageCount) - { - syncMessages(oldMessageCount + 1, mMessageCount, true); + if (oldMessageCount < 0) + { + oldMessageCount = 0; + } + if (mMessageCount > oldMessageCount) + { + syncMessages(oldMessageCount + 1, mMessageCount, true); + } } if (Email.DEBUG) { @@ -2610,10 +2710,13 @@ public class ImapStore extends Store } } - public void stop() throws MessagingException + public void stop() { stop.set(true); - + if (listeningThread != null) + { + listeningThread.interrupt(); + } if (mConnection != null) { if (Email.DEBUG) @@ -2634,109 +2737,143 @@ public class ImapStore extends Store { Log.v(Email.LOG_TAG, "Got async response: " + response); } - if (response.mTag == null) + if (stop.get() == true) { - if (response.size() > 1) + if (Email.DEBUG) { - boolean started = false; - Object responseType = response.get(1); - if ("EXISTS".equals(responseType) || "EXPUNGE".equals(responseType) || - "FETCH".equals(responseType)) + Log.d(Email.LOG_TAG, "Got async untagged response: " + response + ", but stop is set for " + getLogId()); + } + try + { + sendDone(); + } + catch (Exception e) + { + Log.e(Email.LOG_TAG, "Exception while sending DONE for " + getLogId(), e); + } + } + else + { + if (response.mTag == null) + { + if (response.size() > 1) { - if (started == false) + boolean started = false; + Object responseType = response.get(1); + if ("EXISTS".equals(responseType) || "EXPUNGE".equals(responseType) || + "FETCH".equals(responseType)) { - receiver.acquireWakeLock(); - started = true; - } - if (Email.DEBUG) - { - Log.d(Email.LOG_TAG, "Got useful async untagged response: " + response + " for " + getLogId()); - } - try - { - sendDone(); - } - catch (Exception e) - { - Log.e(Email.LOG_TAG, "Exception while sending DONE for " + getLogId(), e); + if (started == false) + { + receiver.acquireWakeLock(); + started = true; + } + if (Email.DEBUG) + { + Log.d(Email.LOG_TAG, "Got useful async untagged response: " + response + " for " + getLogId()); + } + try + { + sendDone(); + } + catch (Exception e) + { + Log.e(Email.LOG_TAG, "Exception while sending DONE for " + getLogId(), e); + } } } - } - else if (response.size() > 0) - { - if ("idling".equals(response.get(0))) + else if (response.size() > 0) { - if (Email.DEBUG) + if ("idling".equals(response.get(0))) { - Log.d(Email.LOG_TAG, "Idling " + getLogId()); + if (Email.DEBUG) + { + Log.d(Email.LOG_TAG, "Idling " + getLogId()); + } + receiver.releaseWakeLock(); } - receiver.releaseWakeLock(); } } } } } + @Override + public Pusher getPusher(PushReceiver receiver) + { + return new ImapPusher(this, receiver); + } public class ImapPusher implements Pusher { - List folderPushers = new ArrayList(); + final ImapStore mStore; + final PushReceiver mReceiver; + + HashMap folderPushers = new HashMap(); - public ImapPusher(ImapStore store, PushReceiver receiver, List folderNames) + public ImapPusher(ImapStore store, PushReceiver receiver) { - for (String folderName : folderNames) + mStore = store; + mReceiver = receiver; + } + + @Override + public void start(List folderNames) + { + stop(); + synchronized(folderPushers) { - ImapFolderPusher pusher = new ImapFolderPusher(store, folderName, receiver); - folderPushers.add(pusher); + for (String folderName : folderNames) + { + ImapFolderPusher pusher = folderPushers.get(folderName); + if (pusher == null) + { + pusher = new ImapFolderPusher(mStore, folderName, mReceiver); + folderPushers.put(folderName, pusher); + pusher.start(); + } + } } } + @Override public void refresh() { - for (ImapFolderPusher folderPusher : folderPushers) + synchronized(folderPushers) { - try + for (ImapFolderPusher folderPusher : folderPushers.values()) { - folderPusher.refresh(); - } - catch (Exception e) - { - Log.e(Email.LOG_TAG, "Got exception while refreshing for " + folderPusher.getName(), e); - } - } - - } - - public void start() - { - for (ImapFolderPusher folderPusher : folderPushers) - { - try - { - folderPusher.start(); - } - catch (Exception e) - { - Log.e(Email.LOG_TAG, "Got exception while starting " + folderPusher.getName(), e); + try + { + folderPusher.refresh(); + } + catch (Exception e) + { + Log.e(Email.LOG_TAG, "Got exception while refreshing for " + folderPusher.getName(), e); + } } } } - + + @Override public void stop() { Log.i(Email.LOG_TAG, "Requested stop of IMAP pusher"); - for (ImapFolderPusher folderPusher : folderPushers) + synchronized(folderPushers) { - try + for (ImapFolderPusher folderPusher : folderPushers.values()) { - Log.i(Email.LOG_TAG, "Requesting stop of IMAP folderPusher " + folderPusher.getName()); - folderPusher.stop(); - } - catch (Exception e) - { - Log.e(Email.LOG_TAG, "Got exception while stopping " + folderPusher.getName(), e); + try + { + Log.i(Email.LOG_TAG, "Requesting stop of IMAP folderPusher " + folderPusher.getName()); + folderPusher.stop(); + } + catch (Exception e) + { + Log.e(Email.LOG_TAG, "Got exception while stopping " + folderPusher.getName(), e); + } } + folderPushers.clear(); } - folderPushers.clear(); } public int getRefreshInterval() diff --git a/src/com/android/email/service/BootReceiver.java b/src/com/android/email/service/BootReceiver.java index 740179ba6..5339e7188 100644 --- a/src/com/android/email/service/BootReceiver.java +++ b/src/com/android/email/service/BootReceiver.java @@ -69,8 +69,8 @@ public class BootReceiver extends BroadcastReceiver if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) { - Email.setServicesEnabled(context, tmpWakeLockId); - tmpWakeLockId = null; + //Email.setServicesEnabled(context, tmpWakeLockId); + //tmpWakeLockId = null; } else if (Intent.ACTION_DEVICE_STORAGE_LOW.equals(intent.getAction())) { diff --git a/src/com/android/email/service/MailService.java b/src/com/android/email/service/MailService.java index 5c54d9217..092b19e26 100644 --- a/src/com/android/email/service/MailService.java +++ b/src/com/android/email/service/MailService.java @@ -361,13 +361,7 @@ public class MailService extends CoreService for (Account account : Preferences.getPreferences(MailService.this).getAccounts()) { Log.i(Email.LOG_TAG, "Setting up pushers for account " + account.getDescription()); - Pusher pusher = MessagingController.getInstance(getApplication()).setupPushing(account); - if (pusher != null) - { - pushing = true; - Log.i(Email.LOG_TAG, "Starting configured pusher for account " + account.getDescription()); - pusher.start(); - } + pushing |= MessagingController.getInstance(getApplication()).setupPushing(account); } if (pushing) {