1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package com.squareup.okhttp; 19 20 import libcore.net.event.NetworkEventDispatcher; 21 import libcore.net.event.NetworkEventListener; 22 23 /** 24 * A provider of the shared Android {@link ConnectionPool}. This class is aware of network 25 * configuration change events: When the network configuration changes the pool object is discarded 26 * and a later calls to {@link #get()} will return a new pool. 27 */ 28 public class ConfigAwareConnectionPool { 29 30 private static final long CONNECTION_POOL_DEFAULT_KEEP_ALIVE_DURATION_MS = 5 * 60 * 1000; // 5 min 31 32 private static final int CONNECTION_POOL_MAX_IDLE_CONNECTIONS; 33 private static final long CONNECTION_POOL_KEEP_ALIVE_DURATION_MS; 34 static { 35 String keepAliveProperty = System.getProperty("http.keepAlive"); 36 String keepAliveDurationProperty = System.getProperty("http.keepAliveDuration"); 37 String maxIdleConnectionsProperty = System.getProperty("http.maxConnections"); 38 CONNECTION_POOL_KEEP_ALIVE_DURATION_MS = (keepAliveDurationProperty != null 39 ? Long.parseLong(keepAliveDurationProperty) 40 : CONNECTION_POOL_DEFAULT_KEEP_ALIVE_DURATION_MS); 41 if (keepAliveProperty != null && !Boolean.parseBoolean(keepAliveProperty)) { 42 CONNECTION_POOL_MAX_IDLE_CONNECTIONS = 0; 43 } else if (maxIdleConnectionsProperty != null) { 44 CONNECTION_POOL_MAX_IDLE_CONNECTIONS = Integer.parseInt(maxIdleConnectionsProperty); 45 } else { 46 CONNECTION_POOL_MAX_IDLE_CONNECTIONS = 5; 47 } 48 } 49 50 private static final ConfigAwareConnectionPool instance = new ConfigAwareConnectionPool(); 51 52 private final NetworkEventDispatcher networkEventDispatcher; 53 54 /** 55 * {@code true} if the ConnectionPool reset has been registered with the 56 * {@link NetworkEventDispatcher}. 57 */ 58 private boolean networkEventListenerRegistered; 59 60 private ConnectionPool connectionPool; 61 62 /** Visible for testing. Use {@link #getInstance()} */ ConfigAwareConnectionPool(NetworkEventDispatcher networkEventDispatcher)63 protected ConfigAwareConnectionPool(NetworkEventDispatcher networkEventDispatcher) { 64 this.networkEventDispatcher = networkEventDispatcher; 65 } 66 ConfigAwareConnectionPool()67 private ConfigAwareConnectionPool() { 68 networkEventDispatcher = NetworkEventDispatcher.getInstance(); 69 } 70 getInstance()71 public static ConfigAwareConnectionPool getInstance() { 72 return instance; 73 } 74 75 /** 76 * Returns the current {@link ConnectionPool} to use. 77 */ get()78 public synchronized ConnectionPool get() { 79 if (connectionPool == null) { 80 // Only register the listener once the first time a ConnectionPool is created. 81 if (!networkEventListenerRegistered) { 82 networkEventDispatcher.addListener(new NetworkEventListener() { 83 @Override 84 public void onNetworkConfigurationChanged() { 85 synchronized (ConfigAwareConnectionPool.this) { 86 // If the network config has changed then existing pooled connections should not be 87 // re-used. By setting connectionPool to null it ensures that the next time 88 // getConnectionPool() is called a new pool will be created. 89 connectionPool = null; 90 } 91 } 92 }); 93 networkEventListenerRegistered = true; 94 } 95 connectionPool = new ConnectionPool( 96 CONNECTION_POOL_MAX_IDLE_CONNECTIONS, CONNECTION_POOL_KEEP_ALIVE_DURATION_MS); 97 } 98 return connectionPool; 99 } 100 } 101