diff --git a/email2/res/xml/services.xml b/email2/res/xml/services.xml
new file mode 100644
index 000000000..dfc332fc4
--- /dev/null
+++ b/email2/res/xml/services.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
diff --git a/email2/src/com/android/email/activity/setup/AccountSetupAccountType.java b/email2/src/com/android/email/activity/setup/AccountSetupAccountType.java
index 7ac7d209c..9add42107 100644
--- a/email2/src/com/android/email/activity/setup/AccountSetupAccountType.java
+++ b/email2/src/com/android/email/activity/setup/AccountSetupAccountType.java
@@ -67,7 +67,7 @@ public class AccountSetupAccountType extends AccountSetupActivity implements OnC
// TODO If we decide to exclude the Exchange option in POP_IMAP mode, use the following line
// instead of the line that follows it
//if (ExchangeUtils.isExchangeAvailable(this) && flowMode != SetupData.FLOW_MODE_POP_IMAP) {
- if (EmailServiceUtils.isExchangeAvailable(this)) {
+ if (EmailServiceUtils.isServiceAvailable(this, "eas")) {
exchangeButton.setOnClickListener(this);
exchangeButton.setVisibility(View.VISIBLE);
if (VendorPolicyLoader.getInstance(this).useAlternateExchangeStrings()) {
diff --git a/email2/src/com/android/email/activity/setup/AccountSetupExchangeFragment.java b/email2/src/com/android/email/activity/setup/AccountSetupExchangeFragment.java
index 299c1f03a..4a1673d8c 100644
--- a/email2/src/com/android/email/activity/setup/AccountSetupExchangeFragment.java
+++ b/email2/src/com/android/email/activity/setup/AccountSetupExchangeFragment.java
@@ -117,11 +117,14 @@ public class AccountSetupExchangeFragment extends AccountServerBaseFragment
// Calls validateFields() which enables or disables the Next button
// based on the fields' validity.
TextWatcher validationTextWatcher = new TextWatcher() {
+ @Override
public void afterTextChanged(Editable s) {
validateFields();
}
+ @Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
+ @Override
public void onTextChanged(CharSequence s, int start, int before, int count) { }
};
// We're editing an existing account; don't allow modification of the user name
@@ -359,7 +362,7 @@ public class AccountSetupExchangeFragment extends AccountServerBaseFragment
account.mHostAuthSend.update(mContext, account.mHostAuthSend.toContentValues());
// For EAS, notify ExchangeService that the password has changed
try {
- EmailServiceUtils.getExchangeService(mContext, null).hostChanged(account.mId);
+ EmailServiceUtils.getService(mContext, null, "eas").hostChanged(account.mId);
} catch (RemoteException e) {
// Nothing to be done if this fails
}
diff --git a/email2/src/com/android/email/activity/setup/AccountSetupOptions.java b/email2/src/com/android/email/activity/setup/AccountSetupOptions.java
index 1a5f646f1..972a1a35e 100644
--- a/email2/src/com/android/email/activity/setup/AccountSetupOptions.java
+++ b/email2/src/com/android/email/activity/setup/AccountSetupOptions.java
@@ -373,7 +373,7 @@ public class AccountSetupOptions extends AccountSetupActivity implements OnClick
AccountSettingsUtils.commitSettings(context, account);
// Start up services based on new account(s)
MailActivityEmail.setServicesEnabledSync(context);
- EmailServiceUtils.startExchangeService(context);
+ EmailServiceUtils.startService(context, "eas");
// Move to final setup screen
AccountSetupNames.actionSetNames(context);
finish();
diff --git a/email2/src/com/android/email/activity/setup/DebugFragment.java b/email2/src/com/android/email/activity/setup/DebugFragment.java
index 18c96ebd9..e3ab807c5 100644
--- a/email2/src/com/android/email/activity/setup/DebugFragment.java
+++ b/email2/src/com/android/email/activity/setup/DebugFragment.java
@@ -72,7 +72,7 @@ public class DebugFragment extends Fragment implements OnCheckedChangeListener,
// Note: To prevent recursion while presetting checkboxes, assign all listeners last
mEnableDebugLoggingView.setOnCheckedChangeListener(this);
- boolean exchangeAvailable = EmailServiceUtils.isExchangeAvailable(context);
+ boolean exchangeAvailable = EmailServiceUtils.isServiceAvailable(context, "eas");
if (exchangeAvailable) {
mEnableExchangeLoggingView.setChecked(MailActivityEmail.DEBUG_EXCHANGE_VERBOSE);
mEnableExchangeFileLoggingView.setChecked(MailActivityEmail.DEBUG_EXCHANGE_FILE);
diff --git a/email2/src/com/android/email/mail/store/ExchangeStore.java b/email2/src/com/android/email/mail/store/ExchangeStore.java
index 11a02d617..fb10552db 100644
--- a/email2/src/com/android/email/mail/store/ExchangeStore.java
+++ b/email2/src/com/android/email/mail/store/ExchangeStore.java
@@ -50,6 +50,6 @@ public class ExchangeStore extends ServiceStore {
@Override
protected IEmailService getService() {
- return EmailServiceUtils.getExchangeService(mContext, null);
+ return EmailServiceUtils.getService(mContext, null, "eas");
}
}
diff --git a/email2/src/com/android/email/service/AccountService.java b/email2/src/com/android/email/service/AccountService.java
index a12108a8b..da8637b16 100644
--- a/email2/src/com/android/email/service/AccountService.java
+++ b/email2/src/com/android/email/service/AccountService.java
@@ -104,7 +104,7 @@ public class AccountService extends Service {
@Override
public void run() {
// Make sure the service is properly running (re: lifecycle)
- EmailServiceUtils.startExchangeService(mContext);
+ EmailServiceUtils.startService(mContext, "eas");
// Send current logging flags
MailActivityEmail.updateLoggingFlags(mContext);
}});
diff --git a/email2/src/com/android/email/service/EmailBroadcastProcessorService.java b/email2/src/com/android/email/service/EmailBroadcastProcessorService.java
index 88d714273..e770465ef 100644
--- a/email2/src/com/android/email/service/EmailBroadcastProcessorService.java
+++ b/email2/src/com/android/email/service/EmailBroadcastProcessorService.java
@@ -131,7 +131,7 @@ public class EmailBroadcastProcessorService extends IntentService {
performOneTimeInitialization();
// Starts the service for Exchange, if supported.
- EmailServiceUtils.startExchangeService(this);
+ EmailServiceUtils.startService(this, "eas");
}
private void performOneTimeInitialization() {
@@ -207,6 +207,6 @@ public class EmailBroadcastProcessorService extends IntentService {
// If the exchange service wasn't already running, starting it will cause exchange account
// reconciliation to be performed. The service stops itself it there are no EAS accounts.
- EmailServiceUtils.startExchangeService(this);
+ EmailServiceUtils.startService(this, "eas");
}
}
diff --git a/email2/src/com/android/email/service/EmailServiceUtils.java b/email2/src/com/android/email/service/EmailServiceUtils.java
index e7b18bb32..92c980d89 100644
--- a/email2/src/com/android/email/service/EmailServiceUtils.java
+++ b/email2/src/com/android/email/service/EmailServiceUtils.java
@@ -16,66 +16,46 @@
package com.android.email.service;
+import android.app.Service;
import android.content.Context;
import android.content.Intent;
+import android.content.res.XmlResourceParser;
+import com.android.email.R;
import com.android.emailcommon.provider.Account;
-import com.android.emailcommon.provider.HostAuth;
import com.android.emailcommon.service.EmailServiceProxy;
-import com.android.emailcommon.service.IEmailService;
import com.android.emailcommon.service.IEmailServiceCallback;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.HashMap;
+
/**
* Utility functions for EmailService support.
*/
public class EmailServiceUtils {
- /**
- * Starts an EmailService by name
- */
- public static void startService(Context context, String intentAction) {
- context.startService(new Intent(intentAction));
- }
+ private static final HashMap sServiceMap =
+ new HashMap();
/**
- * Returns an {@link IEmailService} for the service; otherwise returns an empty
- * {@link IEmailService} implementation.
- *
- * @param context
- * @param callback Object to get callback, or can be null
+ * Starts an EmailService by protocol
*/
- public static EmailServiceProxy getService(Context context, String intentAction,
- IEmailServiceCallback callback) {
- return new EmailServiceProxy(context, intentAction, callback);
+ public static void startService(Context context, String protocol) {
+ EmailServiceInfo info = getServiceInfo(context, protocol);
+ if (info != null && info.intentAction != null) {
+ context.startService(new Intent(info.intentAction));
+ }
}
/**
* Determine if the EmailService is available
*/
- public static boolean isServiceAvailable(Context context, String intentAction) {
- return new EmailServiceProxy(context, intentAction, null).test();
- }
-
- public static void startExchangeService(Context context) {
- startService(context, EmailServiceProxy.EXCHANGE_INTENT);
- }
-
- public static EmailServiceProxy getExchangeService(Context context,
- IEmailServiceCallback callback) {
- return getService(context, EmailServiceProxy.EXCHANGE_INTENT, callback);
- }
-
- public static EmailServiceProxy getImapService(Context context,
- IEmailServiceCallback callback) {
- return new EmailServiceProxy(context, ImapService.class, callback);
- }
-
- public static EmailServiceProxy getPop3Service(Context context,
- IEmailServiceCallback callback) {
- return new EmailServiceProxy(context, Pop3Service.class, callback);
- }
-
- public static boolean isExchangeAvailable(Context context) {
- return isServiceAvailable(context, EmailServiceProxy.EXCHANGE_INTENT);
+ public static boolean isServiceAvailable(Context context, String protocol) {
+ EmailServiceInfo info = getServiceInfo(context, protocol);
+ if (info == null) return false;
+ if (info.klass != null) return true;
+ return new EmailServiceProxy(context, info.intentAction, null).test();
}
/**
@@ -86,15 +66,86 @@ public class EmailServiceUtils {
*/
public static EmailServiceProxy getServiceForAccount(Context context,
IEmailServiceCallback callback, long accountId) {
- String protocol = Account.getProtocol(context, accountId);
- if (HostAuth.SCHEME_IMAP.equals(protocol)) {
- return getImapService(context, callback);
- } else if (HostAuth.SCHEME_POP3.equals(protocol)) {
- return getPop3Service(context, callback);
- } else if (HostAuth.SCHEME_EAS.equals(protocol)) {
- return getExchangeService(context, callback);
+ return getService(context, callback, Account.getProtocol(context, accountId));
+ }
+
+ /**
+ * Holder of service information (currently just name and class/intent); if there is a class
+ * member, this is a (local, i.e. same process) service; otherwise, this is a remote service
+ */
+ static class EmailServiceInfo {
+ String name;
+ Class extends Service> klass;
+ String intentAction;
+ }
+
+ public static EmailServiceProxy getService(Context context, IEmailServiceCallback callback,
+ String protocol) {
+ EmailServiceInfo info = getServiceInfo(context, protocol);
+ if (info.klass != null) {
+ return new EmailServiceProxy(context, info.klass, callback);
} else {
- return null;
+ return new EmailServiceProxy(context, info.intentAction, callback);
}
}
+
+ private static EmailServiceInfo getServiceInfo(Context context, String protocol) {
+ if (sServiceMap.isEmpty()) {
+ findServices(context);
+ }
+ return sServiceMap.get(protocol);
+ }
+
+ /**
+ * Parse services.xml file to find our available email services
+ */
+ @SuppressWarnings("unchecked")
+ private static void findServices(Context context) {
+ try {
+ XmlResourceParser xml = context.getResources().getXml(R.xml.services);
+ int xmlEventType;
+ // walk through senders.xml file.
+ while ((xmlEventType = xml.next()) != XmlResourceParser.END_DOCUMENT) {
+ if (xmlEventType == XmlResourceParser.START_TAG &&
+ "service".equals(xml.getName())) {
+ EmailServiceInfo info = new EmailServiceInfo();
+ String protocol = xml.getAttributeValue(null, "protocol");
+ if (protocol == null) {
+ throw new IllegalStateException(
+ "No protocol specified in service descriptor");
+ }
+ info.name = xml.getAttributeValue(null, "name");
+ if (info.name == null) {
+ throw new IllegalStateException(
+ "No name specified in service descriptor");
+ }
+ String klass = xml.getAttributeValue(null, "class");
+ if (klass != null) {
+ try {
+ info.klass = (Class extends Service>) Class.forName(klass);
+ } catch (ClassNotFoundException e) {
+ throw new IllegalStateException(
+ "Class not found in service descriptor: " + klass);
+ }
+ }
+ info.intentAction = xml.getAttributeValue(null, "intent");
+
+ if (info.klass == null && info.intentAction == null) {
+ throw new IllegalStateException(
+ "No class or intent action specified in service descriptor");
+ }
+ if (info.klass != null && info.intentAction != null) {
+ throw new IllegalStateException(
+ "Both class and intent action specified in service descriptor");
+ }
+ sServiceMap.put(protocol, info);
+ }
+ }
+ } catch (XmlPullParserException e) {
+ // ignore
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+
}
diff --git a/email2/src/com/android/email2/ui/MailActivityEmail.java b/email2/src/com/android/email2/ui/MailActivityEmail.java
index b1514dd09..f13550d24 100644
--- a/email2/src/com/android/email2/ui/MailActivityEmail.java
+++ b/email2/src/com/android/email2/ui/MailActivityEmail.java
@@ -193,7 +193,7 @@ public class MailActivityEmail extends com.android.mail.ui.MailActivity {
int enableStrictMode =
prefs.getEnableStrictMode() ? EmailServiceProxy.DEBUG_ENABLE_STRICT_MODE : 0;
int debugBits = debugLogging | verboseLogging | fileLogging | enableStrictMode;
- EmailServiceProxy service = EmailServiceUtils.getExchangeService(context, null);
+ EmailServiceProxy service = EmailServiceUtils.getService(context, null, "eas");
if (service != null) {
try {
service.setLogging(debugBits);