EasConnectionCache.java revision 9383babdbd7c0049a0eb238819a5d9737232e8ec
1package com.android.exchange.eas; 2 3import android.content.Context; 4 5import com.android.emailcommon.provider.HostAuth; 6import com.android.emailcommon.utility.EmailClientConnectionManager; 7import com.android.exchange.Eas; 8import com.android.mail.utils.LogUtils; 9 10import org.apache.http.conn.params.ConnManagerPNames; 11import org.apache.http.conn.params.ConnPerRoute; 12import org.apache.http.conn.routing.HttpRoute; 13import org.apache.http.params.BasicHttpParams; 14import org.apache.http.params.HttpParams; 15 16import java.util.HashMap; 17 18/** 19 * Manage all {@link EmailClientConnectionManager}s used by Exchange operations. 20 * When making connections for persisted accounts, this class will cache and reuse connections 21 * as much as possible. All access of connection objects should accordingly go through this class. 22 * 23 * We use {@link HostAuth}'s id as the cache key. Multiple calls to {@link #getConnectionManager} 24 * with {@link HostAuth} objects with the same id will get the same connection object returned, 25 * i.e. we assume that the rest of the contents of the {@link HostAuth} objects are also the same, 26 * not just the id. If the {@link HostAuth} changes or is deleted, {@link #uncacheConnectionManager} 27 * must be called. 28 * 29 * This cache is a singleton since the whole point is to not have multiples. 30 */ 31public class EasConnectionCache { 32 33 private final HashMap<Long, EmailClientConnectionManager> mConnectionMap; 34 35 private static final ConnPerRoute sConnPerRoute = new ConnPerRoute() { 36 @Override 37 public int getMaxForRoute(final HttpRoute route) { 38 return 8; 39 } 40 }; 41 42 /** The singleton instance of the cache. */ 43 private static EasConnectionCache sCache = null; 44 45 /** Accessor for the cache singleton. */ 46 public static EasConnectionCache instance() { 47 if (sCache == null) { 48 sCache = new EasConnectionCache(); 49 } 50 return sCache; 51 } 52 53 private EasConnectionCache() { 54 mConnectionMap = new HashMap<Long, EmailClientConnectionManager>(); 55 } 56 57 /** 58 * Create an {@link EmailClientConnectionManager} for this {@link HostAuth}. 59 * @param context The {@link Context}. 60 * @param hostAuth The {@link HostAuth} to which we want to connect. 61 * @return The {@link EmailClientConnectionManager} for hostAuth. 62 */ 63 private EmailClientConnectionManager createConnectionManager(final Context context, 64 final HostAuth hostAuth) { 65 LogUtils.i(Eas.LOG_TAG, "Creating connection for HostAuth %d", hostAuth.mId); 66 final HttpParams params = new BasicHttpParams(); 67 params.setIntParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 25); 68 params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, sConnPerRoute); 69 return EmailClientConnectionManager.newInstance(context, params, hostAuth); 70 } 71 72 /** 73 * Get the correct {@link EmailClientConnectionManager} for a {@link HostAuth} from our cache. 74 * If it's not in the cache, create and add it. 75 * @param context The {@link Context}. 76 * @param hostAuth The {@link HostAuth} to which we want to connect. 77 * @return The {@link EmailClientConnectionManager} for hostAuth. 78 */ 79 private synchronized EmailClientConnectionManager getCachedConnectionManager( 80 final Context context, final HostAuth hostAuth) { 81 LogUtils.i(Eas.LOG_TAG, "Reusing cached connection for HostAuth %d", hostAuth.mId); 82 EmailClientConnectionManager connectionManager = mConnectionMap.get(hostAuth.mId); 83 if (connectionManager == null) { 84 connectionManager = createConnectionManager(context, hostAuth); 85 mConnectionMap.put(hostAuth.mId, connectionManager); 86 } 87 return connectionManager; 88 } 89 90 /** 91 * Get the correct {@link EmailClientConnectionManager} for a {@link HostAuth}. If the 92 * {@link HostAuth} is persistent, then use the cache for this request. 93 * @param context The {@link Context}. 94 * @param hostAuth The {@link HostAuth} to which we want to connect. 95 * @return The {@link EmailClientConnectionManager} for hostAuth. 96 */ 97 public EmailClientConnectionManager getConnectionManager( 98 final Context context, final HostAuth hostAuth) { 99 final EmailClientConnectionManager connectionManager; 100 // We only cache the connection manager for persisted HostAuth objects, i.e. objects 101 // whose ids are permanent and won't get reused by other transient HostAuth objects. 102 if (hostAuth.isSaved()) { 103 connectionManager = getCachedConnectionManager(context, hostAuth); 104 } else { 105 connectionManager = createConnectionManager(context, hostAuth); 106 } 107 return connectionManager; 108 } 109 110 /** 111 * Remove a connection manager from the cache. This is necessary when a {@link HostAuth} is 112 * redirected or otherwise altered. It's not strictly necessary but good to also call this 113 * when a {@link HostAuth} is deleted, i.e. when an account is removed. 114 * @param hostAuth The {@link HostAuth} whose connection manager should be deleted. 115 */ 116 public synchronized void uncacheConnectionManager(final HostAuth hostAuth) { 117 LogUtils.i(Eas.LOG_TAG, "Uncaching connection for HostAuth %d", hostAuth.mId); 118 mConnectionMap.remove(hostAuth.mId); 119 } 120} 121