Support non-standard ports in EAS

Bug: 6469962
Change-Id: I94fa8b45a2211cd908cbd56c057ae49167285507
diff --git a/exchange2/src/com/android/exchange/EasSyncService.java b/exchange2/src/com/android/exchange/EasSyncService.java
index 863e322..657bc84 100644
--- a/exchange2/src/com/android/exchange/EasSyncService.java
+++ b/exchange2/src/com/android/exchange/EasSyncService.java
@@ -166,6 +166,7 @@
     private boolean mSsl = true;
     private boolean mTrustSsl = false;
     private String mClientCertAlias = null;
+    private int mPort;
 
     public ContentResolver mContentResolver;
     // Whether or not the sync service is valid (usable)
@@ -387,10 +388,7 @@
         svc.mUserName = ha.mLogin;
         svc.mPassword = ha.mPassword;
         try {
-            svc.setConnectionParameters(
-                    (ha.mFlags & HostAuth.FLAG_SSL) != 0,
-                    (ha.mFlags & HostAuth.FLAG_TRUST_ALL) != 0,
-                    ha.mClientCertAlias);
+            svc.setConnectionParameters(ha);
             svc.mDeviceId = ExchangeService.getDeviceId(context);
         } catch (IOException e) {
             return null;
@@ -441,10 +439,7 @@
             mUserName = hostAuth.mLogin;
             mPassword = hostAuth.mPassword;
 
-            setConnectionParameters(
-                    hostAuth.shouldUseSsl(),
-                    hostAuth.shouldTrustAllServerCerts(),
-                    hostAuth.mClientCertAlias);
+            setConnectionParameters(hostAuth);
             mDeviceId = ExchangeService.getDeviceId(context);
             mAccount = new Account();
             mAccount.mEmailAddress = hostAuth.mLogin;
@@ -705,6 +700,10 @@
             // Initialize the user name and password
             mUserName = userName;
             mPassword = password;
+            // Port is always 443 and SSL is used
+            mPort = 443;
+            mSsl = true;
+
             // Make sure the authentication string is recreated and cached
             cacheAuthUserAndBaseUriStrings();
 
@@ -1215,26 +1214,23 @@
         }
     }
 
-    protected void setConnectionParameters(
-            boolean useSsl, boolean trustAllServerCerts, String clientCertAlias)
-            throws CertificateException {
-
-        EmailClientConnectionManager connManager = getClientConnectionManager();
-
-        mSsl = useSsl;
-        mTrustSsl = trustAllServerCerts;
-        mClientCertAlias = clientCertAlias;
+    protected void setConnectionParameters(HostAuth hostAuth) throws CertificateException {
+        mSsl = hostAuth.shouldUseSsl();
+        mTrustSsl = hostAuth.shouldTrustAllServerCerts();
+        mClientCertAlias = hostAuth.mClientCertAlias;
+        mPort = hostAuth.mPort;
 
         // Register the new alias, if needed.
         if (mClientCertAlias != null) {
             // Ensure that the connection manager knows to use the proper client certificate
             // when establishing connections for this service.
-            connManager.registerClientCert(mContext, mClientCertAlias, mTrustSsl);
+            EmailClientConnectionManager connManager = getClientConnectionManager();
+            connManager.registerClientCert(mContext, hostAuth);
         }
     }
 
     private EmailClientConnectionManager getClientConnectionManager() {
-        return ExchangeService.getClientConnectionManager();
+        return ExchangeService.getClientConnectionManager(mSsl, mPort);
     }
 
     private HttpClient getHttpClient(int timeout) {
@@ -1805,10 +1801,7 @@
         mPassword = ha.mPassword;
 
         try {
-            setConnectionParameters(
-                    (ha.mFlags & HostAuth.FLAG_SSL) != 0,
-                    (ha.mFlags & HostAuth.FLAG_TRUST_ALL) != 0,
-                    ha.mClientCertAlias);
+            setConnectionParameters(ha);
         } catch (CertificateException e) {
             userLog("Couldn't retrieve certificate for connection");
             try {
diff --git a/exchange2/src/com/android/exchange/ExchangeService.java b/exchange2/src/com/android/exchange/ExchangeService.java
index 0107d55..b1ae3b7 100644
--- a/exchange2/src/com/android/exchange/ExchangeService.java
+++ b/exchange2/src/com/android/exchange/ExchangeService.java
@@ -220,8 +220,9 @@
     private static Thread sServiceThread = null;
     // Cached unique device id
     private static String sDeviceId = null;
-    // ConnectionManager that all EAS threads can use
-    private static EmailClientConnectionManager sClientConnectionManager = null;
+    // HashMap of ConnectionManagers that all EAS threads can use (by ssl/port pair)
+    private static HashMap<Integer, EmailClientConnectionManager> sClientConnectionManagers =
+            new HashMap<Integer, EmailClientConnectionManager>();
     // Count of ClientConnectionManager shutdowns
     private static volatile int sClientConnectionManagerShutdownCount = 0;
 
@@ -1263,8 +1264,12 @@
         }
     };
 
-    static public synchronized EmailClientConnectionManager getClientConnectionManager() {
-        if (sClientConnectionManager == null) {
+    static public synchronized EmailClientConnectionManager getClientConnectionManager(boolean ssl,
+            int port) {
+        // We'll use a different connection manager for each ssl/port pair
+        int key = (ssl ? 0x10000 : 0) + port;
+        EmailClientConnectionManager mgr = sClientConnectionManagers.get(key);
+        if (mgr == null) {
             // After two tries, kill the process.  Most likely, this will happen in the background
             // The service will restart itself after about 5 seconds
             if (sClientConnectionManagerShutdownCount > MAX_CLIENT_CONNECTION_MANAGER_SHUTDOWNS) {
@@ -1274,19 +1279,20 @@
             HttpParams params = new BasicHttpParams();
             params.setIntParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 25);
             params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, sConnPerRoute);
-            sClientConnectionManager = EmailClientConnectionManager.newInstance(params);
+            mgr = EmailClientConnectionManager.newInstance(params, ssl, port);
+            log("Creating connection manager for port " + port + ", ssl: " + ssl);
+            sClientConnectionManagers.put(key, mgr);
         }
         // Null is a valid return result if we get an exception
-        return sClientConnectionManager;
+        return mgr;
     }
 
     static private synchronized void shutdownConnectionManager() {
-        if (sClientConnectionManager != null) {
-            log("Shutting down ClientConnectionManager");
-            sClientConnectionManager.shutdown();
-            sClientConnectionManagerShutdownCount++;
-            sClientConnectionManager = null;
+        log("Shutting down ClientConnectionManagers");
+        for (EmailClientConnectionManager mgr: sClientConnectionManagers.values()) {
+            mgr.shutdown();
         }
+        sClientConnectionManagers.clear();
     }
 
     public static void stopAccountSyncs(long acctId) {