diff --git a/res/layout/account_setup_exchange.xml b/res/layout/account_setup_exchange.xml
index 4173bcf00..2dd256625 100644
--- a/res/layout/account_setup_exchange.xml
+++ b/res/layout/account_setup_exchange.xml
@@ -69,24 +69,16 @@
android:imeOptions="actionDone"
android:layout_height="wrap_content"
android:layout_width="fill_parent" />
-
-
+
Enter domain here
Use secure connection (SSL)
+
+ Accept all SSL certificates
Account options
diff --git a/src/com/android/email/activity/setup/AccountSetupExchange.java b/src/com/android/email/activity/setup/AccountSetupExchange.java
index 8f8f08ae0..7d09ab079 100644
--- a/src/com/android/email/activity/setup/AccountSetupExchange.java
+++ b/src/com/android/email/activity/setup/AccountSetupExchange.java
@@ -19,18 +19,20 @@ package com.android.email.activity.setup;
import com.android.email.R;
import com.android.email.Utility;
import com.android.email.provider.EmailContent;
+import com.android.email.provider.EmailContent.Account;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
-import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
+import android.widget.CompoundButton;
import android.widget.EditText;
+import android.widget.CompoundButton.OnCheckedChangeListener;
import java.net.URI;
import java.net.URISyntaxException;
@@ -45,7 +47,8 @@ import java.net.URISyntaxException;
* User (login)
* Password
*/
-public class AccountSetupExchange extends Activity implements OnClickListener {
+public class AccountSetupExchange extends Activity implements OnClickListener,
+ OnCheckedChangeListener {
private static final String EXTRA_ACCOUNT = "account";
private static final String EXTRA_MAKE_DEFAULT = "makeDefault";
private static final String EXTRA_EAS_FLOW = "easFlow";
@@ -53,14 +56,14 @@ public class AccountSetupExchange extends Activity implements OnClickListener {
private EditText mUsernameView;
private EditText mPasswordView;
private EditText mServerView;
- private EditText mDomainView;
private CheckBox mSslSecurityView;
+ private CheckBox mTrustCertificatesView;
private Button mNextButton;
- private EmailContent.Account mAccount;
+ private Account mAccount;
private boolean mMakeDefault;
- public static void actionIncomingSettings(Activity fromActivity, EmailContent.Account account,
+ public static void actionIncomingSettings(Activity fromActivity, Account account,
boolean makeDefault, boolean easFlowMode) {
Intent i = new Intent(fromActivity, AccountSetupExchange.class);
i.putExtra(EXTRA_ACCOUNT, account);
@@ -69,7 +72,7 @@ public class AccountSetupExchange extends Activity implements OnClickListener {
fromActivity.startActivity(i);
}
- public static void actionEditIncomingSettings(Activity fromActivity, EmailContent.Account account)
+ public static void actionEditIncomingSettings(Activity fromActivity, Account account)
{
Intent i = new Intent(fromActivity, AccountSetupExchange.class);
i.setAction(Intent.ACTION_EDIT);
@@ -81,7 +84,7 @@ public class AccountSetupExchange extends Activity implements OnClickListener {
* For now, we'll simply replicate outgoing, for the purpose of satisfying the
* account settings flow.
*/
- public static void actionEditOutgoingSettings(Activity fromActivity, EmailContent.Account account)
+ public static void actionEditOutgoingSettings(Activity fromActivity, Account account)
{
Intent i = new Intent(fromActivity, AccountSetupExchange.class);
i.setAction(Intent.ACTION_EDIT);
@@ -97,8 +100,9 @@ public class AccountSetupExchange extends Activity implements OnClickListener {
mUsernameView = (EditText) findViewById(R.id.account_username);
mPasswordView = (EditText) findViewById(R.id.account_password);
mServerView = (EditText) findViewById(R.id.account_server);
- mDomainView = (EditText) findViewById(R.id.account_domain);
mSslSecurityView = (CheckBox) findViewById(R.id.account_ssl);
+ mSslSecurityView.setOnCheckedChangeListener(this);
+ mTrustCertificatesView = (CheckBox) findViewById(R.id.account_trust_certificates);
mNextButton = (Button)findViewById(R.id.next);
mNextButton.setOnClickListener(this);
@@ -121,7 +125,6 @@ public class AccountSetupExchange extends Activity implements OnClickListener {
mUsernameView.addTextChangedListener(validationTextWatcher);
mPasswordView.addTextChangedListener(validationTextWatcher);
mServerView.addTextChangedListener(validationTextWatcher);
- mDomainView.addTextChangedListener(validationTextWatcher);
mAccount = (EmailContent.Account) getIntent().getParcelableExtra(EXTRA_ACCOUNT);
mMakeDefault = getIntent().getBooleanExtra(EXTRA_MAKE_DEFAULT, false);
@@ -164,12 +167,10 @@ public class AccountSetupExchange extends Activity implements OnClickListener {
mServerView.setText(uri.getHost());
}
- String domain = uri.getPath();
- if (!TextUtils.isEmpty(domain)) {
- mDomainView.setText(domain.substring(1));
- }
-
- mSslSecurityView.setChecked(uri.getScheme().contains("ssl"));
+ boolean ssl = uri.getScheme().contains("ssl");
+ mSslSecurityView.setChecked(ssl);
+ mTrustCertificatesView.setChecked(uri.getScheme().contains("tssl"));
+ mTrustCertificatesView.setVisibility(ssl ? View.VISIBLE : View.GONE);
} catch (URISyntaxException use) {
/*
@@ -233,15 +234,12 @@ public class AccountSetupExchange extends Activity implements OnClickListener {
*/
private URI getUri() throws URISyntaxException {
boolean sslRequired = mSslSecurityView.isChecked();
- String scheme = sslRequired ? "eas+ssl+" : "eas";
+ boolean trustCertificates = mTrustCertificatesView.isChecked();
+ String scheme = (sslRequired) ? (trustCertificates ? "eas+tssl+" : "eas+ssl+") : "eas";
String userInfo = mUsernameView.getText().toString().trim() + ":" +
mPasswordView.getText().toString().trim();
String host = mServerView.getText().toString().trim();
- String domain = mDomainView.getText().toString().trim();
String path = null;
- if (domain.length() > 0) {
- path = "/" + domain;
- }
URI uri = new URI(
scheme,
@@ -281,4 +279,10 @@ public class AccountSetupExchange extends Activity implements OnClickListener {
break;
}
}
+
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (buttonView.getId() == R.id.account_ssl) {
+ mTrustCertificatesView.setVisibility(isChecked ? View.VISIBLE : View.GONE);
+ }
+ }
}
diff --git a/src/com/android/email/mail/store/ExchangeStore.java b/src/com/android/email/mail/store/ExchangeStore.java
index aef421c94..c5d81745f 100644
--- a/src/com/android/email/mail/store/ExchangeStore.java
+++ b/src/com/android/email/mail/store/ExchangeStore.java
@@ -46,7 +46,6 @@ import java.util.HashMap;
public class ExchangeStore extends Store {
public static final String LOG_TAG = "ExchangeStore";
- private Context mContext;
private URI mUri;
private final ExchangeTransport mTransport;
@@ -66,7 +65,6 @@ public class ExchangeStore extends Store {
*/
private ExchangeStore(String _uri, Context context, PersistentDataCallbacks callbacks)
throws MessagingException {
- mContext = context;
try {
mUri = new URI(_uri);
} catch (URISyntaxException e) {
@@ -157,14 +155,14 @@ public class ExchangeStore extends Store {
private static HashMap sUriToInstanceMap =
new HashMap();
- private static final HashMap sFolderMap = new HashMap();
/**
* Public factory. The transport should be a singleton (per Uri)
*/
public synchronized static ExchangeTransport getInstance(URI uri, Context context)
throws MessagingException {
- if (!uri.getScheme().equals("eas") && !uri.getScheme().equals("eas+ssl+")) {
+ if (!uri.getScheme().equals("eas") && !uri.getScheme().equals("eas+ssl+") &&
+ !uri.getScheme().equals("eas+tssl+")) {
throw new MessagingException("Invalid scheme");
}
@@ -221,9 +219,11 @@ public class ExchangeStore extends Store {
public void checkSettings(URI uri) throws MessagingException {
setUri(uri);
boolean ssl = uri.getScheme().contains("ssl+");
+ boolean tssl = uri.getScheme().contains("tssl+");
try {
+ int port = ssl ? 443 : 80;
int result = new EmailServiceProxy(mContext, SyncManager.class)
- .validate("eas", mHost, mUsername, mPassword, ssl ? 443 : 80, ssl);
+ .validate("eas", mHost, mUsername, mPassword, port, ssl, tssl);
if (result != MessagingException.NO_ERROR) {
if (result == MessagingException.AUTHENTICATION_FAILED) {
throw new AuthenticationFailedException("Authentication failed.");
diff --git a/src/com/android/email/mail/store/TrustManagerFactory.java b/src/com/android/email/mail/store/TrustManagerFactory.java
index 91154bc3a..bcd6a5593 100644
--- a/src/com/android/email/mail/store/TrustManagerFactory.java
+++ b/src/com/android/email/mail/store/TrustManagerFactory.java
@@ -16,18 +16,17 @@
package com.android.email.mail.store;
+import org.apache.harmony.xnet.provider.jsse.SSLParameters;
+
import android.net.http.DomainNameChecker;
-import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;
-import org.apache.harmony.xnet.provider.jsse.SSLParameters;
-
public final class TrustManagerFactory {
- private static X509TrustManager sUnsecureTrustManager
- = new SimpleX509TrustManager();
+ private static X509TrustManager sUnsecureTrustManager = new SimpleX509TrustManager();
private static class SimpleX509TrustManager implements X509TrustManager {
public void checkClientTrusted(X509Certificate[] chain, String authType)
@@ -63,8 +62,7 @@ public final class TrustManagerFactory {
mTrustManager.checkServerTrusted(chain, authType);
if (!DomainNameChecker.match(chain[0], mHost)) {
- throw new CertificateException("Certificate domain name does not match "
- + mHost);
+ throw new CertificateException("Certificate domain name does not match " + mHost);
}
}
@@ -77,8 +75,7 @@ public final class TrustManagerFactory {
}
public static X509TrustManager get(String host, boolean secure) {
- return secure ? new SecureX509TrustManager(
- SSLParameters.getDefaultTrustManager(), host)
+ return secure ? new SecureX509TrustManager(SSLParameters.getDefaultTrustManager(), host)
: sUnsecureTrustManager;
}
}
diff --git a/src/com/android/email/provider/EmailContent.java b/src/com/android/email/provider/EmailContent.java
index 3abd9d1d8..8db282a70 100644
--- a/src/com/android/email/provider/EmailContent.java
+++ b/src/com/android/email/provider/EmailContent.java
@@ -1916,6 +1916,7 @@ public abstract class EmailContent {
public static final int FLAG_SSL = 1;
public static final int FLAG_TLS = 2;
public static final int FLAG_AUTHENTICATE = 4;
+ public static final int FLAG_TRUST_ALL_CERTIFICATES = 8;
public String mProtocol;
public String mAddress;
@@ -2013,7 +2014,9 @@ public abstract class EmailContent {
*/
public String getStoreUri() {
String security = "";
- if ((mFlags & FLAG_SSL) != 0) {
+ if ((mFlags & FLAG_TRUST_ALL_CERTIFICATES) != 0) {
+ security = "+tssl+";
+ } else if ((mFlags & FLAG_SSL) != 0) {
security = "+ssl+";
} else if ((mFlags & FLAG_TLS) != 0) {
security = "+tls+";
@@ -2068,10 +2071,15 @@ public abstract class EmailContent {
mProtocol = (schemeParts.length >= 1) ? schemeParts[0] : null;
boolean ssl = false;
boolean tls = false;
+ boolean tssl = false;
if (schemeParts.length >= 2) {
- if ("ssl".equals(schemeParts[1])) {
+ String part1 = schemeParts[1];
+ if ("tssl".equals(part1)) {
ssl = true;
- } else if ("tls".equals(schemeParts[1])) {
+ tssl = true;
+ } else if ("ssl".equals(part1)) {
+ ssl = true;
+ } else if ("tls".equals(part1)) {
tls = true;
}
}
@@ -2083,6 +2091,9 @@ public abstract class EmailContent {
if (tls) {
mFlags |= FLAG_TLS;
}
+ if (tssl) {
+ mFlags |= FLAG_TRUST_ALL_CERTIFICATES;
+ }
mAddress = uri.getHost();
mPort = uri.getPort();
@@ -2092,11 +2103,11 @@ public abstract class EmailContent {
if ("pop3".equals(mProtocol)) {
mPort = ssl ? 995 : 110;
} else if ("imap".equals(mProtocol)) {
- mPort = ssl ? 993 : 143;
+ mPort = ssl || tssl ? 993 : 143;
} else if ("eas".equals(mProtocol)) {
- mPort = ssl ? 443 : 80;
+ mPort = ssl || tssl ? 443 : 80;
} else if ("smtp".equals(mProtocol)) {
- mPort = ssl ? 465 : 25;
+ mPort = ssl || tssl ? 465 : 25;
}
}
diff --git a/src/com/android/email/service/EmailServiceProxy.java b/src/com/android/email/service/EmailServiceProxy.java
index 1bb0df3c7..423ae695f 100644
--- a/src/com/android/email/service/EmailServiceProxy.java
+++ b/src/com/android/email/service/EmailServiceProxy.java
@@ -184,12 +184,14 @@ public class EmailServiceProxy implements IEmailService {
}
public int validate(final String protocol, final String host, final String userName,
- final String password, final int port, final boolean ssl) throws RemoteException {
+ final String password, final int port, final boolean ssl,
+ final boolean trustCertificates) throws RemoteException {
setTask(new Runnable () {
public void run() {
try {
if (mCallback != null) mService.setCallback(mCallback);
- mReturn = mService.validate(protocol, host, userName, password, port, ssl);
+ mReturn = mService.validate(protocol, host, userName, password, port, ssl,
+ trustCertificates);
} catch (RemoteException e) {
}
}
diff --git a/src/com/android/exchange/AbstractSyncService.java b/src/com/android/exchange/AbstractSyncService.java
index 15cede872..97cfb8767 100644
--- a/src/com/android/exchange/AbstractSyncService.java
+++ b/src/com/android/exchange/AbstractSyncService.java
@@ -101,7 +101,7 @@ public abstract class AbstractSyncService implements Runnable {
* @throws MessagingException
*/
public abstract void validateAccount(String host, String userName, String password, int port,
- boolean ssl, Context context) throws MessagingException;
+ boolean ssl, boolean trustCertificates, Context context) throws MessagingException;
public AbstractSyncService(Context _context, Mailbox _mailbox) {
mContext = _context;
@@ -129,12 +129,13 @@ public abstract class AbstractSyncService implements Runnable {
* @throws MessagingException
*/
static public void validate(Class extends AbstractSyncService> klass, String host,
- String userName, String password, int port, boolean ssl, Context context)
+ String userName, String password, int port, boolean ssl, boolean trustCertificates,
+ Context context)
throws MessagingException {
AbstractSyncService svc;
try {
svc = klass.newInstance();
- svc.validateAccount(host, userName, password, port, ssl, context);
+ svc.validateAccount(host, userName, password, port, ssl, trustCertificates, context);
} catch (IllegalAccessException e) {
throw new MessagingException("internal error", e);
} catch (InstantiationException e) {
diff --git a/src/com/android/exchange/EasSyncService.java b/src/com/android/exchange/EasSyncService.java
index b4f2ac414..7c1e3ae36 100644
--- a/src/com/android/exchange/EasSyncService.java
+++ b/src/com/android/exchange/EasSyncService.java
@@ -46,6 +46,7 @@ import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpOptions;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
@@ -65,11 +66,11 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URLEncoder;
+import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.HashMap;
public class EasSyncService extends AbstractSyncService {
-
private static final String EMAIL_WINDOW_SIZE = "5";
public static final String PIM_WINDOW_SIZE = "20";
private static final String WHERE_ACCOUNT_KEY_AND_SERVER_ID =
@@ -133,6 +134,7 @@ public class EasSyncService extends AbstractSyncService {
public String mUserName;
public String mPassword;
private boolean mSsl = true;
+ private boolean mTrustSsl = false;
public ContentResolver mContentResolver;
private String[] mBindArguments = new String[2];
private ArrayList mPingChangeList;
@@ -149,6 +151,7 @@ public class EasSyncService extends AbstractSyncService {
mContentResolver = _context.getContentResolver();
HostAuth ha = HostAuth.restoreHostAuthWithId(_context, mAccount.mHostAuthKeyRecv);
mSsl = (ha.mFlags & HostAuth.FLAG_SSL) != 0;
+ mTrustSsl = (ha.mFlags & HostAuth.FLAG_TRUST_ALL_CERTIFICATES) != 0;
}
private EasSyncService(String prefix) {
@@ -191,7 +194,7 @@ public class EasSyncService extends AbstractSyncService {
@Override
public void validateAccount(String hostAddress, String userName, String password, int port,
- boolean ssl, Context context) throws MessagingException {
+ boolean ssl, boolean trustCertificates, Context context) throws MessagingException {
try {
userLog("Testing EAS: ", hostAddress, ", ", userName, ", ssl = ", ssl ? "1" : "0");
EasSyncService svc = new EasSyncService("%TestAccount%");
@@ -200,6 +203,7 @@ public class EasSyncService extends AbstractSyncService {
svc.mUserName = userName;
svc.mPassword = password;
svc.mSsl = ssl;
+ svc.mTrustSsl = trustCertificates;
svc.mDeviceId = SyncManager.getDeviceId();
HttpResponse resp = svc.sendHttpClientOptions();
int code = resp.getStatusLine().getStatusCode();
@@ -218,7 +222,12 @@ public class EasSyncService extends AbstractSyncService {
throw new MessagingException(MessagingException.IOERROR);
}
} catch (IOException e) {
- userLog("IOException caught, reporting I/O error: ", e.getMessage());
+ Throwable cause = e.getCause();
+ if (cause != null && cause instanceof CertificateException) {
+ userLog("CertificateException caught: ", e.getMessage());
+ throw new MessagingException(MessagingException.GENERAL_SECURITY);
+ }
+ userLog("IOException caught: ", e.getMessage());
throw new MessagingException(MessagingException.IOERROR);
}
@@ -351,7 +360,7 @@ public class EasSyncService extends AbstractSyncService {
mCmdString = "&User=" + safeUserName + "&DeviceId=" + mDeviceId + "&DeviceType="
+ mDeviceType;
}
- String us = (mSsl ? "https" : "http") + "://" + mHostAddress +
+ String us = (mSsl ? (mTrustSsl ? "httpts" : "https") : "http") + "://" + mHostAddress +
"/Microsoft-Server-ActiveSync";
if (cmd != null) {
us += "?Cmd=" + cmd + mCmdString;
@@ -369,11 +378,17 @@ public class EasSyncService extends AbstractSyncService {
method.setHeader("User-Agent", mDeviceType + '/' + Eas.VERSION);
}
+ private ClientConnectionManager getClientConnectionManager() {
+ return SyncManager.getClientConnectionManager();
+ }
+
private HttpClient getHttpClient(int timeout) {
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, 15*SECONDS);
HttpConnectionParams.setSoTimeout(params, timeout);
- return new DefaultHttpClient(params);
+ HttpConnectionParams.setSocketBufferSize(params, 8192);
+ HttpClient client = new DefaultHttpClient(getClientConnectionManager(), params);
+ return client;
}
protected HttpResponse sendHttpClientPost(String cmd, byte[] bytes) throws IOException {
diff --git a/src/com/android/exchange/IEmailService.aidl b/src/com/android/exchange/IEmailService.aidl
index 23ff74494..a07fab00b 100644
--- a/src/com/android/exchange/IEmailService.aidl
+++ b/src/com/android/exchange/IEmailService.aidl
@@ -21,7 +21,7 @@ import com.android.exchange.EmailContent;
interface IEmailService {
int validate(in String protocol, in String host, in String userName, in String password,
- int port, boolean ssl) ;
+ int port, boolean ssl, boolean trustCertificates) ;
void startSync(long mailboxId);
void stopSync(long mailboxId);
diff --git a/src/com/android/exchange/SyncManager.java b/src/com/android/exchange/SyncManager.java
index 96196e6c7..3c4cb1359 100644
--- a/src/com/android/exchange/SyncManager.java
+++ b/src/com/android/exchange/SyncManager.java
@@ -18,6 +18,7 @@
package com.android.exchange;
import com.android.email.mail.MessagingException;
+import com.android.email.mail.store.TrustManagerFactory;
import com.android.email.provider.EmailContent;
import com.android.email.provider.EmailContent.Account;
import com.android.email.provider.EmailContent.Attachment;
@@ -29,6 +30,19 @@ import com.android.email.provider.EmailContent.Message;
import com.android.email.provider.EmailContent.SyncColumns;
import com.android.exchange.utility.FileLogger;
+import org.apache.harmony.xnet.provider.jsse.SSLContextImpl;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.params.ConnManagerPNames;
+import org.apache.http.conn.params.ConnPerRoute;
+import org.apache.http.conn.routing.HttpRoute;
+import org.apache.http.conn.scheme.PlainSocketFactory;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeRegistry;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.HttpParams;
+
import android.accounts.AccountManager;
import android.accounts.OnAccountsUpdatedListener;
import android.app.AlarmManager;
@@ -65,10 +79,16 @@ import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
/**
* The SyncManager handles all aspects of starting, maintaining, and stopping the various sync
* adapters used by Exchange. However, it is capable of handing any kind of email sync, and it
@@ -176,6 +196,8 @@ public class SyncManager extends Service implements Runnable {
private static Thread sServiceThread = null;
// Cached unique device id
private static String sDeviceId = null;
+ // ConnectionManager that all EAS threads can use
+ private static ClientConnectionManager sClientConnectionManager = null;
private boolean mStop = false;
@@ -240,10 +262,10 @@ public class SyncManager extends Service implements Runnable {
private final IEmailService.Stub mBinder = new IEmailService.Stub() {
public int validate(String protocol, String host, String userName, String password,
- int port, boolean ssl) throws RemoteException {
+ int port, boolean ssl, boolean trustCertificates) throws RemoteException {
try {
AbstractSyncService.validate(EasSyncService.class, host, userName, password, port,
- ssl, SyncManager.this);
+ ssl, trustCertificates, SyncManager.this);
return MessagingException.NO_ERROR;
} catch (MessagingException e) {
return e.getExceptionType();
@@ -672,6 +694,52 @@ public class SyncManager extends Service implements Runnable {
}
}
+ static public ConnPerRoute sConnPerRoute = new ConnPerRoute() {
+ public int getMaxForRoute(HttpRoute route) {
+ return 8;
+ }
+ };
+
+ static public synchronized ClientConnectionManager getClientConnectionManager() {
+ if (sClientConnectionManager == null) {
+ // Create a registry for our three schemes; http and https will use built-in factories
+ SchemeRegistry registry = new SchemeRegistry();
+ registry.register(new Scheme("http",
+ PlainSocketFactory.getSocketFactory(), 80));
+ registry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
+
+ // Create a new SSLSocketFactory for our "trusted ssl"
+ // Get the unsecure trust manager from the factory
+ X509TrustManager trustManager = TrustManagerFactory.get(null, false);
+ TrustManager[] trustManagers = new TrustManager[] {trustManager};
+ SSLContext sslcontext;
+ try {
+ sslcontext = SSLContext.getInstance("TLS");
+ sslcontext.init(null, trustManagers, null);
+ SSLContextImpl sslContext = new SSLContextImpl();
+ try {
+ sslContext.engineInit(null, trustManagers, null, null, null);
+ } catch (KeyManagementException e) {
+ throw new AssertionError(e);
+ }
+ // Ok, now make our factory
+ SSLSocketFactory sf = new SSLSocketFactory(sslContext.engineGetSocketFactory());
+ sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+ // Register the httpts scheme with our factory
+ registry.register(new Scheme("httpts", sf, 443));
+ // And create a ccm with our registry
+ HttpParams params = new BasicHttpParams();
+ params.setIntParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 25);
+ params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, sConnPerRoute);
+ sClientConnectionManager = new ThreadSafeClientConnManager(params, registry);
+ } catch (NoSuchAlgorithmException e2) {
+ } catch (KeyManagementException e1) {
+ }
+ }
+ // Null is a valid return result if we get an exception
+ return sClientConnectionManager;
+ }
+
@Override
public void onDestroy() {
log("!!! EAS SyncManager destroyed");
diff --git a/tests/src/com/android/email/activity/setup/AccountSetupExchangeTests.java b/tests/src/com/android/email/activity/setup/AccountSetupExchangeTests.java
index f23b075d7..2a77ba94b 100644
--- a/tests/src/com/android/email/activity/setup/AccountSetupExchangeTests.java
+++ b/tests/src/com/android/email/activity/setup/AccountSetupExchangeTests.java
@@ -38,7 +38,6 @@ public class AccountSetupExchangeTests extends
private AccountSetupExchange mActivity;
private EditText mServerView;
- private EditText mDomainView;
private Button mNextButton;
public AccountSetupExchangeTests() {
@@ -56,7 +55,7 @@ public class AccountSetupExchangeTests extends
// This sets up a default URI which can be used by any of the test methods below.
// Individual test methods can replace this with a custom URI if they wish
// (except those that run on the UI thread - for them, it's too late to change it.)
- Intent i = getTestIntent("eas://user:password@server.com/domain");
+ Intent i = getTestIntent("eas://user:password@server.com");
setActivityIntent(i);
}
@@ -64,17 +63,20 @@ public class AccountSetupExchangeTests extends
* Test processing with a complete, good URI -> good fields
*/
public void testGoodUri() {
- Intent i = getTestIntent("eas://user:password@server.com/domain");
+ Intent i = getTestIntent("eas://user:password@server.com");
setActivityIntent(i);
getActivityAndFields();
assertTrue(mNextButton.isEnabled());
}
+ // TODO Add tests for valid usernames in eas
+ // They would be or \ or / or a valid email address
+
/**
* No user is not OK - not enabled
*/
public void testBadUriNoUser() {
- Intent i = getTestIntent("eas://:password@server.com/domain");
+ Intent i = getTestIntent("eas://:password@server.com");
setActivityIntent(i);
getActivityAndFields();
assertFalse(mNextButton.isEnabled());
@@ -84,7 +86,7 @@ public class AccountSetupExchangeTests extends
* No password is not OK - not enabled
*/
public void testBadUriNoPassword() {
- Intent i = getTestIntent("eas://user@server.com/domain");
+ Intent i = getTestIntent("eas://user@server.com");
setActivityIntent(i);
getActivityAndFields();
assertFalse(mNextButton.isEnabled());
@@ -116,49 +118,6 @@ public class AccountSetupExchangeTests extends
mServerView.setText("serv$er.com");
assertFalse(mNextButton.isEnabled());
}
-
- /**
- * No EAS domain is OK - enabled
- */
- public void testBadUriNoDomain() {
- Intent i = getTestIntent("eas://user:password@server.com");
- setActivityIntent(i);
- getActivityAndFields();
- assertTrue(mNextButton.isEnabled());
- }
-
- /**
- * Test for non-standard but OK domain names
- */
- @UiThreadTest
- public void testGoodDomainVariants() {
- getActivityAndFields();
- assertTrue(mNextButton.isEnabled());
-
- mDomainView.setText(" domain ");
- assertTrue(mNextButton.isEnabled());
- }
-
- /**
- * Test for non-empty but non-OK domain names
- *
- * TODO: These are tests that *should* fail but the code is not checking these cases
- */
- @UiThreadTest
- public void disabled_testBadDomainVariants() {
- getActivityAndFields();
- assertTrue(mNextButton.isEnabled());
-
- mDomainView.setText(" ");
- assertTrue(mNextButton.isEnabled());
-
- mDomainView.setText("do main");
- assertFalse(mNextButton.isEnabled());
- }
-
- /**
- * TODO: More tests of exchange-specific fields?
- */
/**
* Get the activity (which causes it to be started, using our intent) and get the UI fields
@@ -166,7 +125,6 @@ public class AccountSetupExchangeTests extends
private void getActivityAndFields() {
mActivity = getActivity();
mServerView = (EditText) mActivity.findViewById(R.id.account_server);
- mDomainView = (EditText) mActivity.findViewById(R.id.account_domain);
mNextButton = (Button) mActivity.findViewById(R.id.next);
}