From 61dc3a8795678e274530958847deba854aa3bd05 Mon Sep 17 00:00:00 2001 From: Andy Stadler <> Date: Wed, 8 Apr 2009 19:28:19 -0700 Subject: [PATCH] AI 145230: am: CL 145227 Add callback for push-mode stores to report async updates. The logic for this is quite simplistic, for now: When the store reports that it has new messages, it triggers a service refresh, just as if a pull-mode interval had expired and it is time to check the server. Note, unfortunately at this time there are no tests, because there are not currently any good test seams in MailService.java. Original author: stadler Automated import of CL 145230 --- src/com/android/email/mail/Store.java | 21 +++++ .../mail/exchange/ExchangeStoreExample.java | 29 +++++++ .../android/email/service/MailService.java | 77 ++++++++++++++++--- 3 files changed, 115 insertions(+), 12 deletions(-) diff --git a/src/com/android/email/mail/Store.java b/src/com/android/email/mail/Store.java index f32bf871a..3a5cf881c 100644 --- a/src/com/android/email/mail/Store.java +++ b/src/com/android/email/mail/Store.java @@ -185,6 +185,27 @@ public abstract class Store { public abstract void checkSettings() throws MessagingException; + /** + * Enable or disable push mode delivery for a given Store. + * + *
For protocols that do not support push mode, be sure that push="true" is not + * set by the stores.xml definition file(s). This function need not be implemented. + * + *
For protocols that do support push mode, this will be called at startup (boot) time + * so that the Store can launch its own underlying connection service. It will also be called + * any time the user changes the settings for the account (because the user may switch back + * to polling mode (or disable checking completely). + * + *
This API will be called repeatedly, even after push mode has already been started or
+ * stopped. Stores that support push mode should return quickly if the configuration has not
+ * changed.
+ *
+ * @param enablePushMode start or stop push mode delivery
+ */
+ public void enablePushModeDelivery(boolean enablePushMode) {
+ // does nothing for non-push protocols
+ }
+
/**
* Delete Store and its corresponding resources.
* @throws MessagingException
diff --git a/src/com/android/email/mail/exchange/ExchangeStoreExample.java b/src/com/android/email/mail/exchange/ExchangeStoreExample.java
index d70ca0658..444fb68b8 100644
--- a/src/com/android/email/mail/exchange/ExchangeStoreExample.java
+++ b/src/com/android/email/mail/exchange/ExchangeStoreExample.java
@@ -16,11 +16,14 @@
package com.android.email.mail.exchange;
+import com.android.email.Email;
import com.android.email.mail.Folder;
import com.android.email.mail.MessagingException;
import com.android.email.mail.Store;
import android.content.Context;
+import android.util.Config;
+import android.util.Log;
import java.net.URI;
import java.net.URISyntaxException;
@@ -36,12 +39,15 @@ import java.util.HashMap;
* to res/xml/stores.xml
*/
public class ExchangeStoreExample extends Store {
+ public static final String LOG_TAG = "ExchangeStoreExample";
private final Context mContext;
private URI mUri;
private final ExchangeTransportExample mTransport;
private final HashMap Note, may be called multiple times, even after push mode has been started or stopped.
+ *
+ * @param enablePushMode start or stop push mode delivery
+ */
+ @Override
+ public void enablePushModeDelivery(boolean enablePushMode) {
+ if (Config.LOGD && Email.DEBUG) {
+ if (enablePushMode && !mPushModeRunning) {
+ Log.d(Email.LOG_TAG, "start push mode");
+ } else if (!enablePushMode && mPushModeRunning) {
+ Log.d(Email.LOG_TAG, "stop push mode");
+ } else {
+ Log.d(Email.LOG_TAG, enablePushMode ?
+ "push mode already started" : "push mode already stopped");
+ }
+ }
+ mPushModeRunning = enablePushMode;
+ }
+
/**
* Get class of SettingActivity for this Store class.
* @return Activity class that has class method actionEditIncomingSettings().
diff --git a/src/com/android/email/service/MailService.java b/src/com/android/email/service/MailService.java
index 9cd8c0169..7d1fb00a5 100644
--- a/src/com/android/email/service/MailService.java
+++ b/src/com/android/email/service/MailService.java
@@ -16,8 +16,16 @@
package com.android.email.service;
-import java.util.ArrayList;
-import java.util.HashMap;
+import com.android.email.Account;
+import com.android.email.Email;
+import com.android.email.MessagingController;
+import com.android.email.MessagingListener;
+import com.android.email.Preferences;
+import com.android.email.R;
+import com.android.email.activity.Accounts;
+import com.android.email.activity.FolderMessageList;
+import com.android.email.mail.MessagingException;
+import com.android.email.mail.Store;
import android.app.AlarmManager;
import android.app.Notification;
@@ -33,14 +41,8 @@ import android.text.TextUtils;
import android.util.Config;
import android.util.Log;
-import com.android.email.Account;
-import com.android.email.Email;
-import com.android.email.MessagingController;
-import com.android.email.MessagingListener;
-import com.android.email.Preferences;
-import com.android.email.R;
-import com.android.email.activity.Accounts;
-import com.android.email.activity.FolderMessageList;
+import java.util.ArrayList;
+import java.util.HashMap;
/**
*/
@@ -48,6 +50,8 @@ public class MailService extends Service {
private static final String ACTION_CHECK_MAIL = "com.android.email.intent.action.MAIL_SERVICE_WAKEUP";
private static final String ACTION_RESCHEDULE = "com.android.email.intent.action.MAIL_SERVICE_RESCHEDULE";
private static final String ACTION_CANCEL = "com.android.email.intent.action.MAIL_SERVICE_CANCEL";
+
+ private static final String EXTRA_CHECK_ACCOUNT = "com.android.email.intent.extra.ACCOUNT";
private Listener mListener = new Listener();
@@ -66,6 +70,21 @@ public class MailService extends Service {
i.setAction(MailService.ACTION_CANCEL);
context.startService(i);
}
+
+ /**
+ * Entry point for asynchronous message services (e.g. push mode) to post notifications of new
+ * messages. Note: Although this is not a blocking call, it will start the MessagingController
+ * which will attempt to load the new messages. So the Store should expect to be opened and
+ * fetched from shortly after making this call.
+ *
+ * @param storeUri the Uri of the store that is reporting new messages
+ */
+ public static void actionNotifyNewMessages(Context context, String storeUri) {
+ Intent i = new Intent(ACTION_CHECK_MAIL);
+ i.setClass(context, MailService.class);
+ i.putExtra(EXTRA_CHECK_ACCOUNT, storeUri);
+ context.startService(i);
+ }
@Override
public void onStart(Intent intent, int startId) {
@@ -84,11 +103,21 @@ public class MailService extends Service {
// accounts that should not have been checked at all.
// Also note: Due to the organization of this service, you must gather the accounts
// and make a single call to controller.checkMail().
+
+ // TODO: Notification for single push account will fire up checks on all other
+ // accounts. This needs to be cleaned up for better efficiency.
+ String specificStoreUri = intent.getStringExtra(EXTRA_CHECK_ACCOUNT);
+
ArrayList