diff --git a/res/xml/providers.xml b/res/xml/providers.xml
index 8a92f0b7d..ed8637125 100644
--- a/res/xml/providers.xml
+++ b/res/xml/providers.xml
@@ -233,220 +233,8 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
diff --git a/src/com/android/email/activity/setup/AccountSettingsUtils.java b/src/com/android/email/activity/setup/AccountSettingsUtils.java
index 0634fd26c..99fff64ba 100644
--- a/src/com/android/email/activity/setup/AccountSettingsUtils.java
+++ b/src/com/android/email/activity/setup/AccountSettingsUtils.java
@@ -31,7 +31,6 @@ import android.util.Log;
import android.widget.EditText;
import java.io.Serializable;
-import java.net.URI;
public class AccountSettingsUtils {
@@ -101,20 +100,28 @@ public class AccountSettingsUtils {
* @param resourceId Id of the provider resource to scan
* @return suitable Provider definition, or null if no match found
*/
- private static Provider findProviderForDomain(Context context, String domain, int resourceId) {
+ /*package*/ static Provider findProviderForDomain(
+ Context context, String domain, int resourceId) {
try {
XmlResourceParser xml = context.getResources().getXml(resourceId);
int xmlEventType;
Provider provider = null;
while ((xmlEventType = xml.next()) != XmlResourceParser.END_DOCUMENT) {
if (xmlEventType == XmlResourceParser.START_TAG
- && "provider".equals(xml.getName())
- && domain.equalsIgnoreCase(getXmlAttribute(context, xml, "domain"))) {
- provider = new Provider();
- provider.id = getXmlAttribute(context, xml, "id");
- provider.label = getXmlAttribute(context, xml, "label");
- provider.domain = getXmlAttribute(context, xml, "domain");
- provider.note = getXmlAttribute(context, xml, "note");
+ && "provider".equals(xml.getName())) {
+ String providerDomain = getXmlAttribute(context, xml, "domain");
+ try {
+ if (globMatchIgnoreCase(domain, providerDomain)) {
+ provider = new Provider();
+ provider.id = getXmlAttribute(context, xml, "id");
+ provider.label = getXmlAttribute(context, xml, "label");
+ provider.domain = domain.toLowerCase();
+ provider.note = getXmlAttribute(context, xml, "note");
+ }
+ } catch (IllegalArgumentException e) {
+ Log.w(Logging.LOG_TAG, "providers line: " + xml.getLineNumber() +
+ "; Domain contains multiple globals");
+ }
}
else if (xmlEventType == XmlResourceParser.START_TAG
&& "incoming".equals(xml.getName())
@@ -141,6 +148,42 @@ public class AccountSettingsUtils {
return null;
}
+ /**
+ * Compares the two strings. glob may have at most a single global character ('*') that
+ * will match any number of characters in the input string.
+ * @return true if the strings match. otherwise, false.
+ * @throws IllegalArgumentException if the strings are null or glob has multiple globals.
+ */
+ /*package*/ static boolean globMatchIgnoreCase(String in, String glob)
+ throws IllegalArgumentException {
+ if (in == null || glob == null) {
+ throw new IllegalArgumentException("one or both strings are null");
+ }
+
+ // Handle the possible global in the domain name
+ String[] globParts = glob.split("\\*");
+ String inLower = in.toLowerCase();
+ switch (globParts.length) {
+ case 1:
+ // No globals; test for simple equality
+ if (!inLower.equals(globParts[0].toLowerCase())) {
+ return false;
+ }
+ break;
+ case 2:
+ // Global; test the front & end parts of the domain
+ String d1 = globParts[0].toLowerCase();
+ String d2 = globParts[1].toLowerCase();
+ if (!inLower.startsWith(d1) || !inLower.substring(d1.length()).endsWith(d2)) {
+ return false;
+ }
+ break;
+ default:
+ throw new IllegalArgumentException("Multiple globals");
+ }
+ return true;
+ }
+
/**
* Attempts to get the given attribute as a String resource first, and if it fails
* returns the attribute as a simple String value.
@@ -168,7 +211,27 @@ public class AccountSettingsUtils {
public String incomingUsernameTemplate;
public String outgoingUriTemplate;
public String outgoingUsernameTemplate;
+ public String incomingUri;
+ public String incomingUsername;
+ public String outgoingUri;
+ public String outgoingUsername;
public String note;
+ public void expandTemplates(String email) {
+ String[] emailParts = email.split("@");
+ String user = emailParts[0];
+
+ incomingUri = expandTemplate(incomingUriTemplate, email, user);
+ incomingUsername = expandTemplate(incomingUsernameTemplate, email, user);
+ outgoingUri = expandTemplate(outgoingUriTemplate, email, user);
+ outgoingUsername = expandTemplate(outgoingUsernameTemplate, email, user);
+ }
+ private String expandTemplate(String template, String email, String user) {
+ String returnString = template;
+ returnString = returnString.replaceAll("\\$email", email);
+ returnString = returnString.replaceAll("\\$user", user);
+ returnString = returnString.replaceAll("\\$domain", domain);
+ return returnString;
+ }
}
/**
diff --git a/src/com/android/email/activity/setup/AccountSetupBasics.java b/src/com/android/email/activity/setup/AccountSetupBasics.java
index 01bf180c5..bd40f19cb 100644
--- a/src/com/android/email/activity/setup/AccountSetupBasics.java
+++ b/src/com/android/email/activity/setup/AccountSetupBasics.java
@@ -418,36 +418,25 @@ public class AccountSetupBasics extends AccountSetupActivity
private void finishAutoSetup() {
String email = mEmailView.getText().toString().trim();
String password = mPasswordView.getText().toString();
- String[] emailParts = email.split("@");
- String user = emailParts[0];
- String domain = emailParts[1];
try {
- String incomingUsername = mProvider.incomingUsernameTemplate;
- incomingUsername = incomingUsername.replaceAll("\\$email", email);
- incomingUsername = incomingUsername.replaceAll("\\$user", user);
- incomingUsername = incomingUsername.replaceAll("\\$domain", domain);
+ mProvider.expandTemplates(email);
Account account = SetupData.getAccount();
HostAuth recvAuth = account.getOrCreateHostAuthRecv(this);
- Utility.setHostAuthFromString(recvAuth, mProvider.incomingUriTemplate);
- recvAuth.setLogin(incomingUsername, password);
-
- String outgoingUsername = mProvider.outgoingUsernameTemplate;
- outgoingUsername = outgoingUsername.replaceAll("\\$email", email);
- outgoingUsername = outgoingUsername.replaceAll("\\$user", user);
- outgoingUsername = outgoingUsername.replaceAll("\\$domain", domain);
+ Utility.setHostAuthFromString(recvAuth, mProvider.incomingUri);
+ recvAuth.setLogin(mProvider.incomingUsername, password);
HostAuth sendAuth = account.getOrCreateHostAuthSend(this);
- Utility.setHostAuthFromString(sendAuth, mProvider.outgoingUriTemplate);
- sendAuth.setLogin(outgoingUsername, password);
+ Utility.setHostAuthFromString(sendAuth, mProvider.outgoingUri);
+ sendAuth.setLogin(mProvider.outgoingUsername, password);
// Populate the setup data, assuming that the duplicate account check will succeed
populateSetupData(getOwnerName(), email, mDefaultView.isChecked());
// Stop here if the login credentials duplicate an existing account
// Launch an Async task to do the work
- new DuplicateCheckTask(this, recvAuth.mAddress, incomingUsername).execute();
+ new DuplicateCheckTask(this, recvAuth.mAddress, mProvider.incomingUsername).execute();
} catch (URISyntaxException e) {
/*
* If there is some problem with the URI we give up and go on to manual setup.
diff --git a/tests/res/xml/test_providers.xml b/tests/res/xml/test_providers.xml
new file mode 100644
index 000000000..02642026e
--- /dev/null
+++ b/tests/res/xml/test_providers.xml
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/src/com/android/email/activity/setup/AccountSettingsUtilsTests.java b/tests/src/com/android/email/activity/setup/AccountSettingsUtilsTests.java
index 90282b3f4..86a4fb192 100644
--- a/tests/src/com/android/email/activity/setup/AccountSettingsUtilsTests.java
+++ b/tests/src/com/android/email/activity/setup/AccountSettingsUtilsTests.java
@@ -16,6 +16,10 @@
package com.android.email.activity.setup;
+import com.android.email.tests.R;
+import com.android.email.activity.setup.AccountSettingsUtils.Provider;
+
+import android.content.Context;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
@@ -28,6 +32,14 @@ import android.test.suitebuilder.annotation.SmallTest;
@SmallTest
public class AccountSettingsUtilsTests extends AndroidTestCase {
+ private Context mTestContext;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mTestContext = getTestContext();
+ }
+
/**
* Test server name inferences
*
@@ -51,4 +63,154 @@ public class AccountSettingsUtilsTests extends AndroidTestCase {
assertEquals("MaiL.y.z", AccountSettingsUtils.inferServerName("MaiL.y.z", null, "bar"));
}
+ public void testFindProviderForDomain() {
+ Provider testProvider;
+ //
+ //
+ //
+ //
+ testProvider = AccountSettingsUtils.findProviderForDomain(
+ mTestContext, "gmail.com", R.xml.test_providers);
+ assertNotNull(testProvider);
+ assertEquals("imap+ssl+://imap.gmail.com", testProvider.incomingUriTemplate);
+ assertEquals("smtp+ssl+://smtp.gmail.com", testProvider.outgoingUriTemplate);
+ assertEquals("gmail.com", testProvider.domain);
+
+ //
+ //
+ //
+ //
+ testProvider = AccountSettingsUtils.findProviderForDomain(
+ mTestContext, "elmore.rr.com", R.xml.test_providers);
+ assertNotNull(testProvider);
+ assertEquals("pop3://pop-server.$domain", testProvider.incomingUriTemplate);
+ assertEquals("smtp://mobile-smtp.roadrunner.com", testProvider.outgoingUriTemplate);
+ assertEquals("elmore.rr.com", testProvider.domain);
+
+ // Domain matches 2 providers; first one wins
+ testProvider = AccountSettingsUtils.findProviderForDomain(
+ mTestContext, "leonard.rr.com", R.xml.test_providers);
+ assertNotNull(testProvider);
+ assertEquals("pop3://pop-server.firstonewins.com", testProvider.incomingUriTemplate);
+
+ // Domains that don't exist
+ testProvider = AccountSettingsUtils.findProviderForDomain(
+ mTestContext, "nonexist.com", R.xml.test_providers);
+ assertNull(testProvider);
+ }
+
+ public void testGlobMatchIgnoreCase() {
+ boolean testMatch;
+
+ assertTrue(AccountSettingsUtils.globMatchIgnoreCase(
+ "mail.yahoo.com", "mail*yahoo.com"));
+ assertTrue(AccountSettingsUtils.globMatchIgnoreCase(
+ "mail.foo.bar.yahoo.com", "mail*yahoo.com"));
+ assertTrue(AccountSettingsUtils.globMatchIgnoreCase(
+ "mail.notwhatyouwant.myyahoo.com", "mail*yahoo.com"));
+
+ // Test other combinations
+ assertTrue(AccountSettingsUtils.globMatchIgnoreCase(
+ "yahoo.com", "yahoo.com"));
+ assertFalse(AccountSettingsUtils.globMatchIgnoreCase(
+ "yahoo.com.au", "yahoo.com"));
+ assertFalse(AccountSettingsUtils.globMatchIgnoreCase(
+ "yahoo.com", "yahoo.com.au"));
+
+ // Try mixed case in the domain name
+ assertTrue(AccountSettingsUtils.globMatchIgnoreCase(
+ "GmAiL.cOm", "gMaIl.CoM"));
+
+ assertFalse(AccountSettingsUtils.globMatchIgnoreCase(
+ "nonexist.frr.com", "*.rr.com"));
+ assertFalse(AccountSettingsUtils.globMatchIgnoreCase(
+ "rr.com", "*.rr.com"));
+ assertTrue(AccountSettingsUtils.globMatchIgnoreCase(
+ "abbc.com", "ab*bc.com"));
+ assertFalse(AccountSettingsUtils.globMatchIgnoreCase(
+ "abc.com", "ab*bc.com"));
+
+ try {
+ AccountSettingsUtils.globMatchIgnoreCase(
+ "abc.com", "ab*bc*.com");
+ fail("Should have thrown an IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ AccountSettingsUtils.globMatchIgnoreCase(
+ null, "ab*bc*.com");
+ fail("Should have thrown an IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ AccountSettingsUtils.globMatchIgnoreCase(
+ "abc.com", null);
+ fail("Should have thrown an IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ public void testExpandTemplates() {
+ Provider testProvider;
+ //
+ //
+ //
+ //
+ testProvider = new Provider();
+ testProvider.domain = "cox.net";
+ testProvider.incomingUriTemplate = "pop3+ssl+://pop.east.$domain";
+ testProvider.outgoingUriTemplate = "smtp+ssl+://smtp.east.$domain";
+ testProvider.incomingUsernameTemplate = "$user";
+ testProvider.outgoingUsernameTemplate = "$user";
+ testProvider.expandTemplates("replUser@cox.net");
+ assertEquals("replUser", testProvider.incomingUsername);
+ assertEquals("replUser", testProvider.outgoingUsername);
+ assertEquals("pop3+ssl+://pop.east.cox.net", testProvider.incomingUri);
+ assertEquals("smtp+ssl+://smtp.east.cox.net", testProvider.outgoingUri);
+
+ //
+ //
+ //
+ //
+ testProvider = new Provider();
+ testProvider.domain = "earthlink.net";
+ testProvider.incomingUriTemplate = "pop3://pop.earthlink.net";
+ testProvider.outgoingUriTemplate = "smtp://smtpauth.earthlink.net:587";
+ testProvider.incomingUsernameTemplate = "$email";
+ testProvider.outgoingUsernameTemplate = "$email";
+ testProvider.expandTemplates("replUser@earthlink.net");
+ assertEquals("replUser@earthlink.net", testProvider.incomingUsername);
+ assertEquals("replUser@earthlink.net", testProvider.outgoingUsername);
+ assertEquals("pop3://pop.earthlink.net", testProvider.incomingUri);
+ assertEquals("smtp://smtpauth.earthlink.net:587", testProvider.outgoingUri);
+
+ //
+ //
+ //
+ //
+ testProvider = new Provider();
+ testProvider.domain = "tuffmail.com";
+ testProvider.incomingUriTemplate = "imap+ssl+://mail.mxes.net";
+ testProvider.outgoingUriTemplate = "smtp+ssl+://smtp.mxes.net";
+ testProvider.incomingUsernameTemplate = "$user_$domain";
+ testProvider.outgoingUsernameTemplate = "$user_$domain";
+ testProvider.expandTemplates("replUser@tuffmail.com");
+ assertEquals("replUser_tuffmail.com", testProvider.incomingUsername);
+ assertEquals("replUser_tuffmail.com", testProvider.outgoingUsername);
+ assertEquals("imap+ssl+://mail.mxes.net", testProvider.incomingUri);
+ assertEquals("smtp+ssl+://smtp.mxes.net", testProvider.outgoingUri);
+
+ // Everything hardcoded; not effective in the wild
+ testProvider = new Provider();
+ testProvider.domain = "yahoo.com";
+ testProvider.incomingUriTemplate = "imap+ssl+://pop.yahoo.com";
+ testProvider.outgoingUriTemplate = "smtp+ssl+://smtp.yahoo.com";
+ testProvider.incomingUsernameTemplate = "joe_smith";
+ testProvider.outgoingUsernameTemplate = "joe_smith";
+ testProvider.expandTemplates("replUser@yahoo.com");
+ assertEquals("joe_smith", testProvider.incomingUsername);
+ assertEquals("joe_smith", testProvider.outgoingUsername);
+ assertEquals("imap+ssl+://pop.yahoo.com", testProvider.incomingUri);
+ assertEquals("smtp+ssl+://smtp.yahoo.com", testProvider.outgoingUri);
+ }
}