18bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller/* 28bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller * Licensed to the Apache Software Foundation (ASF) under one or more 38bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller * contributor license agreements. See the NOTICE file distributed with 48bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller * this work for additional information regarding copyright ownership. 58bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller * The ASF licenses this file to You under the Apache License, Version 2.0 68bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller * (the "License"); you may not use this file except in compliance with 78bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller * the License. You may obtain a copy of the License at 88bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller * 98bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller * http://www.apache.org/licenses/LICENSE-2.0 108bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller * 118bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller * Unless required by applicable law or agreed to in writing, software 128bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller * distributed under the License is distributed on an "AS IS" BASIS, 138bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 148bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller * See the License for the specific language governing permissions and 158bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller * limitations under the License. 168bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller */ 178bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller 188bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fullerpackage com.squareup.okhttp; 198bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller 208bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fullerimport libcore.net.event.NetworkEventDispatcher; 218bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fullerimport libcore.net.event.NetworkEventListener; 228bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller 238bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller/** 248bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller * A provider of the shared Android {@link ConnectionPool}. This class is aware of network 258bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller * configuration change events: When the network configuration changes the pool object is discarded 268bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller * and a later calls to {@link #get()} will return a new pool. 278bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller */ 288bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fullerpublic class ConfigAwareConnectionPool { 298bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller 308bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller private static final long CONNECTION_POOL_DEFAULT_KEEP_ALIVE_DURATION_MS = 5 * 60 * 1000; // 5 min 318bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller 328bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller private static final int CONNECTION_POOL_MAX_IDLE_CONNECTIONS; 338bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller private static final long CONNECTION_POOL_KEEP_ALIVE_DURATION_MS; 348bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller static { 358bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller String keepAliveProperty = System.getProperty("http.keepAlive"); 368bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller String keepAliveDurationProperty = System.getProperty("http.keepAliveDuration"); 378bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller String maxIdleConnectionsProperty = System.getProperty("http.maxConnections"); 388bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller CONNECTION_POOL_KEEP_ALIVE_DURATION_MS = (keepAliveDurationProperty != null 398bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller ? Long.parseLong(keepAliveDurationProperty) 408bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller : CONNECTION_POOL_DEFAULT_KEEP_ALIVE_DURATION_MS); 418bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller if (keepAliveProperty != null && !Boolean.parseBoolean(keepAliveProperty)) { 428bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller CONNECTION_POOL_MAX_IDLE_CONNECTIONS = 0; 438bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller } else if (maxIdleConnectionsProperty != null) { 448bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller CONNECTION_POOL_MAX_IDLE_CONNECTIONS = Integer.parseInt(maxIdleConnectionsProperty); 458bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller } else { 468bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller CONNECTION_POOL_MAX_IDLE_CONNECTIONS = 5; 478bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller } 488bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller } 498bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller 508bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller private static final ConfigAwareConnectionPool instance = new ConfigAwareConnectionPool(); 518bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller 528bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller private final NetworkEventDispatcher networkEventDispatcher; 538bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller 548bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller /** 558bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller * {@code true} if the ConnectionPool reset has been registered with the 568bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller * {@link NetworkEventDispatcher}. 578bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller */ 588bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller private boolean networkEventListenerRegistered; 598bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller 608bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller private ConnectionPool connectionPool; 618bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller 628bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller /** Visible for testing. Use {@link #getInstance()} */ 638bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller protected ConfigAwareConnectionPool(NetworkEventDispatcher networkEventDispatcher) { 648bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller this.networkEventDispatcher = networkEventDispatcher; 658bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller } 668bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller 678bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller private ConfigAwareConnectionPool() { 688bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller networkEventDispatcher = NetworkEventDispatcher.getInstance(); 698bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller } 708bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller 718bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller public static ConfigAwareConnectionPool getInstance() { 728bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller return instance; 738bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller } 748bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller 758bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller /** 768bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller * Returns the current {@link ConnectionPool} to use. 778bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller */ 788bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller public synchronized ConnectionPool get() { 798bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller if (connectionPool == null) { 808bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller // Only register the listener once the first time a ConnectionPool is created. 818bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller if (!networkEventListenerRegistered) { 828bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller networkEventDispatcher.addListener(new NetworkEventListener() { 838bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller @Override 848bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller public void onNetworkConfigurationChanged() { 858bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller synchronized (ConfigAwareConnectionPool.this) { 868bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller // If the network config has changed then existing pooled connections should not be 878bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller // re-used. By setting connectionPool to null it ensures that the next time 888bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller // getConnectionPool() is called a new pool will be created. 898bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller connectionPool = null; 908bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller } 918bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller } 928bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller }); 938bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller networkEventListenerRegistered = true; 948bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller } 958bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller connectionPool = new ConnectionPool( 968bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller CONNECTION_POOL_MAX_IDLE_CONNECTIONS, CONNECTION_POOL_KEEP_ALIVE_DURATION_MS); 978bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller } 988bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller return connectionPool; 998bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller } 1008bced3e769d315a0a81b89de7a5282f1a85acbf7Neil Fuller} 101