Merge "Changes associated with an OkHttp upgrade"

This commit is contained in:
Neil Fuller
2015-01-20 12:50:47 +00:00
committed by Gerrit Code Review
2 changed files with 60 additions and 50 deletions

View File

@@ -16,7 +16,6 @@
package android.net; package android.net;
import android.net.NetworkUtils;
import android.os.Parcelable; import android.os.Parcelable;
import android.os.Parcel; import android.os.Parcel;
import android.system.ErrnoException; import android.system.ErrnoException;
@@ -31,15 +30,14 @@ import java.net.SocketException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.util.concurrent.atomic.AtomicReference;
import javax.net.SocketFactory; import javax.net.SocketFactory;
import com.android.okhttp.ConnectionPool; import com.android.okhttp.ConnectionPool;
import com.android.okhttp.HostResolver;
import com.android.okhttp.HttpHandler; import com.android.okhttp.HttpHandler;
import com.android.okhttp.HttpsHandler; import com.android.okhttp.HttpsHandler;
import com.android.okhttp.OkHttpClient; import com.android.okhttp.OkHttpClient;
import com.android.okhttp.OkUrlFactory;
import com.android.okhttp.internal.Internal;
/** /**
* Identifies a {@code Network}. This is supplied to applications via * Identifies a {@code Network}. This is supplied to applications via
@@ -60,10 +58,10 @@ public class Network implements Parcelable {
// Objects used to perform per-network operations such as getSocketFactory // Objects used to perform per-network operations such as getSocketFactory
// and openConnection, and a lock to protect access to them. // and openConnection, and a lock to protect access to them.
private volatile NetworkBoundSocketFactory mNetworkBoundSocketFactory = null; private volatile NetworkBoundSocketFactory mNetworkBoundSocketFactory = null;
// mLock should be used to control write access to mConnectionPool and mHostResolver. // mLock should be used to control write access to mConnectionPool and mNetwork.
// maybeInitHttpClient() must be called prior to reading either variable. // maybeInitHttpClient() must be called prior to reading either variable.
private volatile ConnectionPool mConnectionPool = null; private volatile ConnectionPool mConnectionPool = null;
private volatile HostResolver mHostResolver = null; private volatile com.android.okhttp.internal.Network mNetwork = null;
private Object mLock = new Object(); private Object mLock = new Object();
// Default connection pool values. These are evaluated at startup, just // Default connection pool values. These are evaluated at startup, just
@@ -217,10 +215,10 @@ public class Network implements Parcelable {
// out) ConnectionPools. // out) ConnectionPools.
private void maybeInitHttpClient() { private void maybeInitHttpClient() {
synchronized (mLock) { synchronized (mLock) {
if (mHostResolver == null) { if (mNetwork == null) {
mHostResolver = new HostResolver() { mNetwork = new com.android.okhttp.internal.Network() {
@Override @Override
public InetAddress[] getAllByName(String host) throws UnknownHostException { public InetAddress[] resolveInetAddresses(String host) throws UnknownHostException {
return Network.this.getAllByName(host); return Network.this.getAllByName(host);
} }
}; };
@@ -244,23 +242,26 @@ public class Network implements Parcelable {
public URLConnection openConnection(URL url) throws IOException { public URLConnection openConnection(URL url) throws IOException {
maybeInitHttpClient(); maybeInitHttpClient();
String protocol = url.getProtocol(); String protocol = url.getProtocol();
OkHttpClient client; OkUrlFactory okUrlFactory;
// TODO: HttpHandler creates OkHttpClients that share the default ResponseCache. // TODO: HttpHandler creates OkUrlFactory instances that share the default ResponseCache.
// Could this cause unexpected behavior? // Could this cause unexpected behavior?
// TODO: Should the network's proxy be specified? // TODO: Should the network's proxy be specified?
if (protocol.equals("http")) { if (protocol.equals("http")) {
client = HttpHandler.createHttpOkHttpClient(null /* proxy */); okUrlFactory = HttpHandler.createHttpOkUrlFactory(null /* proxy */);
} else if (protocol.equals("https")) { } else if (protocol.equals("https")) {
client = HttpsHandler.createHttpsOkHttpClient(null /* proxy */); okUrlFactory = HttpsHandler.createHttpsOkUrlFactory(null /* proxy */);
} else { } else {
// OkHttpClient only supports HTTP and HTTPS and returns a null URLStreamHandler if // OkHttp only supports HTTP and HTTPS and returns a null URLStreamHandler if
// passed another protocol. // passed another protocol.
throw new MalformedURLException("Invalid URL or unrecognized protocol " + protocol); throw new MalformedURLException("Invalid URL or unrecognized protocol " + protocol);
} }
return client.setSocketFactory(getSocketFactory()) OkHttpClient client = okUrlFactory.client();
.setHostResolver(mHostResolver) client.setSocketFactory(getSocketFactory()).setConnectionPool(mConnectionPool);
.setConnectionPool(mConnectionPool)
.open(url); // Use internal APIs to change the Network.
Internal.instance.setNetwork(client, mNetwork);
return okUrlFactory.open(url);
} }
/** /**

View File

@@ -16,20 +16,20 @@
package android.net.http; package android.net.http;
import android.content.Context; import com.android.okhttp.Cache;
import com.android.okhttp.AndroidShimResponseCache;
import com.android.okhttp.OkCacheContainer;
import java.io.Closeable; import java.io.Closeable;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.CacheRequest; import java.net.CacheRequest;
import java.net.CacheResponse; import java.net.CacheResponse;
import java.net.HttpURLConnection;
import java.net.ResponseCache; import java.net.ResponseCache;
import java.net.URI; import java.net.URI;
import java.net.URLConnection; import java.net.URLConnection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.net.ssl.HttpsURLConnection;
import org.apache.http.impl.client.DefaultHttpClient;
/** /**
* Caches HTTP and HTTPS responses to the filesystem so they may be reused, * Caches HTTP and HTTPS responses to the filesystem so they may be reused,
@@ -40,7 +40,7 @@ import org.apache.http.impl.client.DefaultHttpClient;
* <h3>Installing an HTTP response cache</h3> * <h3>Installing an HTTP response cache</h3>
* Enable caching of all of your application's HTTP requests by installing the * Enable caching of all of your application's HTTP requests by installing the
* cache at application startup. For example, this code installs a 10 MiB cache * cache at application startup. For example, this code installs a 10 MiB cache
* in the {@link Context#getCacheDir() application-specific cache directory} of * in the {@link android.content.Context#getCacheDir() application-specific cache directory} of
* the filesystem}: <pre> {@code * the filesystem}: <pre> {@code
* protected void onCreate(Bundle savedInstanceState) { * protected void onCreate(Bundle savedInstanceState) {
* ... * ...
@@ -147,11 +147,11 @@ import org.apache.http.impl.client.DefaultHttpClient;
* } catch (Exception httpResponseCacheNotAvailable) { * } catch (Exception httpResponseCacheNotAvailable) {
* }}</pre> * }}</pre>
*/ */
public final class HttpResponseCache extends ResponseCache implements Closeable { public final class HttpResponseCache extends ResponseCache implements Closeable, OkCacheContainer {
private final com.android.okhttp.HttpResponseCache delegate; private final AndroidShimResponseCache delegate;
private HttpResponseCache(com.android.okhttp.HttpResponseCache delegate) { private HttpResponseCache(AndroidShimResponseCache delegate) {
this.delegate = delegate; this.delegate = delegate;
} }
@@ -161,17 +161,14 @@ public final class HttpResponseCache extends ResponseCache implements Closeable
*/ */
public static HttpResponseCache getInstalled() { public static HttpResponseCache getInstalled() {
ResponseCache installed = ResponseCache.getDefault(); ResponseCache installed = ResponseCache.getDefault();
if (installed instanceof com.android.okhttp.HttpResponseCache) { if (installed instanceof HttpResponseCache) {
return new HttpResponseCache( return (HttpResponseCache) installed;
(com.android.okhttp.HttpResponseCache) installed);
} }
return null; return null;
} }
/** /**
* Creates a new HTTP response cache and {@link ResponseCache#setDefault * Creates a new HTTP response cache and sets it as the system default cache.
* sets it} as the system default cache.
* *
* @param directory the directory to hold cache data. * @param directory the directory to hold cache data.
* @param maxSize the maximum size of the cache in bytes. * @param maxSize the maximum size of the cache in bytes.
@@ -180,26 +177,26 @@ public final class HttpResponseCache extends ResponseCache implements Closeable
* Most applications should respond to this exception by logging a * Most applications should respond to this exception by logging a
* warning. * warning.
*/ */
public static HttpResponseCache install(File directory, long maxSize) throws IOException { public static synchronized HttpResponseCache install(File directory, long maxSize)
throws IOException {
ResponseCache installed = ResponseCache.getDefault(); ResponseCache installed = ResponseCache.getDefault();
if (installed instanceof com.android.okhttp.HttpResponseCache) { if (installed instanceof HttpResponseCache) {
com.android.okhttp.HttpResponseCache installedCache = HttpResponseCache installedResponseCache = (HttpResponseCache) installed;
(com.android.okhttp.HttpResponseCache) installed;
// don't close and reopen if an equivalent cache is already installed // don't close and reopen if an equivalent cache is already installed
if (installedCache.getDirectory().equals(directory) AndroidShimResponseCache trueResponseCache = installedResponseCache.delegate;
&& installedCache.getMaxSize() == maxSize if (trueResponseCache.isEquivalent(directory, maxSize)) {
&& !installedCache.isClosed()) { return installedResponseCache;
return new HttpResponseCache(installedCache);
} else { } else {
// The HttpResponseCache that owns this object is about to be replaced. // The HttpResponseCache that owns this object is about to be replaced.
installedCache.close(); trueResponseCache.close();
} }
} }
com.android.okhttp.HttpResponseCache responseCache = AndroidShimResponseCache trueResponseCache =
new com.android.okhttp.HttpResponseCache(directory, maxSize); AndroidShimResponseCache.create(directory, maxSize);
ResponseCache.setDefault(responseCache); HttpResponseCache newResponseCache = new HttpResponseCache(trueResponseCache);
return new HttpResponseCache(responseCache); ResponseCache.setDefault(newResponseCache);
return newResponseCache;
} }
@Override public CacheResponse get(URI uri, String requestMethod, @Override public CacheResponse get(URI uri, String requestMethod,
@@ -214,10 +211,15 @@ public final class HttpResponseCache extends ResponseCache implements Closeable
/** /**
* Returns the number of bytes currently being used to store the values in * Returns the number of bytes currently being used to store the values in
* this cache. This may be greater than the {@link #maxSize} if a background * this cache. This may be greater than the {@link #maxSize} if a background
* deletion is pending. * deletion is pending. {@code -1} is returned if the size cannot be determined.
*/ */
public long size() { public long size() {
return delegate.getSize(); try {
return delegate.size();
} catch (IOException e) {
// This can occur if the cache failed to lazily initialize.
return -1;
}
} }
/** /**
@@ -225,7 +227,7 @@ public final class HttpResponseCache extends ResponseCache implements Closeable
* its data. * its data.
*/ */
public long maxSize() { public long maxSize() {
return delegate.getMaxSize(); return delegate.maxSize();
} }
/** /**
@@ -271,7 +273,7 @@ public final class HttpResponseCache extends ResponseCache implements Closeable
* will remain on the filesystem. * will remain on the filesystem.
*/ */
@Override public void close() throws IOException { @Override public void close() throws IOException {
if (ResponseCache.getDefault() == this.delegate) { if (ResponseCache.getDefault() == this) {
ResponseCache.setDefault(null); ResponseCache.setDefault(null);
} }
delegate.close(); delegate.close();
@@ -281,9 +283,16 @@ public final class HttpResponseCache extends ResponseCache implements Closeable
* Uninstalls the cache and deletes all of its stored contents. * Uninstalls the cache and deletes all of its stored contents.
*/ */
public void delete() throws IOException { public void delete() throws IOException {
if (ResponseCache.getDefault() == this.delegate) { if (ResponseCache.getDefault() == this) {
ResponseCache.setDefault(null); ResponseCache.setDefault(null);
} }
delegate.delete(); delegate.delete();
} }
/** @hide Needed for OkHttp integration. */
@Override
public Cache getCache() {
return delegate.getCache();
}
} }